");$(messageBox).prependTo(container).slideDown(),"updated"===messageClass&&window.setTimeout(function(){self.hideMessage(container,!1)},1e4)},self.hideMessage=function(container,messageQueued){var messageBox=$(container).find(".message");messageQueued?$(messageBox).remove():$(messageBox).slideUp(function(){$(this).remove()})},self.updateApproved=function(entryID,approved,$target){var data={action:"gv_update_approved",entry_id:entryID,form_id:gvGlobals.form_id,approved:approved,nonce:gvGlobals.nonce};return $.post(ajaxurl,data,function(response){response&&$target.removeClass("loading").toggleClass("entry_approved","Approved"===approved)}),!0},$(self.init)}(jQuery);
\ No newline at end of file
+!function($){"use strict";var self={};self.init=function(){self.maybeDisplayMessages(),1*gvGlobals.add_bulk_action&&self.addBulkAction(),1*gvGlobals.show_column&&(self.addApprovedColumn(),self.setInitialApprovedEntries(),$(".toggleApproved").click(self.toggleApproved))},self.maybeDisplayMessages=function(){gvGlobals.bulk_message.length>0&&self.displayMessage(gvGlobals.bulk_message,"updated","#lead_form")},self.setInitialApprovedEntries=function(){$("tr:has(input.entry_approved)").find("a.toggleApproved").addClass("entry_approved").prop("title",gvGlobals.unapprove_title)},self.addBulkAction=function(){$("#bulk_action, #bulk_action2").append('")},self.addApprovedColumn=function(){$("thead th.check-column:eq(1), tfoot th.check-column:eq(1)").after('
");$(messageBox).prependTo(container).slideDown(),"updated"===messageClass&&window.setTimeout(function(){self.hideMessage(container,!1)},1e4)},self.hideMessage=function(container,messageQueued){var messageBox=$(container).find(".message");messageQueued?$(messageBox).remove():$(messageBox).slideUp(function(){$(this).remove()})},self.updateApproved=function(entryID,approved,$target){var data={action:"gv_update_approved",entry_id:entryID,form_id:gvGlobals.form_id,approved:approved,nonce:gvGlobals.nonce};return $.post(ajaxurl,data,function(response){response&&$target.removeClass("loading").toggleClass("entry_approved","Approved"===approved)}),!0},$(self.init)}(jQuery);
\ No newline at end of file
diff --git a/assets/js/feedback.js b/assets/js/feedback.js
deleted file mode 100644
index 9f70956216..0000000000
--- a/assets/js/feedback.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * @global jQuery
- */
-var _chatlio=_chatlio||[];
-!function(){var t=document.getElementById("chatlio-widget-embed");if(t&&window.React&&_chatlio.init)return void _chatlio.init(t,React);for(var e=function(t){return function(){_chatlio.push([t].concat(arguments))}},i=["identify","track","show","hide","isShown","isOnline"],a=0;aadd_hooks();
+ }
+
+ /**
+ * @since 1.15
+ */
+ function add_hooks() {
+ add_action( 'personal_options', array( $this, 'user_field' ) );
+ add_action( 'personal_options_update', array( $this, 'update_user_meta_value' ) );
+ add_action( 'edit_user_profile_update', array( $this, 'update_user_meta_value' ) );
+ add_action( 'admin_enqueue_scripts', array( $this, 'maybe_enqueue_script' ), 1000 );
+ add_action( 'update_option_active_plugins', array( $this, 'flush_related_plugins_transient' ) );
+ add_action( 'update_option_active_sitewide_plugins', array( $this, 'flush_related_plugins_transient' ) );
+ }
+
+ /**
+ * Enqueue Support Port script if user has it enabled and we're on a GravityView plugin page
+ *
+ * @uses gravityview_is_admin_page()
+ * @uses wp_enqueue_script()
+ * @since 1.15
+ *
+ * @return void
+ */
+ static function maybe_enqueue_script( $hook ) {
+ global $pagenow;
+
+ // Don't show if not GravityView page, or if we're on the Widgets page
+ if ( ! gravityview_is_admin_page( $hook ) || $pagenow === 'widgets.php' ) {
+ return;
+ }
+
+ /**
+ * @filter `gravityview/support_port/display` Whether to display Support Port
+ * @since 1.15
+ *
+ * @param boolean $display_beacon Default: `true`
+ */
+ $display_support_port = apply_filters( 'gravityview/support_port/display', self::show_for_user() );
+
+ if ( empty( $display_support_port ) ) {
+ do_action( 'gravityview_log_debug', __METHOD__ . ' - Not showing Support Port' );
+
+ return;
+ }
+
+ $script_debug = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min';
+
+ wp_enqueue_script( 'gravityview-support', plugins_url( 'assets/js/support' . $script_debug . '.js', GRAVITYVIEW_FILE ), array(), GravityView_Plugin::version, true );
+
+ self::_localize_script();
+ }
+
+ /**
+ * Localize the Support Port script
+ *
+ * @uses wp_localize_script()
+ * @since 1.15
+ * @return void
+ */
+ private static function _localize_script() {
+
+ $translation = array(
+ 'agentLabel' => __( 'GravityView Support', 'gravityview' ),
+ 'searchLabel' => __( 'Search GravityView Docs', 'gravityview' ),
+ 'searchErrorLabel' => __( 'Your search timed out. Please double-check your internet connection and try again.', 'gravityview' ),
+ 'noResultsLabel' => _x( 'No results found for', 'a support form search has returned empty for the following word', 'gravityview' ),
+ 'contactLabel' => __( 'Contact Support', 'gravityview' ),
+ 'attachFileLabel' => __( 'Attach a screenshot or file', 'gravityview' ),
+ 'attachFileError' => __( 'The maximum file size is 10 MB', 'gravityview' ),
+ 'nameLabel' => __( 'Your Name', 'gravityview' ),
+ 'nameError' => __( 'Please enter your name', 'gravityview' ),
+ 'emailLabel' => __( 'Email address', 'gravityview' ),
+ 'emailError' => __( 'Please enter a valid email address', 'gravityview' ),
+ 'subjectLabel' => __( 'Subject', 'gravityview' ),
+ 'subjectError' => _x( 'Please enter a subject', 'Error shown when submitting support request and there is no subject provided', 'gravityview' ),
+ 'messageLabel' => __( 'How can we help you?', 'gravityview' ),
+ 'messageError' => _x( 'Please enter a message', 'Error shown when submitting support request and there is no message provided', 'gravityview' ),
+ 'contactSuccessLabel' => __( 'Message sent!', 'gravityview' ),
+ 'contactSuccessDescription' => __( 'Thanks for reaching out! Someone from the GravityView team will get back to you soon.', 'gravityview' ),
+ #'topicLabel' => __('Select a topic', 'gravityview' ), // Not yet implemented
+ #'topicError' => __('Please select a topic from the list', 'gravityview' ), // Not yet implemented
+ );
+
+ $response = GravityView_Settings::getSetting( 'license_key_response' );
+
+ $response = wp_parse_args( $response, array(
+ 'license' => '',
+ 'message' => '',
+ 'license_key' => '',
+ 'license_limit' => '',
+ 'expires' => '',
+ 'activations_left' => '',
+ 'site_count' => '',
+ 'payment_id' => '',
+ 'customer_name' => '',
+ 'customer_email' => '',
+ ) );
+
+ // This is just HTML we don't need.
+ unset( $response['message'] );
+
+ switch ( intval( $response['license_limit'] ) ) {
+ case 1:
+ $package = 'Sol';
+ break;
+ case 100:
+ $package = 'Galactic';
+ break;
+ case 3:
+ $package = 'Interstellar';
+ break;
+ default:
+ $package = sprintf( '%d-Site License', $response['license_limit'] );
+ }
+
+ $data = array(
+ 'email' => GravityView_Settings::getSetting( 'support-email' ),
+ 'name' => $response['customer_name'],
+ 'Valid License?' => ucwords( $response['license'] ),
+ 'License Key' => $response['license_key'],
+ 'License Level' => $package,
+ 'Site Admin Email' => get_bloginfo( 'admin_email' ),
+ 'Support Email' => GravityView_Settings::getSetting( 'support-email' ),
+ 'License Limit' => $response['license_limit'],
+ 'Site Count' => $response['site_count'],
+ 'License Expires' => $response['expires'],
+ 'Activations Left' => $response['activations_left'],
+ 'Payment ID' => $response['payment_id'],
+ 'Payment Name' => $response['customer_name'],
+ 'Payment Email' => $response['customer_email'],
+ 'WordPress Version' => get_bloginfo( 'version', 'display' ),
+ 'PHP Version' => phpversion(),
+ 'GravityView Version' => GravityView_Plugin::version,
+ 'Gravity Forms Version' => GFForms::$version,
+ 'Plugins & Extensions' => self::get_related_plugins_and_extensions(),
+ );
+
+ $localization_data = array(
+ 'contactEnabled' => (int)current_user_can( 'gravityview_contact_support' ), // @todo use GVCommon::has_cap() after merge
+ 'data' => $data,
+ 'translation' => $translation,
+ );
+
+ wp_localize_script( 'gravityview-support', 'gvSupport', $localization_data );
+
+ unset( $localization_data, $data, $translation, $response, $package );
+ }
+
+ /**
+ * Get active GravityView Extensions and Gravity Forms Add-ons to help debug issues.
+ *
+ * @since 1.15
+ * @return string List of active extensions related to GravityView or Gravity Forms, separated by HTML line breaks
+ */
+ static private function get_related_plugins_and_extensions() {
+
+ if ( ! function_exists( 'wp_get_active_and_valid_plugins' ) ) {
+ return 'Running < WP 3.0';
+ }
+
+ $extensions = (array)get_site_transient( self::related_plugins_key );
+
+ if ( empty( $extensions ) ) {
+
+ $active_plugins = wp_get_active_and_valid_plugins();
+
+ foreach ( $active_plugins as $active_plugin ) {
+
+ // Match gravityview, gravity-forms, gravityforms, gravitate
+ if ( ! preg_match( '/(gravityview|gravity-?forms|gravitate)/ism', $active_plugin ) ) {
+ continue;
+ }
+
+ $plugin_data = get_plugin_data( $active_plugin );
+
+ $extensions[] = sprintf( '%s %s', $plugin_data['Name'], $plugin_data['Version'] );
+ }
+
+ if( $extensions ) {
+ set_site_transient( self::related_plugins_key, $extensions, HOUR_IN_SECONDS );
+ } else {
+ return 'There was an error fetching related plugins.';
+ }
+ }
+
+ return implode( ' ', $extensions );
+ }
+
+ /**
+ * When a plugin is activated or deactivated, delete the cached extensions/plugins used by get_related_plugins_and_extensions()
+ *
+ * @see get_related_plugins_and_extensions()
+ * @since 1.15
+ */
+ public function flush_related_plugins_transient() {
+ if ( function_exists( 'delete_site_transient' ) ) {
+ delete_site_transient( self::related_plugins_key );
+ }
+ }
+
+ /**
+ * Check whether to show Support for a user
+ *
+ * If the user doesn't have the `gravityview_support_port` capability, returns false.
+ * If there is no preference set for the user, use the global plugin setting.
+ *
+ * @since 1.15
+ *
+ * @param int $user Optional. ID of the user to check, defaults to 0 for current user.
+ *
+ * @return bool Whether to show GravityView support
+ */
+ static public function show_for_user( $user = 0 ) {
+
+ if ( ! GVCommon::has_cap( 'gravityview_support_port' ) ) {
+ return false;
+ }
+
+ $pref = get_user_option( self::user_pref_name, $user );
+
+ // Not set; default to plugin setting
+ if ( false === $pref ) {
+ return GravityView_Settings::getSetting( 'support_port' );
+ }
+
+ return ! empty( $pref );
+ }
+
+
+ /**
+ * Update User Profile preferences for GravityView Support
+ *
+ * @since 1.5
+ *
+ * @param int $user_id
+ *
+ * @return void
+ */
+ public function update_user_meta_value( $user_id ) {
+ if ( current_user_can( 'edit_user', $user_id ) && isset( $_POST[ self::user_pref_name ] ) ) {
+ update_user_meta( $user_id, self::user_pref_name, intval( $_POST[ self::user_pref_name ] ) );
+ }
+ }
+
+ /**
+ * Modify User Profile
+ *
+ * Modifies the output of profile.php to add GravityView Support preference
+ *
+ * @since 1.15
+ *
+ * @param WP_User $user Current user info
+ *
+ * @return void
+ */
+ function user_field( $user ) {
+
+ /**
+ * @filter `gravityview/support_port/show_profile_setting` Should the "GravityView Support Port" setting be shown on user profiles?
+ * @todo use GVCommon::has_cap() after merge
+ * @since 1.15
+ *
+ * @param boolean $allow_profile_setting Default: `true`, if the user has the `gravityview_support_port` capability, which defaults to true for Contributors and higher
+ * @param WP_User $user Current user object
+ */
+ $allow_profile_setting = apply_filters( 'gravityview/support_port/show_profile_setting', current_user_can( 'gravityview_support_port' ), $user );
+
+ if ( $allow_profile_setting && current_user_can( 'edit_user', $user->ID ) ) {
+ ?>
+
+
+
+
+
+
+
+
+
+
+
@@ -34,9 +34,9 @@
if( !empty( $forms ) ) { ?>
diff --git a/includes/class-admin-add-shortcode.php b/includes/class-admin-add-shortcode.php
index c89982fca7..a948daa9e8 100644
--- a/includes/class-admin-add-shortcode.php
+++ b/includes/class-admin-add-shortcode.php
@@ -55,7 +55,7 @@ function add_shortcode_button() {
return;
}
?>
- ">
+ ">
get_error_message() );
+ $result = false;
+ }
+
+ }
exit( $result );
}
@@ -481,6 +507,11 @@ static public function get_approved_column( $form ) {
static public function add_entry_approved_hidden_input( $form_id, $field_id, $value, $entry, $query_string ) {
+
+ if( ! GVCommon::has_cap( 'gravityview_moderate_entries', $entry['id'] ) ) {
+ return;
+ }
+
if( empty( $entry['id'] ) ) {
return;
}
@@ -529,7 +560,8 @@ function add_scripts_and_styles( $hook ) {
wp_localize_script( 'gravityview_gf_entries_scripts', 'gvGlobals', array(
'nonce' => wp_create_nonce( 'gravityview_ajaxgfentries'),
'form_id' => $form_id,
- 'show_column' => $this->show_approve_entry_column( $form_id ),
+ 'show_column' => (int)$this->show_approve_entry_column( $form_id ),
+ 'add_bulk_action' => (int)GVCommon::has_cap( 'gravityview_moderate_entries' ),
'label_approve' => __( 'Approve', 'gravityview' ) ,
'label_disapprove' => __( 'Disapprove', 'gravityview' ),
'bulk_message' => $this->bulk_update_message,
@@ -554,7 +586,7 @@ function add_scripts_and_styles( $hook ) {
*/
private function show_approve_entry_column( $form_id ) {
- $show_approve_column = true;
+ $show_approve_column = GVCommon::has_cap( 'gravityview_moderate_entries' );
/**
* @filter `gravityview/approve_entries/hide-if-no-connections` Return true to hide reject/approve if there are no connected Views
diff --git a/includes/class-admin-views.php b/includes/class-admin-views.php
index bbc98aceb7..d2f37b90d3 100644
--- a/includes/class-admin-views.php
+++ b/includes/class-admin-views.php
@@ -53,6 +53,55 @@ function __construct() {
add_action( 'manage_gravityview_posts_custom_column', array( $this, 'add_custom_column_content'), 10, 2 );
+ add_action( 'restrict_manage_posts', array( $this, 'add_view_dropdown' ) );
+
+ add_action( 'pre_get_posts', array( $this, 'filter_pre_get_posts_by_gravityview_form_id' ) );
+
+ }
+
+ /**
+ * @since 1.15
+ * @param WP_Query $query
+ */
+ public function filter_pre_get_posts_by_gravityview_form_id( &$query ) {
+ global $pagenow;
+
+ if ( !is_admin() ) {
+ return;
+ }
+
+ if( 'edit.php' !== $pagenow || ! rgget( 'gravityview_form_id' ) || ! isset( $query->query_vars[ 'post_type' ] ) ) {
+ return;
+ }
+
+ if ( $query->query_vars[ 'post_type' ] == 'gravityview' ) {
+ $query->set( 'meta_query', array(
+ array(
+ 'key' => '_gravityview_form_id',
+ 'value' => rgget( 'gravityview_form_id' ),
+ )
+ ) );
+ }
+ }
+
+ function add_view_dropdown() {
+ $current_screen = get_current_screen();
+
+ if( 'gravityview' !== $current_screen->post_type ) {
+ return;
+ }
+
+ $forms = gravityview_get_forms();
+ $current_form = rgget( 'gravityview_form_id' );
+ // If there are no forms to select, show no forms.
+ if( !empty( $forms ) ) { ?>
+
+ '#',
- 'label' => '',
- 'menu_class' => 'hidden',
- 'capabilities' => '',
- )
- );
-
+ $sub_menu_items = array();
foreach ( (array)$connected_views as $view ) {
+
+ if( ! GVCommon::has_cap( 'edit_gravityview', $view->ID ) ) {
+ continue;
+ }
+
$label = empty( $view->post_title ) ? sprintf( __('No Title (View #%d)', 'gravityview' ), $view->ID ) : $view->post_title;
+
$sub_menu_items[] = array(
- 'url' => admin_url( 'post.php?action=edit&post='.$view->ID ),
'label' => esc_attr( $label ),
- 'capabilities' => current_user_can( 'edit_post', $view->ID ),
+ 'url' => admin_url( 'post.php?action=edit&post='.$view->ID ),
);
}
- $menu_items['gravityview'] = array(
- 'label' => __( 'Connected Views', 'gravityview' ),
- 'icon' => '',
- 'title' => __('GravityView Views using this form as a data source', 'gravityview'),
- 'url' => '#',
- 'onclick' => 'return false;',
- 'menu_class' => 'gv_connected_forms gf_form_toolbar_settings',
- 'link_class' => ( 1 === 1 ? '' : 'gf_toolbar_disabled' ),
- 'sub_menu_items' => $sub_menu_items,
- 'capabilities' => array(),
- 'priority' => 0
- );
+ // If there were no items added, then let's create the parent menu
+ if( $sub_menu_items ) {
+
+ // Make sure Gravity Forms uses the submenu; if there's only one item, it uses a link instead of a dropdown
+ $sub_menu_items[] = array(
+ 'url' => '#',
+ 'label' => '',
+ 'menu_class' => 'hidden',
+ 'capabilities' => '',
+ );
+
+ $menu_items['gravityview'] = array(
+ 'label' => __( 'Connected Views', 'gravityview' ),
+ 'icon' => '',
+ 'title' => __( 'GravityView Views using this form as a data source', 'gravityview' ),
+ 'url' => '#',
+ 'onclick' => 'return false;',
+ 'menu_class' => 'gv_connected_forms gf_form_toolbar_settings',
+ 'link_class' => ( 1 === 1 ? '' : 'gf_toolbar_disabled' ),
+ 'sub_menu_items' => $sub_menu_items,
+ 'priority' => 0,
+ 'capabilities' => array( 'edit_gravityviews' ),
+ );
+ }
return $menu_items;
}
@@ -287,26 +343,27 @@ static public function get_connected_form_links( $form, $include_form_link = tru
}
$form_id = $form['id'];
- $form_link = '';
$links = array();
- if( GFCommon::current_user_can_any('gravityforms_edit_forms') ) {
+ if( GVCommon::has_cap( 'gravityforms_edit_forms' ) ) {
$form_url = admin_url( sprintf( 'admin.php?page=gf_edit_forms&id=%d', $form_id ) );
$form_link = ''.gravityview_get_link( $form_url, $form['title'], 'class=row-title' ).'';
$links[] = ''.gravityview_get_link( $form_url, __('Edit Form', 'gravityview') ).'';
+ } else {
+ $form_link = ''. esc_html( $form['title'] ). '';
}
- if( GFCommon::current_user_can_any('gravityforms_view_entries') ) {
+ if( GVCommon::has_cap( 'gravityforms_view_entries' ) ) {
$entries_url = admin_url( sprintf( 'admin.php?page=gf_entries&id=%d', $form_id ) );
$links[] = ''.gravityview_get_link( $entries_url, __('Entries', 'gravityview') ).'';
}
- if( GFCommon::current_user_can_any('gravityforms_edit_settings') ) {
+ if( GVCommon::has_cap( array( 'gravityforms_edit_settings', 'gravityview_view_settings' ) ) ) {
$settings_url = admin_url( sprintf( 'admin.php?page=gf_edit_forms&view=settings&id=%d', $form_id ) );
$links[] = ''.gravityview_get_link( $settings_url, __('Settings', 'gravityview'), 'title='.__('Edit settings for this form', 'gravityview') ).'';
}
- if( GFCommon::current_user_can_any( array("gravityforms_edit_forms", "gravityforms_create_form", "gravityforms_preview_forms") ) ) {
+ if( GVCommon::has_cap( array("gravityforms_edit_forms", "gravityforms_create_form", "gravityforms_preview_forms") ) ) {
$preview_url = site_url( sprintf( '?gf_page=preview&id=%d', $form_id ) );
$links[] = ''.gravityview_get_link( $preview_url, __('Preview Form', 'gravityview'), 'title='.__('Preview this form', 'gravityview') ).'';
}
@@ -342,9 +399,20 @@ public function add_post_type_columns( $columns ) {
$date = $columns['date'];
unset( $columns['date'] );
- $columns['gv_connected_form'] = __('Data Source', 'gravityview');
+ $data_source_required_caps = array(
+ 'gravityforms_edit_forms',
+ 'gravityforms_view_entries',
+ 'gravityforms_edit_settings',
+ 'gravityview_view_settings',
+ 'gravityforms_create_form',
+ 'gravityforms_preview_forms',
+ );
+
+ if( GVCommon::has_cap( $data_source_required_caps ) ) {
+ $columns['gv_connected_form'] = __( 'Data Source', 'gravityview' );
+ }
- $columns['gv_template'] = __('Template', 'gravityview');
+ $columns['gv_template'] = _x( 'Template', 'Column title that shows what template is being used for Views', 'gravityview' );
// Add the date back in.
$columns['date'] = $date;
@@ -356,7 +424,7 @@ public function add_post_type_columns( $columns ) {
* Save View configuration
*
* @access public
- * @param mixed $post_id
+ * @param int $post_id Currently saved Post ID
* @return void
*/
function save_postdata( $post_id ) {
@@ -369,13 +437,11 @@ function save_postdata( $post_id ) {
if ( ! isset( $_POST['post_type'] ) || 'gravityview' != $_POST['post_type'] ) {
return;
}
- // validate user can edit and save post/page
- if ( 'page' == $_POST['post_type'] ) {
- if ( ! current_user_can( 'edit_page', $post_id ) )
- return;
- } else {
- if ( ! current_user_can( 'edit_post', $post_id ) )
- return;
+
+ // validate user can edit and save View
+ if ( ! GVCommon::has_cap( 'edit_gravityview', $post_id ) ) {
+ do_action( 'gravityview_log_error', __METHOD__ . ' - Current user does not have the capability to edit View #' . $post_id, wp_get_current_user() );
+ return;
}
do_action( 'gravityview_log_debug', '[save_postdata] Saving View post type.', $_POST );
@@ -391,6 +457,11 @@ function save_postdata( $post_id ) {
}
+ if( false === GVCommon::has_cap( 'gravityforms_create_form' ) && empty( $statii['form_id'] ) ) {
+ do_action( 'gravityview_log_error', __METHOD__ . ' - Current user does not have the capability to create a new Form.', wp_get_current_user() );
+ return;
+ }
+
// Was this a start fresh?
if ( ! empty( $_POST['gravityview_form_id_start_fresh'] ) ) {
$statii['start_fresh'] = add_post_meta( $post_id, '_gravityview_start_fresh', 1 );
@@ -900,84 +971,6 @@ function render_directory_active_areas( $template_id = '', $context = 'single',
return $output;
}
- /**
- * Chatlio.com customer support widget
- */
- static function enqueue_feedback_widget() {
-
- /**
- * @filter `gravityview/admin/display_live_chat` Whether to display live chat support widget when operators are available
- * @since 1.13.1
- * @param boolean $display_live_chat Default: `true`
- */
- $display_live_chat = apply_filters( 'gravityview/admin/display_live_chat', true );
-
- if( ! $display_live_chat ) {
- return;
- }
-
- $script_debug = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min';
-
- $response = GravityView_Settings::getSetting( 'license_key_response' );
-
- $response = wp_parse_args( $response, array(
- 'license' => '',
- 'message' => '',
- 'license_key' => '',
- 'license_limit' => '',
- 'expires' => '',
- 'activations_left' => '',
- 'site_count' => '',
- 'payment_id' => '',
- 'customer_name' => '',
- 'customer_email' => '',
- ) );
-
- // This is just HTML we don't need.
- unset( $response['message'] );
-
- switch( intval( $response['license_limit'] ) ) {
- case 1:
- $package = 'Sol';
- break;
- case 100:
- $package = 'Galactic';
- break;
- default:
- case 3:
- $package = 'Interstellar';
- break;
- }
-
- $chat_settings = array(
- 'onlineTitle' => __('Ask GravityView Support', 'gravityview'),
- 'offlineTitle' => __('GravityView Support', 'gravityview'),
- 'offlineGreeting' => __('If you have any questions, send us an email and we will get respond to you as soon as possible.', 'gravityview'),
- 'offlineNamePlaceholder' => __('Your Name', 'gravityview'),
- "autoResponseMessage" => sprintf( __('Question or comment? We are online and ready to answer! If you don\'t hear back from us, you can send your question to %s', 'gravityview'), 'support@gravityview.co' ),
- "agentLabel" => __('GravityView Support', 'gravityview'),
- 'css' => plugins_url( 'assets/css/feedback.css', GRAVITYVIEW_FILE ),
- );
-
- wp_enqueue_script( 'gravityview-feedback-widget', plugins_url('assets/js/feedback'.$script_debug.'.js', GRAVITYVIEW_FILE), array('jquery'), GravityView_Plugin::version, true);
-
- wp_localize_script( 'gravityview-feedback-widget', 'gvFeedback', array(
- 'Valid License?' => ucwords( $response['license'] ),
- 'License Key' => $response['license_key'],
- 'License Level' => $package,
- 'Site Admin Email' => get_bloginfo( 'admin_email' ),
- 'Support Email' => GravityView_Settings::getSetting( 'support-email' ),
- 'License Limit' => $response['license_limit'],
- 'Site Count' => $response['site_count'],
- 'License Expires' => $response['expires'],
- 'License Activations Left' => $response['activations_left'],
- 'Payment ID' => $response['payment_id'],
- 'Payment Name' => $response['customer_name'],
- 'Payment Email' => $response['customer_email'],
- 'chat_settings' => json_encode( $chat_settings ),
- ));
- }
-
/**
* Enqueue scripts and styles at Views editor
*
@@ -998,14 +991,6 @@ static function add_scripts_and_styles( $hook ) {
// Don't process any scripts below here if it's not a GravityView page.
if( !gravityview_is_admin_page($hook) && !$is_widgets_page ) { return; }
-
- if( !$is_widgets_page ) {
-
- // Add the Chatlio widget on all GV pages
- self::enqueue_feedback_widget();
-
- }
-
// Only enqueue the following on single pages
if( gravityview_is_admin_page($hook, 'single') || $is_widgets_page ) {
@@ -1063,7 +1048,7 @@ function register_no_conflict( $registered ) {
$filter = current_filter();
if( preg_match('/script/ism', $filter ) ) {
- $allow_scripts = array( 'jquery-ui-core', 'jquery-ui-dialog', 'jquery-ui-tabs', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-sortable', 'jquery-ui-tooltip', 'gravityview_views_scripts', 'gravityview-feedback-widget', 'gravityview-jquery-cookie', 'gravityview_views_datepicker',
+ $allow_scripts = array( 'jquery-ui-core', 'jquery-ui-dialog', 'jquery-ui-tabs', 'jquery-ui-draggable', 'jquery-ui-droppable', 'jquery-ui-sortable', 'jquery-ui-tooltip', 'gravityview_views_scripts', 'gravityview-support', 'gravityview-jquery-cookie', 'gravityview_views_datepicker',
'sack', 'gform_gravityforms', 'gform_forms', 'gform_form_admin', 'jquery-ui-autocomplete' );
$registered = array_merge( $registered, $allow_scripts );
} elseif( preg_match('/style/ism', $filter ) ) {
diff --git a/includes/class-admin-welcome.php b/includes/class-admin-welcome.php
index 1bc6d7320c..e1d52d1f28 100644
--- a/includes/class-admin-welcome.php
+++ b/includes/class-admin-welcome.php
@@ -26,7 +26,7 @@ class GravityView_Welcome {
/**
* @var string The capability users should have to view the page
*/
- public $minimum_capability = 'manage_options';
+ public $minimum_capability = 'gravityview_getting_started';
/**
* Get things started
@@ -256,26 +256,75 @@ public function changelog_screen() {
-
+
-
-
Custom Search Labels & Search Mode
-
You can now modify the search labels from the Search Bar configuration, and you can now choose whether you want your search to match all of the search field filters, or any.
', '', '' );
+ if( GVCommon::has_cap( 'edit_gravityviews' ) ) {
+ $output = sprintf( esc_attr__( "%sYou don't have any active views. Let’s go %screate one%s!%s\n\nIf you feel like you're lost in space and need help getting started, check out the %sGetting Started%s page.", 'gravityview' ), '
', '', '' );
+ } else {
+ $output = esc_attr__( 'There are no active Views', 'gravityview' );
+ }
- return $image.wpautop( $not_found );
+ return $image . wpautop( $output );
}
diff --git a/includes/class-settings.php b/includes/class-settings.php
index afd1365610..4572b24120 100644
--- a/includes/class-settings.php
+++ b/includes/class-settings.php
@@ -33,7 +33,17 @@ class GravityView_Settings extends GFAddOn {
/**
* @var string|array A string or an array of capabilities or roles that can uninstall the plugin
*/
- protected $_capabilities_uninstall = 'gravityview_gfaddon_uninstall';
+ protected $_capabilities_uninstall = 'gravityview_uninstall';
+
+ /**
+ * @var string|array A string or an array of capabilities or roles that have access to the settings page
+ */
+ protected $_capabilities_app_settings = 'gravityview_view_settings';
+
+ /**
+ * @var string|array A string or an array of capabilities or roles that have access to the settings page
+ */
+ protected $_capabilities_app_menu = 'gravityview_view_settings';
/**
* @var string The hook suffix for the app menu
@@ -93,14 +103,18 @@ public static function get_instance() {
public function current_user_can_any( $caps ) {
/**
- * Don't show uninstall tab
+ * Prevent Gravity Forms from showing the uninstall tab on the settings page
* @hack
*/
if( $caps === $this->_capabilities_uninstall ) {
return false;
}
- return parent::current_user_can_any( $caps );
+ if( empty( $caps ) ) {
+ $caps = array( 'gravityview_full_access' );
+ }
+
+ return GVCommon::has_cap( $caps );
}
/**
@@ -114,8 +128,6 @@ function init_admin() {
$this->_load_license_handler();
- $this->_capabilities_app_settings = apply_filters( 'gravityview_settings_capability' , 'manage_options' );
-
$this->license_key_notice();
add_filter( 'gform_addon_app_settings_menu_gravityview', array( $this, 'modify_app_settings_menu_title' ) );
@@ -477,12 +489,33 @@ private function get_default_settings() {
'license_key_status' => '',
'support-email' => get_bloginfo( 'admin_email' ),
'no-conflict-mode' => '0',
+ 'support_port' => '1',
'delete-on-uninstall' => '0',
);
return $defaults;
}
+ /**
+ * Check for the `gravityview_edit_settings` capability before saving plugin settings.
+ * Gravity Forms says you're able to edit if you're able to view settings. GravityView allows two different permissions.
+ *
+ * @since 1.15
+ * @return void
+ */
+ public function maybe_save_app_settings() {
+
+ if ( $this->is_save_postback() ) {
+ if ( ! GVCommon::has_cap( 'gravityview_edit_settings' ) ) {
+ $_POST = array(); // If you don't reset the $_POST array, it *looks* like the settings were changed, but they weren't
+ GFCommon::add_error_message( __( 'You don\'t have the ability to edit plugin settings.', 'gravityview' ) );
+ return;
+ }
+ }
+
+ parent::maybe_save_app_settings();
+ }
+
/**
* When the settings are saved, make sure the license key matches the previously activated key
*
@@ -523,6 +556,8 @@ public function app_settings_fields() {
$default_settings = $this->get_default_settings();
+ $disabled_attribute = GVCommon::has_cap( 'gravityview_edit_settings' ) ? false : 'disabled';
+
$fields = apply_filters( 'gravityview_settings_fields', array(
array(
'name' => 'license_key',
@@ -553,6 +588,28 @@ public function app_settings_fields() {
'description' => __( 'In order to provide responses to your support requests, please provide your email address.', 'gravityview' ),
'class' => 'code regular-text',
),
+ /**
+ * @since 1.15 Added Support Port support
+ */
+ array(
+ 'name' => 'support_port',
+ 'type' => 'radio',
+ 'label' => __( 'Show Support Port?', 'gravityview' ),
+ 'default_value' => $default_settings['support_port'],
+ 'horizontal' => 1,
+ 'choices' => array(
+ array(
+ 'label' => _x('Show', 'Setting: Show or Hide', 'gravityview'),
+ 'value' => '1',
+ ),
+ array(
+ 'label' => _x('Hide', 'Setting: Show or Hide', 'gravityview'),
+ 'value' => '0',
+ ),
+ ),
+ 'tooltip' => '
' . esc_html__('The Support Port provides quick access to how-to articles and tutorials. For administrators, it also makes it easy to contact support.', 'gravityview') . '
',
+ 'description' => __( 'Show the Support Port on GravityView pages?', 'gravityview' ),
+ ),
array(
'name' => 'no-conflict-mode',
'type' => 'radio',
@@ -562,39 +619,40 @@ public function app_settings_fields() {
'choices' => array(
array(
'label' => _x('On', 'Setting: On or off', 'gravityview'),
- 'value' => '1'
+ 'value' => '1',
),
array(
'label' => _x('Off', 'Setting: On or off', 'gravityview'),
'value' => '0',
),
),
- 'description' => __( 'Set this to ON to prevent extraneous scripts and styles from being printed on GravityView admin pages, reducing conflicts with other plugins and themes.', 'gravityview' ) . ' ' . __('If your Edit View tabs are ugly, enable this setting.'),
+ 'description' => __( 'Set this to ON to prevent extraneous scripts and styles from being printed on GravityView admin pages, reducing conflicts with other plugins and themes.', 'gravityview' ) . ' ' . __('If your Edit View tabs are ugly, enable this setting.', 'gravityview'),
),
array(
'name' => 'delete-on-uninstall',
'type' => 'radio',
- 'label' => __( 'Remove Data on Uninstall?', 'gravityview' ),
+ 'label' => __( 'Remove Data on Delete?', 'gravityview' ),
'default_value' => $default_settings['delete-on-uninstall'],
'horizontal' => 1,
'choices' => array(
array(
- 'label' => _x('Permanently Delete', 'Setting: what to do when uninstalling plugin', 'gravityview'),
- 'value' => 'delete',
- 'tooltip' => sprintf( '
%s
%s
%s
', __('Delete all GravityView content and settings'), __('If you delete then re-install GravityView, it will be like installing GravityView for the first time.'), __('When GravityView is uninstalled and deleted, delete all Views, GravityView entry approvals, GravityView-generated entry notes (including approval and entry creator changes), and GravityView plugin settings. No Gravity Forms data will be touched.') ),
+ 'label' => _x( 'Keep GravityView Data', 'Setting: what to do when uninstalling plugin', 'gravityview' ),
+ 'value' => '0',
+ 'tooltip' => sprintf( '
%s
%s
', __( 'Keep GravityView content and settings', 'gravityview' ), __( 'If you delete then re-install the plugin, all GravityView data will be kept. Views, settings, etc. will be untouched.', 'gravityview' ) ),
),
array(
- 'label' => _x('Keep GravityView Data', 'Setting: what to do when uninstalling plugin', 'gravityview'),
- 'value' => '0',
- 'tooltip' => sprintf( '
%s
%s
', __('Keep GravityView content and settings'), __('If you delete then re-install the plugin, all Views, plugin settings, entry notes, and entry approvals will still be here.') ),
+ 'label' => _x( 'Permanently Delete', 'Setting: what to do when uninstalling plugin', 'gravityview' ),
+ 'value' => 'delete',
+ 'tooltip' => sprintf( '
%s
%s
%s
', __( 'Delete all GravityView content and settings', 'gravityview' ), __( 'If you delete then re-install GravityView, it will be like installing GravityView for the first time.', 'gravityview' ), __( 'When GravityView is uninstalled and deleted, delete all Views, GravityView entry approvals, GravityView-generated entry notes (including approval and entry creator changes), and GravityView plugin settings. No Gravity Forms data will be touched.', 'gravityview' ) ),
),
),
- 'description' => sprintf( __( 'Should GravityView content be removed from the site when the GravityView plugin is deleted?', 'gravityview' ), __('Permanently Delete', 'gravityview') ),
+ 'description' => sprintf( __( 'Should GravityView content and entry approval status be removed from the site when the GravityView plugin is deleted?', 'gravityview' ), __( 'Permanently Delete', 'gravityview' ) ),
),
) );
+
/**
* Redux backward compatibility
* @since 1.7.4
@@ -604,6 +662,10 @@ public function app_settings_fields() {
$field['label'] = isset( $field['label'] ) ? $field['label'] : rgget('title', $field );
$field['default_value'] = isset( $field['default_value'] ) ? $field['default_value'] : rgget('default', $field );
$field['description'] = isset( $field['description'] ) ? $field['description'] : rgget('subtitle', $field );
+
+ if( $disabled_attribute ) {
+ $field['disabled'] = $disabled_attribute;
+ }
}
@@ -620,20 +682,35 @@ public function app_settings_fields() {
'type' => 'save',
);
+ if( $disabled_attribute ) {
+ $button['disabled'] = $disabled_attribute;
+ }
+
/**
+ * @filter `gravityview/settings/extension/sections` Modify the GravityView settings page
* Extensions can tap in here to insert their own section and settings.
- *
+ *
* $sections[] = array(
* 'title' => __( 'GravityView My Extension Settings', 'gravityview' ),
* 'fields' => $settings,
* );
- *
+ *
+ * @param array $extension_settings Empty array, ready for extension settings!
*/
$extension_sections = apply_filters( 'gravityview/settings/extension/sections', array() );
// If there are extensions, add a section for them
if ( ! empty( $extension_sections ) ) {
+
+ if( $disabled_attribute ) {
+ foreach ( $extension_sections as &$section ) {
+ foreach ( $section['fields'] as &$field ) {
+ $field['disabled'] = $disabled_attribute;
+ }
+ }
+ }
+
$k = count( $extension_sections ) - 1 ;
$extension_sections[ $k ]['fields'][] = $button;
$sections = array_merge( $sections, $extension_sections );
diff --git a/includes/connector-functions.php b/includes/connector-functions.php
index 0cf75dd060..b92a6ba95c 100644
--- a/includes/connector-functions.php
+++ b/includes/connector-functions.php
@@ -259,6 +259,7 @@ function gravityview_get_directory_fields( $post_id ) {
*
* @access public
* @param int $formid Form ID
+ * @param string $current Field ID of field used to sort
* @return string html
*/
function gravityview_get_sortable_fields( $formid, $current = '' ) {
@@ -320,3 +321,31 @@ function the_gravityview( $view_id = '', $atts = array() ) {
function gravityview_is_single_entry() {
return GravityView_frontend::is_single_entry();
}
+
+/**
+ * Determine whether a View has a single checkbox or single radio input
+ * @see GravityView_frontend::add_scripts_and_styles()
+ * @since 1.15
+ * @param array $form Gravity Forms form
+ * @param array $view_fields GravityView fields array
+ */
+function gravityview_view_has_single_checkbox_or_radio( $form, $view_fields ) {
+
+ if( $form_fields = GFFormsModel::get_fields_by_type( $form, array( 'checkbox', 'radio' ) ) ) {
+
+ /** @var GF_Field_Radio|GF_Field_Checkbox $form_field */
+ foreach( $form_fields as $form_field ) {
+ $field_id = $form_field->id;
+ foreach( $view_fields as $zone ) {
+ foreach( $zone as $field ) {
+ // If it's an input, not the parent and the parent ID matches a checkbox or radio
+ if( ( strpos( $field['id'], '.' ) > 0 ) && floor( $field['id'] ) === floor( $field_id ) ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
\ No newline at end of file
diff --git a/includes/default-templates.php b/includes/default-templates.php
deleted file mode 100644
index 8b0dbbc000..0000000000
--- a/includes/default-templates.php
+++ /dev/null
@@ -1,631 +0,0 @@
- 'table',
- 'type' => 'custom',
- 'label' => __( 'Table (default)', 'gravityview' ),
- 'description' => __('Display items in a table view.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/default-table/logo-default-table.png', GRAVITYVIEW_FILE),
- 'css_source' => plugins_url('templates/css/table-view.css', GRAVITYVIEW_FILE),
- );
-
- $settings = wp_parse_args( $settings, $table_settings );
-
- /**
- * @see GravityView_Admin_Views::get_default_field_options() for Generic Field Options
- * @var array
- */
- $field_options = array(
- 'show_as_link' => array(
- 'type' => 'checkbox',
- 'label' => __( 'Link to single entry', 'gravityview' ),
- 'value' => false,
- 'context' => 'directory'
- ),
- );
-
- $areas = array(
- array(
- '1-1' => array(
- array(
- 'areaid' => 'table-columns',
- 'title' => __('Visible Table Columns', 'gravityview' ) ,
- 'subtitle' => __('Each field will be displayed as a column in the table.', 'gravityview'),
- )
- )
- )
- );
-
-
- parent::__construct( $id, $settings, $field_options, $areas );
-
- }
-
-}
-
-/**
- * GravityView_Default_Template_Edit class.
- * Defines Edit Table(default) template (Edit Entry)
- */
-class GravityView_Default_Template_Edit extends GravityView_Template {
-
- function __construct( $id = 'default_table_edit', $settings = array(), $field_options = array(), $areas = array() ) {
-
- $edit_settings = array(
- 'slug' => 'edit',
- 'type' => 'internal',
- 'label' => __( 'Edit Table', 'gravityview' ),
- 'description' => __('Display items in a table view.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/default-table/logo-default-table.png', GRAVITYVIEW_FILE),
- 'css_source' => plugins_url('templates/css/table-view.css', GRAVITYVIEW_FILE),
- );
-
- $settings = wp_parse_args( $settings, $edit_settings );
-
- /**
- * @see GravityView_Admin_Views::get_default_field_options() for Generic Field Options
- * @var array
- */
- $field_options = array();
-
- $areas = array(
- array(
- '1-1' => array(
- array(
- 'areaid' => 'edit-fields',
- 'title' => __('Visible Edit Fields', 'gravityview' )
- )
- )
- )
- );
-
-
- parent::__construct( $id, $settings, $field_options, $areas );
-
- }
-
-}
-
-
-
-/**
- * GravityView_Default_Template_List class.
- * Defines List (default) template
- */
-class GravityView_Default_Template_List extends GravityView_Template {
-
- function __construct( $id = 'default_list', $settings = array(), $field_options = array(), $areas = array() ) {
-
- $list_settings = array(
- 'slug' => 'list',
- 'type' => 'custom',
- 'label' => __( 'List (default)', 'gravityview' ),
- 'description' => __('Display items in a listing view.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/default-list/logo-default-list.png', GRAVITYVIEW_FILE),
- 'css_source' => plugins_url('templates/css/list-view.css', GRAVITYVIEW_FILE),
- );
-
- $settings = wp_parse_args( $settings, $list_settings );
-
- $field_options = array(
- 'show_as_link' => array(
- 'type' => 'checkbox',
- 'label' => __( 'Link to single entry', 'gravityview' ),
- 'value' => false,
- 'context' => 'directory'
- ),
- );
-
- $areas = array(
- array(
- '1-1' => array(
- array( 'areaid' => 'list-title', 'title' => __('Listing Title', 'gravityview' ) , 'subtitle' => '' ),
- array( 'areaid' => 'list-subtitle', 'title' => __('Subheading', 'gravityview' ) , 'subtitle' => 'Data placed here will be bold.' ),
- ),
- '1-3' => array(
- array( 'areaid' => 'list-image', 'title' => __( 'Image', 'gravityview' ) , 'subtitle' => 'Leave empty to remove.' )
- ),
- '2-3' => array(
- array( 'areaid' => 'list-description', 'title' => __('Other Fields', 'gravityview' ) , 'subtitle' => 'Below the subheading, a good place for description and other data.' ) )
- ),
- array(
- '1-2' => array(
- array( 'areaid' => 'list-footer-left', 'title' => __('Footer Left', 'gravityview' ) , 'subtitle' => '' )
- ),
- '2-2' => array(
- array( 'areaid' => 'list-footer-right', 'title' => __('Footer Right', 'gravityview' ) , 'subtitle' => '' )
- )
- )
- );
-
- parent::__construct( $id, $settings, $field_options, $areas );
-
- }
-}
-
-
-abstract class GravityView_Template {
-
- // template unique id
- public $template_id;
-
- // define template settings
- public $settings;
- /**
- * $settings:
- * slug - template slug (frontend)
- * css_source - url path to CSS file, to be enqueued (frontend)
- * type - 'custom' or 'preset' (admin)
- * label - template nicename (admin)
- * description - short about text (admin)
- * logo - template icon (admin)
- * preview - template image for previewing (admin)
- * buy_source - url source for buying this template
- * preset_form - path to Gravity Form form XML file
- * preset_config - path to View config (XML)
- *
- */
-
- // form fields extra options
- public $field_options;
-
- // define the active areas
- public $active_areas;
-
-
- function __construct( $id, $settings = array(), $field_options = array(), $areas = array() ) {
-
- if( empty( $id ) ) {
- return;
- }
-
- $this->template_id = $id;
-
- $this->merge_defaults( $settings );
-
- $this->field_options = $field_options;
- $this->active_areas = $areas;
-
- add_filter( 'gravityview_register_directory_template', array( $this, 'register_template' ) );
-
- // presets hooks:
- // form xml
- add_filter( 'gravityview_template_formxml', array( $this, 'assign_form_xml' ), 10 , 2);
- // fields config xml
- add_filter( 'gravityview_template_fieldsxml', array( $this, 'assign_fields_xml' ), 10 , 2);
-
- // assign active areas
- add_filter( 'gravityview_template_active_areas', array( $this, 'assign_active_areas' ), 10, 3 );
-
- // field options
- add_filter( 'gravityview_template_field_options', array( $this, 'assign_field_options' ), 10, 4 );
-
- // template slug
- add_filter( "gravityview_template_slug_{$id}", array( $this, 'assign_view_slug' ), 10, 2 );
-
- // register template CSS
- add_action( 'wp_enqueue_scripts', array( $this, 'register_styles' ) );
- }
-
- /**
- * Merge the template settings with the default settings
- *
- * Sets the `settings` object var.
- *
- * @param array $settings Defined template settings
- * @return array Merged template settings.
- */
- function merge_defaults( $settings = array() ) {
-
- $defaults = array(
- 'slug' => '',
- 'css_source' => '',
- 'type' => '',
- 'label' => '',
- 'description' => '',
- 'logo' => '',
- 'preview' => '',
- 'buy_source' => '',
- 'preset_form' => '',
- 'preset_fields' => ''
- );
-
- $this->settings = wp_parse_args( $settings, $defaults);
-
- return $this->settings;
- }
-
- /**
- * Register the template to display in the admin
- *
- * @access private
- * @param mixed $templates
- * @return array Array of templates available for GV
- */
- public function register_template( $templates ) {
- $templates[ $this->template_id ] = $this->settings;
- return $templates;
- }
-
-
- /**
- * Assign active areas (for admin configuration)
- *
- * @access protected
- * @param array $areas
- * @param string $template (default: '')
- * @return array Array of active areas
- */
- public function assign_active_areas( $areas, $template = '', $context = 'directory' ) {
- if( $this->template_id === $template ) {
- $areas = $this->get_active_areas( $context );
- }
- return $areas;
- }
-
- public function get_active_areas( $context ) {
- if( isset( $this->active_areas[ $context ] ) ) {
- return $this->active_areas[ $context ];
- } else {
- return $this->active_areas;
- }
- }
-
-
- /**
- * Assign template specific field options
- *
- * @access protected
- * @param array $options (default: array())
- * @param string $template (default: '')
- * @param string $field_id key for the field
- * @param string|array $context Context for the field; `directory` or `single` for example.
- * @return array Array of field options
- */
- public function assign_field_options( $field_options, $template_id, $field_id = NULL, $context = 'directory' ) {
-
- if( $this->template_id === $template_id ) {
-
- foreach ($this->field_options as $key => $field_option) {
-
- $field_context = rgar($field_option, 'context');
-
- // Does the field option only apply to a certain context?
- // You can define multiple contexts as an array: `context => array("directory", "single")`
- $context_matches = is_array($field_context) ? in_array($context, $field_context) : $context === $field_context;
-
- // If the context matches (or isn't defined), add the field options.
- if($context_matches) {
- $field_options[$key] = $field_option;
- }
- }
- }
-
- return $field_options;
- }
-
- /**
- * Set the Gravity Forms import form information by using the `preset_form` field defined in the template.
- * @see GravityView_Admin_Views::pre_get_form_fields()
- * @see GravityView_Admin_Views::create_preset_form()
- * @return string Path to XML file
- */
- public function assign_form_xml( $xml = '' , $template = '' ) {
- if( $this->settings['type'] === 'preset' && !empty( $this->settings['preset_form'] ) && $this->template_id === $template ) {
- return $this->settings['preset_form'];
- }
-
- return $xml;
- }
-
- /**
- * Set the Gravity Forms import form by using the `preset_fields` field defined in the template.
- * @see GravityView_Admin_Views::pre_get_form_fields()
- * @return string Path to XML file
- */
- public function assign_fields_xml( $xml = '' , $template = '' ) {
- if( $this->settings['type'] === 'preset' && !empty( $this->settings['preset_fields'] ) && $this->template_id === $template ) {
- return $this->settings['preset_fields'];
- }
-
- return $xml;
- }
-
-
- /**
- * Assign the template slug when loading the presentation template (frontend)
- *
- * @access protected
- * @param mixed $default
- * @return void
- */
- public function assign_view_slug( $default, $context ) {
-
- if( !empty( $this->settings['slug'] ) ) {
- return $this->settings['slug'];
- }
- if( !empty( $default ) ) {
- return $default;
- }
- // last resort, template_id
- return $this->template_id;
- }
-
- /**
- * Register styles
- * @return void
- */
- public function register_styles() {
- if( !empty( $this->settings['css_source'] ) ) {
- wp_register_style( 'gravityview_style_' . $this->template_id, $this->settings['css_source'], array(), GravityView_Plugin::version, 'all' );
- }
- }
-
-
-
-}
-
-/** Preset templates */
-
-class GravityView_Preset_Business_Data extends GravityView_Default_Template_Table {
-
- function __construct() {
-
- $id = 'preset_business_data';
-
- $settings = array(
- 'slug' => 'table',
- 'type' => 'preset',
- 'label' => __( 'Business Data', 'gravityview' ),
- 'description' => __( 'Display business information in a table.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/business-data/logo-business-data.png', GRAVITYVIEW_FILE),
- 'preview' => 'http://demo.gravityview.co/blog/view/business-table/',
- 'preset_form' => GRAVITYVIEW_DIR . 'includes/presets/business-data/form-business-data.xml',
- 'preset_fields' => GRAVITYVIEW_DIR . 'includes/presets/business-data/fields-business-data.xml'
- );
-
- parent::__construct( $id, $settings );
- }
-}
-
-
-class GravityView_Preset_Resume_Board extends GravityView_Default_Template_Table {
-
- function __construct() {
-
- $id = 'preset_resume_board';
-
- $settings = array(
- 'slug' => 'table',
- 'type' => 'preset',
- 'label' => __( 'Resume Board', 'gravityview' ),
- 'description' => __( 'Allow job-seekers to post their resumes.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/resume-board/logo-resume-board.png', GRAVITYVIEW_FILE),
- 'preview' => 'http://demo.gravityview.co/blog/view/resume-board/',
- 'preset_form' => GRAVITYVIEW_DIR . 'includes/presets/resume-board/form-resume-board.xml',
- 'preset_fields' => GRAVITYVIEW_DIR . 'includes/presets/resume-board/fields-resume-board.xml'
- );
-
- parent::__construct( $id, $settings );
-
- }
-}
-
-class GravityView_Preset_Job_Board extends GravityView_Default_Template_List {
-
- function __construct() {
-
- $id = 'preset_job_board';
-
- $settings = array(
- 'slug' => 'list',
- 'type' => 'preset',
- 'label' => __( 'Job Board', 'gravityview' ),
- 'description' => __( 'Post available jobs in a simple job board.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/job-board/logo-job-board.png', GRAVITYVIEW_FILE),
- 'preview' => 'http://demo.gravityview.co/blog/view/job-board/',
- 'preset_form' => GRAVITYVIEW_DIR . 'includes/presets/job-board/form-job-board.xml',
- 'preset_fields' => GRAVITYVIEW_DIR . 'includes/presets/job-board/fields-job-board.xml'
-
- );
-
- parent::__construct( $id, $settings );
- }
-}
-
-class GravityView_Preset_People_Table extends GravityView_Default_Template_Table {
-
- function __construct() {
-
- $id = 'preset_people_table';
-
- $settings = array(
- 'slug' => 'table',
- 'type' => 'preset',
- 'label' => __( 'People Table', 'gravityview' ),
- 'description' => __( 'Display information about people in a table.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/people-table/logo-people-table.png', GRAVITYVIEW_FILE),
- 'preview' => '',
- 'preset_form' => GRAVITYVIEW_DIR . 'includes/presets/people-table/form-people-table.xml',
- #'preset_fields' => GRAVITYVIEW_DIR . 'includes/presets/people-table/fields-people-table.xml'
-
- );
-
- parent::__construct( $id, $settings );
-
- }
-}
-
-class GravityView_Preset_Issue_Tracker extends GravityView_Default_Template_Table {
-
- function __construct() {
-
- $id = 'preset_issue_tracker';
-
- $settings = array(
- 'slug' => 'table',
- 'type' => 'preset',
- 'label' => __( 'Issue Tracker', 'gravityview' ),
- 'description' => __( 'Manage issues and their statuses.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/issue-tracker/logo-issue-tracker.png', GRAVITYVIEW_FILE),
- 'preview' => 'http://demo.gravityview.co/blog/view/issue-tracker/',
- 'preset_form' => GRAVITYVIEW_DIR . 'includes/presets/issue-tracker/form-issue-tracker.xml',
- 'preset_fields' => GRAVITYVIEW_DIR . 'includes/presets/issue-tracker/fields-issue-tracker.xml'
-
- );
-
- parent::__construct( $id, $settings );
-
- }
-}
-
-class GravityView_Preset_Business_Listings extends GravityView_Default_Template_List {
-
- function __construct() {
-
- $id = 'preset_business_listings';
-
- $settings = array(
- 'slug' => 'list',
- 'type' => 'preset',
- 'label' => __( 'Business Listings', 'gravityview' ),
- 'description' => __( 'Display business profiles.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/business-listings/logo-business-listings.png', GRAVITYVIEW_FILE),
- 'preview' => 'http://demo.gravityview.co/blog/view/business-listings/',
- 'preset_form' => GRAVITYVIEW_DIR . 'includes/presets/business-listings/form-business-listings.xml',
- 'preset_fields' => GRAVITYVIEW_DIR . 'includes/presets/business-listings/fields-business-listings.xml'
- );
-
- parent::__construct( $id, $settings );
-
- }
-}
-
-class GravityView_Preset_Event_Listings extends GravityView_Default_Template_List {
-
- function __construct() {
-
- $id = 'preset_event_listings';
-
- $settings = array(
- 'slug' => 'list',
- 'type' => 'preset',
- 'label' => __( 'Event Listings', 'gravityview' ),
- 'description' => __( 'Present a list of your events.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/event-listings/logo-event-listings.png', GRAVITYVIEW_FILE),
- 'preview' => 'http://demo.gravityview.co/blog/view/event-listings/',
- 'preset_form' => GRAVITYVIEW_DIR . 'includes/presets/event-listings/form-event-listings.xml',
- 'preset_fields' => GRAVITYVIEW_DIR . 'includes/presets/event-listings/fields-event-listings.xml'
- );
-
- parent::__construct( $id, $settings );
-
- }
-}
-
-class GravityView_Preset_Profiles extends GravityView_Default_Template_List {
-
- function __construct() {
-
- $id = 'preset_profiles';
-
- $settings = array(
- 'slug' => 'list',
- 'type' => 'preset',
- 'label' => __( 'People Profiles', 'gravityview' ),
- 'description' => __( 'List people with individual profiles.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/profiles/logo-profiles.png', GRAVITYVIEW_FILE),
- 'preview' => 'http://demo.gravityview.co/blog/view/people-profiles/',
- 'preset_form' => GRAVITYVIEW_DIR . 'includes/presets/profiles/form-profiles.xml',
- 'preset_fields' => GRAVITYVIEW_DIR . 'includes/presets/profiles/fields-profiles.xml'
- );
-
- parent::__construct( $id, $settings );
-
- }
-}
-
-class GravityView_Preset_Staff_Profiles extends GravityView_Default_Template_List {
-
- function __construct() {
-
- $id = 'preset_staff_profiles';
-
- $settings = array(
- 'slug' => 'list',
- 'type' => 'preset',
- 'label' => __( 'Staff Profiles', 'gravityview' ),
- 'description' => __( 'List members of your team.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/staff-profiles/logo-staff-profiles.png', GRAVITYVIEW_FILE),
- 'preview' => 'http://demo.gravityview.co/blog/view/staff-profiles/',
- 'preset_form' => GRAVITYVIEW_DIR . 'includes/presets/staff-profiles/form-staff-profiles.xml',
- 'preset_fields' => GRAVITYVIEW_DIR . 'includes/presets/staff-profiles/fields-staff-profiles.xml',
- );
-
- parent::__construct( $id, $settings );
-
- }
-}
-
-class GravityView_Preset_Website_Showcase extends GravityView_Default_Template_List {
-
- function __construct() {
-
- $id = 'preset_website_showcase';
-
- $settings = array(
- 'slug' => 'list',
- 'type' => 'preset',
- 'label' => __( 'Website Showcase', 'gravityview' ),
- 'description' => __( 'Feature submitted websites with screenshots.', 'gravityview'),
- 'logo' => plugins_url('includes/presets/website-showcase/logo-website-showcase.png', GRAVITYVIEW_FILE),
- 'preview' => 'http://demo.gravityview.co/blog/view/website-showcase/',
- 'preset_form' => GRAVITYVIEW_DIR . 'includes/presets/website-showcase/form-website-showcase.xml',
- 'preset_fields' => GRAVITYVIEW_DIR . 'includes/presets/website-showcase/fields-website-showcase.xml'
- );
-
- parent::__construct( $id, $settings );
-
- }
-}
-
-new GravityView_Default_Template_Table;
-new GravityView_Default_Template_List;
-new GravityView_Default_Template_Edit;
-
-//presets
-new GravityView_Preset_Business_Listings;
-new GravityView_Preset_Business_Data;
-new GravityView_Preset_Profiles;
-new GravityView_Preset_Staff_Profiles;
-new GravityView_Preset_Website_Showcase;
-new GravityView_Preset_Issue_Tracker;
-new GravityView_Preset_Resume_Board;
-new GravityView_Preset_Job_Board;
-
-new GravityView_Preset_Event_Listings;
-#new GravityView_Preset_People_Table;
diff --git a/includes/extensions/delete-entry/class-delete-entry-shortcode.php b/includes/extensions/delete-entry/class-delete-entry-shortcode.php
deleted file mode 100644
index a9e34c0eb3..0000000000
--- a/includes/extensions/delete-entry/class-delete-entry-shortcode.php
+++ /dev/null
@@ -1,157 +0,0 @@
-add_hooks();
- }
-
- function add_hooks() {
- add_shortcode( 'gv_delete_entry_link', array( $this, 'shortcode' ) );
- }
-
- /**
- * Fetch the entry for the View
- *
- * We need to use this instead of GFAPI::get_entry() because we want to also pass the Form ID to the
- * get_entries() method.
- *
- * @param int $entry_id
- * @param int $form_id
- *
- * @return array|bool False if no entry exists; Entry array if exists.
- */
- function get_entry( $entry_id = 0, $form_id = 0 ) {
-
- $search_criteria = array(
- 'field_filters' => array(
- array(
- 'key' => 'id',
- 'value' => $entry_id
- )
- ),
- );
-
- $paging = array(
- 'offset' => 0,
- 'page_size' => 1
- );
-
- $entries = GFAPI::get_entries( $form_id, $search_criteria, null, $paging );
-
- $entry = ( ! is_wp_error( $entries ) && ! empty( $entries[0] ) ) ? $entries[0] : false;
-
- return $entry;
- }
-
- /**
- * @param array $atts {
- * @type string $view_id Define the ID for the View where the entry will
- * @type string $entry_id ID of the entry to edit. If undefined, uses the current entry ID
- * @type string $post_id ID of the base post or page to use for an embedded View
- * @type string $link_atts Whether to open Edit Entry link in a new window or the same window
- * @type string $return What should the shortcode return: link HTML (`html`) or the URL (`url`). Default: `html`
- * @type string $field_values Parameters to pass in to the Edit Entry form to prefill data. Uses the same format as Gravity Forms "Allow field to be populated dynamically" {@see https://www.gravityhelp.com/documentation/article/allow-field-to-be-populated-dynamically/ }
- * }
- * @param string $content
- * @param string $context
- *
- * @return string|void
- */
- public function shortcode( $atts = array(), $content = '', $context = 'gv_edit_entry' ) {
-
- // Make sure GV is loaded
- if( !class_exists('GravityView_frontend') || !class_exists('GravityView_View') ) {
- return null;
- }
-
- $defaults = array(
- 'view_id' => 0,
- 'entry_id' => 0,
- 'post_id' => 0,
- 'link_atts' => '',
- 'return' => 'html',
- 'field_values' => '',
- );
-
- $settings = shortcode_atts( $defaults, $atts, $context );
-
- if( empty( $settings['view_id'] ) ) {
- $view_id = GravityView_View::getInstance()->getViewId();
- } else {
- $view_id = absint( $settings['view_id'] );
- }
-
- if( empty( $view_id ) ) {
- do_action( 'gravityview_log_debug', __METHOD__ . ' A View ID was not defined' );
- return null;
- }
-
- $post_id = empty( $settings['post_id'] ) ? $view_id : absint( $settings['post_id'] );
-
- $form_id = gravityview_get_form_id( $view_id );
-
- $backup_entry_id = GravityView_frontend::getInstance()->getSingleEntry() ? GravityView_frontend::getInstance()->getSingleEntry() : GravityView_View::getInstance()->getCurrentEntry();
-
- $entry_id = empty( $settings['entry_id'] ) ? $backup_entry_id : absint( $settings['entry_id'] );
-
- if( empty( $entry_id ) ) {
- do_action( 'gravityview_log_debug', __METHOD__ . ' No entry defined' );
- return null;
- }
-
- // By default, show only current user
- $user = wp_get_current_user();
-
- if( ! $user ) {
- do_action( 'gravityview_log_debug', __METHOD__ . ' No user defined; edit entry requires logged in user' );
- return null;
- }
-
- $entry = $this->get_entry( $entry_id, $form_id );
-
- // No search results
- if( false === $entry ) {
- do_action( 'gravityview_log_debug', __METHOD__ . ' No entries match the entry ID defined', $entry_id );
- return null;
- }
-
- // Check permissions
- if( false === GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view_id ) ) {
- do_action( 'gravityview_log_debug', __METHOD__ . ' User does not have the capability to edit this entry: ' . $entry_id );
- return null;
- }
-
- $href = GravityView_Delete_Entry::get_delete_link( $entry, $view_id, $post_id, $settings );
-
- // Get just the URL, not the tag
- if( 'url' === $settings['return'] ) {
- return $href;
- }
-
- $link_text = empty( $content ) ? __('Delete Entry', 'gravityview') : $content;
-
- return gravityview_get_link( $href, $link_text, $settings['link_atts'] );
-
- }
-
-} //end class
-
-new GravityView_Delete_Entry_Shortcode;
diff --git a/includes/extensions/delete-entry/class-delete-entry.php b/includes/extensions/delete-entry/class-delete-entry.php
index 7147b76be0..af17b3d817 100644
--- a/includes/extensions/delete-entry/class-delete-entry.php
+++ b/includes/extensions/delete-entry/class-delete-entry.php
@@ -32,18 +32,9 @@ function __construct() {
self::$file = plugin_dir_path( __FILE__ );
- $this->include_files();
-
$this->add_hooks();
}
- /**
- * @since 1.9.2
- */
- private function include_files() {
- require_once( self::$file . 'class-delete-entry-shortcode.php' );
- }
-
/**
* @since 1.9.2
*/
@@ -240,6 +231,7 @@ public static function get_delete_link( $entry, $view_id = 0, $post_id = null )
$base = GravityView_API::directory_link( $post_id, true );
if( empty( $base ) ) {
+ do_action( 'gravityview_log_error', __METHOD__ . ' - Post ID does not exist: '.$post_id );
return NULL;
}
@@ -522,22 +514,28 @@ function user_can_delete_entry( $entry = array() ) {
* checks if user has permissions to view the link or delete a specific entry
*
* @since 1.5.1
+ * @since 1.15 Added `$view_id` param
+ *
* @param array $entry Gravity Forms entry array
* @param array $field Field settings (optional)
+ * @param int $view_id Pass a View ID to check caps against. If not set, check against current View (optional)
* @return bool
*/
- public static function check_user_cap_delete_entry( $entry, $field = array() ) {
+ public static function check_user_cap_delete_entry( $entry, $field = array(), $view_id = 0 ) {
$gravityview_view = GravityView_View::getInstance();
+ $current_user = wp_get_current_user();
+
+ $entry_id = isset( $entry['id'] ) ? $entry['id'] : NULL;
+
// Or if they can delete any entries (as defined in Gravity Forms), we're good.
- if( GFCommon::current_user_can_any( 'gravityforms_delete_entries' ) ) {
+ if( GVCommon::has_cap( array( 'gravityforms_delete_entries', 'gravityview_delete_others_entries' ), $entry_id ) ) {
- do_action('gravityview_log_debug', 'GravityView_Delete_Entry[check_user_cap_delete_entry] Current user has `gravityforms_delete_entries` capability.' );
+ do_action('gravityview_log_debug', 'GravityView_Delete_Entry[check_user_cap_delete_entry] Current user has `gravityforms_delete_entries` or `gravityview_delete_others_entries` capability.' );
return true;
}
- $current_user = wp_get_current_user();
// If field options are passed, check if current user can view the link
if( !empty( $field ) ) {
@@ -550,7 +548,7 @@ public static function check_user_cap_delete_entry( $entry, $field = array() ) {
return false;
}
- if( GFCommon::current_user_can_any( $field['allow_edit_cap'] ) ) {
+ if( GVCommon::has_cap( $field['allow_edit_cap'] ) ) {
// Do not return true if cap is read, as we need to check if the current user created the entry
if( $field['allow_edit_cap'] !== 'read' ) {
@@ -573,10 +571,12 @@ public static function check_user_cap_delete_entry( $entry, $field = array() ) {
return false;
}
+ $view_id = empty( $view_id ) ? $gravityview_view->getViewId() : $view_id;
+
// Only checks user_delete view option if view is already set
- if( $gravityview_view->getViewId() ) {
+ if( $view_id ) {
- $current_view = gravityview_get_current_view_data();
+ $current_view = gravityview_get_current_view_data( $view_id );
$user_delete = isset( $current_view['atts']['user_delete'] ) ? $current_view['atts']['user_delete'] : false;
diff --git a/includes/extensions/edit-entry/class-edit-entry-render.php b/includes/extensions/edit-entry/class-edit-entry-render.php
index 2245e82cae..f977074c0e 100644
--- a/includes/extensions/edit-entry/class-edit-entry-render.php
+++ b/includes/extensions/edit-entry/class-edit-entry-render.php
@@ -351,7 +351,7 @@ function maybe_update_post_fields( $form ) {
$post_id = $this->entry['post_id'];
// Security check
- if( false === current_user_can( 'edit_post', $post_id ) ) {
+ if( false === GVCommon::has_cap( 'edit_post', $post_id ) ) {
do_action( 'gravityview_log_error', 'The current user does not have the ability to edit Post #'.$post_id );
return;
}
@@ -509,12 +509,12 @@ public function edit_entry_form() {
@@ -642,9 +642,7 @@ private function render_edit_form() {
* @return string
*/
public function render_form_buttons() {
- ob_start();
- include( GravityView_Edit_Entry::$file .'/partials/form-buttons.php');
- return ob_get_clean();
+ return gravityview_ob_include( GravityView_Edit_Entry::$file .'/partials/form-buttons.php', $this );
}
@@ -718,12 +716,9 @@ function modify_edit_field_input( $field_content = '', $field, $value, $lead_id
}
/**
- * Allow the pre-populated value to override saved value
- * By default, pre-populate mechanism only kicks on empty fields
- *
+ * @filter `gravityview/edit_entry/pre_populate/override` Allow the pre-populated value to override saved value in Edit Entry form. By default, pre-populate mechanism only kicks on empty fields.
* @param boolean True: override saved values; False: don't override (default)
* @param $field GF_Field object Gravity Forms field object
- *
* @since 1.13
*/
$override_saved_value = apply_filters( 'gravityview/edit_entry/pre_populate/override', false, $field );
@@ -777,9 +772,8 @@ function modify_edit_field_input( $field_content = '', $field, $value, $lead_id
$field_value = $field->get_value_default_if_empty( $field_value );
/**
- * change the field value if needed
+ * @filter `gravityview/edit_entry/field_value` Change the value of an Edit Entry field, if needed
* @since 1.11
- *
* @param mixed $field_value field value used to populate the input
* @param object $field Gravity Forms field object ( Class GF_Field )
*/
@@ -794,7 +788,7 @@ function modify_edit_field_input( $field_content = '', $field, $value, $lead_id
$warnings = ob_get_clean();
if( !empty( $warnings ) ) {
- do_action( 'gravityview_log_error', __METHOD__ . $warnings );
+ do_action( 'gravityview_log_error', __METHOD__ . $warnings, $field_value );
}
/**
@@ -1206,10 +1200,11 @@ private function filter_fields( $fields, $configured_fields ) {
);
/**
- * Hide product fields from being editable. Default: false (set using self::$supports_product_fields)
+ * @filter `gravityview/edit_entry/hide-product-fields` Hide product fields from being editable.
* @since 1.9.1
+ * @param boolean $hide_product_fields Whether to hide product fields in the editor. Default: false
*/
- $hide_product_fields = apply_filters( 'gravityview/edit_entry/hide-product-fields', empty( $supports_product_fields ) );
+ $hide_product_fields = apply_filters( 'gravityview/edit_entry/hide-product-fields', empty( self::$supports_product_fields ) );
if( $hide_product_fields ) {
$field_type_blacklist[] = 'option';
@@ -1297,18 +1292,17 @@ private function merge_field_properties( $field, $field_setting ) {
function filter_admin_only_fields( $fields = array(), $edit_fields = null, $form = array(), $view_id = 0 ) {
/**
+ * @filter `gravityview/edit_entry/use_gf_admin_only_setting` When Edit tab isn't configured, should the Gravity Forms "Admin Only" field settings be used to control field display to non-admins? Default: true
* If the Edit Entry tab is not configured, adminOnly fields will not be shown to non-administrators.
* If the Edit Entry tab *is* configured, adminOnly fields will be shown to non-administrators, using the configured GV permissions
- *
* @since 1.9.1
- *
* @param boolean $use_gf_adminonly_setting True: Hide field if set to Admin Only in GF and the user is not an admin. False: show field based on GV permissions, ignoring GF permissions.
* @param array $form GF Form array
* @param int $view_id View ID
*/
$use_gf_adminonly_setting = apply_filters( 'gravityview/edit_entry/use_gf_admin_only_setting', empty( $edit_fields ), $form, $view_id );
- if( $use_gf_adminonly_setting && false === GFCommon::current_user_can_any( 'gravityforms_edit_entries' ) ) {
+ if( $use_gf_adminonly_setting && false === GVCommon::has_cap( 'gravityforms_edit_entries', $this->entry['id'] ) ) {
return $fields;
}
@@ -1326,12 +1320,20 @@ function filter_admin_only_fields( $fields = array(), $edit_fields = null, $form
*
* @since 1.9
*
- * @param $form
- * @return mixed
+ * @param array $form Gravity Forms form
+ * @return array Modified form, if not using Conditional Logic
*/
function filter_conditional_logic( $form ) {
- if( apply_filters( 'gravityview/edit_entry/conditional_logic', true, $form ) ) {
+ /**
+ * @filter `gravityview/edit_entry/conditional_logic` Should the Edit Entry form use Gravity Forms conditional logic showing/hiding of fields?
+ * @since 1.9
+ * @param bool $use_conditional_logic True: Gravity Forms will show/hide fields just like in the original form; False: conditional logic will be disabled and fields will be shown based on configuration. Default: true
+ * @param array $form Gravity Forms form
+ */
+ $use_conditional_logic = apply_filters( 'gravityview/edit_entry/conditional_logic', true, $form );
+
+ if( $use_conditional_logic ) {
return $form;
}
@@ -1488,7 +1490,7 @@ private function user_can_edit_field( $field, $echo = false ) {
private function check_user_cap_edit_field( $field ) {
// If they can edit any entries (as defined in Gravity Forms), we're good.
- if( GFCommon::current_user_can_any( 'gravityforms_edit_entries' ) ) {
+ if( GVCommon::has_cap( array( 'gravityforms_edit_entries', 'gravityview_edit_others_entries' ) ) ) {
return true;
}
@@ -1496,7 +1498,7 @@ private function check_user_cap_edit_field( $field ) {
// If the field has custom editing capaibilities set, check those
if( $field_cap ) {
- return GFCommon::current_user_can_any( $field['allow_edit_cap'] );
+ return GVCommon::has_cap( $field['allow_edit_cap'] );
}
return false;
@@ -1524,9 +1526,8 @@ public function verify_nonce() {
}
/**
- * Override nonce validation
+ * @filter `gravityview/edit_entry/verify_nonce` Override Edit Entry nonce validation. Return true to declare nonce valid.
* @since 1.13
- *
* @param int|boolean $valid False if invalid; 1 or 2 when nonce was generated
* @param string $nonce_field Key used when validating submissions. Default: is_gv_edit_entry
*/
diff --git a/includes/extensions/edit-entry/class-edit-entry-shortcode.php b/includes/extensions/edit-entry/class-edit-entry-shortcode.php
deleted file mode 100644
index 516224557b..0000000000
--- a/includes/extensions/edit-entry/class-edit-entry-shortcode.php
+++ /dev/null
@@ -1,192 +0,0 @@
-loader = $loader;
- }
-
- function load() {
-
- add_shortcode( 'gv_edit_entry_link', array( $this, 'shortcode' ) );
-
- }
-
- /**
- * Fetch the entry for the View
- *
- * We need to use this instead of GFAPI::get_entry() because we want to also pass the Form ID to the
- * get_entries() method.
- *
- * @param int $entry_id
- * @param int $form_id
- *
- * @return array|bool False if no entry exists; Entry array if exists.
- */
- function get_entry( $entry_id = 0, $form_id = 0 ) {
-
- $search_criteria = array(
- 'field_filters' => array(
- array(
- 'key' => 'id',
- 'value' => $entry_id
- )
- ),
- );
-
- $paging = array(
- 'offset' => 0,
- 'page_size' => 1
- );
-
- $entries = GFAPI::get_entries( $form_id, $search_criteria, null, $paging );
-
- $entry = ( ! is_wp_error( $entries ) && ! empty( $entries[0] ) ) ? $entries[0] : false;
-
- return $entry;
- }
-
- /**
- * Get the URL for the Edit Entry link
- *
- * @param array $entry GF Entry array
- * @param int $view_id View ID
- * @param int $post_id Optional: alternative base URL for embedded Views
- */
- private function get_edit_url( $entry, $view_id, $post_id, $settings = array() ) {
-
- $href = GravityView_Edit_Entry::get_edit_link( $entry, $view_id, $post_id );
-
- // Allow passing params to dynamically populate
- if( !empty( $settings['field_values'] ) ) {
-
- parse_str( $settings['field_values'], $field_values );
-
- $href = add_query_arg( $field_values, $href );
- }
-
- return $href;
- }
-
- /**
- * @param array $atts {
- * @type string $view_id Define the ID for the View where the entry will
- * @type string $entry_id ID of the entry to edit. If undefined, uses the current entry ID
- * @type string $post_id ID of the base post or page to use for an embedded View
- * @type string $link_atts Whether to open Edit Entry link in a new window or the same window
- * @type string $return What should the shortcode return: link HTML (`html`) or the URL (`url`). Default: `html`
- * @type string $field_values Parameters to pass in to the Edit Entry form to prefill data. Uses the same format as Gravity Forms "Allow field to be populated dynamically" {@see https://www.gravityhelp.com/documentation/article/allow-field-to-be-populated-dynamically/ }
- * }
- * @param string $content
- * @param string $context
- *
- * @return string|void
- */
- public function shortcode( $atts = array(), $content = '', $context = 'gv_edit_entry' ) {
-
- // Make sure GV is loaded
- if( !class_exists('GravityView_frontend') || !class_exists('GravityView_View') ) {
- return null;
- }
-
- $defaults = array(
- 'view_id' => 0,
- 'entry_id' => 0,
- 'post_id' => 0,
- 'link_atts' => '',
- 'return' => 'html',
- 'field_values' => '',
- );
-
- $settings = shortcode_atts( $defaults, $atts, $context );
-
- if( empty( $settings['view_id'] ) ) {
- $view_id = GravityView_View::getInstance()->getViewId();
- } else {
- $view_id = absint( $settings['view_id'] );
- }
-
- if( empty( $view_id ) ) {
- do_action( 'gravityview_log_debug', __METHOD__ . ' A View ID was not defined' );
- return null;
- }
-
- // if post_id is not defined, default to view_id
- $post_id = empty( $settings['post_id'] ) ? $view_id : absint( $settings['post_id'] );
-
- $form_id = gravityview_get_form_id( $view_id );
-
- $backup_entry_id = GravityView_frontend::getInstance()->getSingleEntry() ? GravityView_frontend::getInstance()->getSingleEntry() : GravityView_View::getInstance()->getCurrentEntry();
-
- $entry_id = empty( $settings['entry_id'] ) ? $backup_entry_id : absint( $settings['entry_id'] );
-
- if( empty( $entry_id ) ) {
- do_action( 'gravityview_log_debug', __METHOD__ . ' No entry defined' );
- return null;
- }
-
- // By default, show only current user
- $user = wp_get_current_user();
-
- if( ! $user ) {
- do_action( 'gravityview_log_debug', __METHOD__ . ' No user defined; edit entry requires logged in user' );
- return null;
- }
-
- $entry = $this->get_entry( $entry_id, $form_id );
-
- // No search results
- if( false === $entry ) {
- do_action( 'gravityview_log_debug', __METHOD__ . ' No entries match the entry ID defined', $entry_id );
- return null;
- }
-
- // Check permissions
- if( false === GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view_id ) ) {
- do_action( 'gravityview_log_debug', __METHOD__ . ' User does not have the capability to edit this entry: ' . $entry_id );
- return null;
- }
-
- $href = $this->get_edit_url( $entry, $view_id, $post_id, $settings );
-
- // Get just the URL, not the tag
- if( 'url' === $settings['return'] ) {
- return $href;
- }
-
- $link_text = empty( $content ) ? __('Edit Entry', 'gravityview') : $content;
-
- return gravityview_get_link( $href, $link_text, $settings['link_atts'] );
-
- }
-
-} //end class
diff --git a/includes/extensions/edit-entry/class-edit-entry-user-registration.php b/includes/extensions/edit-entry/class-edit-entry-user-registration.php
index 2048025a4e..17a11e64c1 100644
--- a/includes/extensions/edit-entry/class-edit-entry-user-registration.php
+++ b/includes/extensions/edit-entry/class-edit-entry-user-registration.php
@@ -46,9 +46,7 @@ public function load() {
if( apply_filters( 'gravityview/edit_entry/user_registration/trigger_update', true ) ) {
add_action( 'gravityview/edit_entry/after_update' , array( $this, 'update_user' ), 10, 2 );
- /**
- * TODO: Should be removed once Gravity Forms allows for defining "Preserve current Display Name" option
- */
+ // last resort in case the current user display name don't match any of the defaults
add_action( 'gform_user_updated', array( $this, 'restore_display_name' ), 10, 4 );
}
}
@@ -83,6 +81,27 @@ public function update_user( $form = array(), $entry_id = 0 ) {
*/
$config = GFUser::get_active_config( $form, $entry );
+ /**
+ * @filter `gravityview/edit_entry/user_registration/preserve_role` Keep the current user role or override with the role defined in the Create feed
+ * @since 1.15
+ * @param[in,out] boolean $preserve_role Preserve current user role Default: true
+ * @param[in] array $config Gravity Forms User Registration feed configuration for the form
+ * @param[in] array $form Gravity Forms form array
+ * @param[in] array $entry Gravity Forms entry being edited
+ */
+ $preserve_role = apply_filters( 'gravityview/edit_entry/user_registration/preserve_role', true, $config, $form, $entry );
+
+ if( $preserve_role ) {
+ $config['meta']['role'] = 'gfur_preserve_role';
+ }
+
+ /**
+ * Make sure the current display name is not changed with the update user method.
+ * @since 1.15
+ */
+ $config['meta']['displayname'] = $this->match_current_display_name( $entry['created_by'] );
+
+
/**
* @filter `gravityview/edit_entry/user_registration/config` Modify the User Registration Addon feed configuration
* @since 1.14
@@ -92,25 +111,84 @@ public function update_user( $form = array(), $entry_id = 0 ) {
*/
$config = apply_filters( 'gravityview/edit_entry/user_registration/config', $config, $form, $entry );
- $is_update_feed = ( $config && rgars( $config, 'meta/feed_type') === 'update' );
+ $is_create_feed = ( $config && rgars( $config, 'meta/feed_type') === 'create' );
+
+ // Only update if it's a create feed
+ if( ! $is_create_feed ) {
+ return;
+ }
+
+ // The priority is set to 3 so that default priority (10) will still override it
+ add_filter( 'send_password_change_email', '__return_false', 3 );
+ add_filter( 'send_email_change_email', '__return_false', 3 );
+
+ // Trigger the User Registration update user method
+ GFUser::update_user( $entry, $form, $config );
+
+ remove_filter( 'send_password_change_email', '__return_false', 3 );
+ remove_filter( 'send_email_change_email', '__return_false', 3 );
+
+ }
- // Only update if it's an update feed (not a create feed)
- if( $is_update_feed ) {
+ /**
+ * Calculate the user display name format
+ *
+ * @since 1.15
+ *
+ * @param int $user_id WP User ID
+ * @return string Display name format as used inside Gravity Forms User Registration
+ */
+ public function match_current_display_name( $user_id ) {
+
+ $user = get_userdata( $user_id );
+
+ $names = $this->generate_display_names( $user );
+
+ $format = array_search( $user->display_name, $names, true );
+
+ // In case we can't find the current display name format, or it is the 'nickname' format (which Gravity Forms doesn't support)
+ // trigger last resort method at the 'gform_user_updated' hook
+ if( false === $format || 'nickname' === $format ) {
+ $this->_user_before_update = $user;
+ $format = 'nickname';
+ }
+
+ return $format;
- $this->_user_before_update = get_userdata( $entry['created_by'] );
+ }
+
+ /**
+ * Generate an array of all the user display names possibilities
+ *
+ * @since 1.15
+ *
+ * @param object $profileuser WP_User object
+ * @return array List all the possible display names for a certain User object
+ */
+ public function generate_display_names( $profileuser ) {
+
+ $public_display = array();
+ $public_display['nickname'] = $profileuser->nickname;
+ $public_display['username'] = $profileuser->user_login;
- // The priority is set to 3 so that default priority (10) will still override it
- add_filter( 'send_password_change_email', '__return_false', 3 );
- add_filter( 'send_email_change_email', '__return_false', 3 );
+ if ( !empty($profileuser->first_name) )
+ $public_display['firstname'] = $profileuser->first_name;
- // Trigger the User Registration update user method
- GFUser::update_user( $entry, $form, $config );
+ if ( !empty($profileuser->last_name) )
+ $public_display['lastname'] = $profileuser->last_name;
- remove_filter( 'send_password_change_email', '__return_false', 3 );
- remove_filter( 'send_email_change_email', '__return_false', 3 );
+ if ( !empty($profileuser->first_name) && !empty($profileuser->last_name) ) {
+ $public_display['firstlast'] = $profileuser->first_name . ' ' . $profileuser->last_name;
+ $public_display['lastfirst'] = $profileuser->last_name . ' ' . $profileuser->first_name;
}
+
+ $public_display = array_map( 'trim', $public_display );
+ $public_display = array_unique( $public_display );
+
+ return $public_display;
}
+
/**
* Restore the Display Name and roles of a user after being updated by Gravity Forms User Registration Addon
*
@@ -134,10 +212,13 @@ public function restore_display_name( $user_id = 0, $config = array(), $entry =
$is_update_feed = ( $config && rgars( $config, 'meta/feed_type') === 'update' );
/**
- * Don't restore display name: either disabled, or not an Update feed (it's a Create feed)
+ * Don't restore display name:
+ * - either disabled,
+ * - or it is an Update feed (we only care about Create feed)
+ * - or we don't need as we found the correct format before updating user.
* @since 1.14.4
*/
- if( ! $restore_display_name || ! $is_update_feed ) {
+ if( ! $restore_display_name || $is_update_feed || is_null( $this->_user_before_update ) ) {
return;
}
diff --git a/includes/extensions/edit-entry/class-edit-entry.php b/includes/extensions/edit-entry/class-edit-entry.php
index 9db40f3f58..ec5798bbbf 100644
--- a/includes/extensions/edit-entry/class-edit-entry.php
+++ b/includes/extensions/edit-entry/class-edit-entry.php
@@ -18,6 +18,9 @@
class GravityView_Edit_Entry {
+ /**
+ * @var string
+ */
static $file;
static $instance;
@@ -31,7 +34,7 @@ class GravityView_Edit_Entry {
function __construct() {
- self::$file = plugin_dir_path( __FILE__ );
+ self::$file = plugin_dir_path( __FILE__ );
if( is_admin() ) {
$this->load_components( 'admin' );
@@ -39,7 +42,6 @@ function __construct() {
$this->load_components( 'render' );
- $this->load_components( 'shortcode' );
// If GF User Registration Add-on exists
if( class_exists( 'GFUser' ) ) {
@@ -223,8 +225,12 @@ public static function check_user_cap_edit_entry( $entry, $view_id = 0 ) {
// No permission by default
$user_can_edit = false;
- // Or if they can edit any entries (as defined in Gravity Forms), we're good.
- if( GFCommon::current_user_can_any( 'gravityforms_edit_entries' ) ) {
+ // If they can edit any entries (as defined in Gravity Forms)
+ // Or if they can edit other people's entries
+ // Then we're good.
+ if( GVCommon::has_cap( array( 'gravityforms_edit_entries', 'gravityview_edit_others_entries' ), $entry['id'] ) ) {
+
+ do_action('gravityview_log_debug', __METHOD__ . ' - User has ability to edit all entries.');
$user_can_edit = true;
@@ -261,15 +267,20 @@ public static function check_user_cap_edit_entry( $entry, $view_id = 0 ) {
do_action('gravityview_log_debug', sprintf( 'GravityView_Edit_Entry[check_user_cap_edit_entry] User %s created the entry.', $current_user->ID ) );
$user_can_edit = true;
+
+ } else if( ! is_user_logged_in() ) {
+
+ do_action( 'gravityview_log_debug', __METHOD__ . ' No user defined; edit entry requires logged in user' );
}
}
/**
* @filter `gravityview/edit_entry/user_can_edit_entry` Modify whether user can edit an entry.
+ * @since 1.15 Added `$entry` and `$view_id` parameters
* @param[in,out] boolean $user_can_edit Can the current user edit the current entry? (Default: false)
- * @param[in] array $entry Gravity Forms entry array {@since 1.14.4}
- * @param[in] int $view_id ID of the view you want to check visibility against {@since 1.14.4}
+ * @param[in] array $entry Gravity Forms entry array {@since 1.15}
+ * @param[in] int $view_id ID of the view you want to check visibility against {@since 1.15}
*/
$user_can_edit = apply_filters( 'gravityview/edit_entry/user_can_edit_entry', $user_can_edit, $entry, $view_id );
diff --git a/includes/extensions/edit-entry/partials/form-buttons.php b/includes/extensions/edit-entry/partials/form-buttons.php
index 3a4d44bcd5..df54a10d64 100644
--- a/includes/extensions/edit-entry/partials/form-buttons.php
+++ b/includes/extensions/edit-entry/partials/form-buttons.php
@@ -1,3 +1,9 @@
+
form, $this->entry, $this->view_id );
+ $back_link = apply_filters( 'gravityview/edit_entry/cancel_link', remove_query_arg( array( 'page', 'view', 'edit' ) ), $object->form, $object->entry, $object->view_id );
/**
* @action `gravityview/edit-entry/publishing-action/before` Triggered before the submit buttons in the Edit Entry screen, inside the `
` container.
@@ -18,10 +24,10 @@
* @param array $entry The Gravity Forms entry
* @param int $view_id The current View ID
*/
- do_action( 'gravityview/edit-entry/publishing-action/before', $this->form, $this->entry, $this->view_id );
+ do_action( 'gravityview/edit-entry/publishing-action/before', $object->form, $object->entry, $object->view_id );
?>
-
+
form, $this->entry, $this->view_id );
+ do_action( 'gravityview/edit-entry/publishing-action/after', $object->form, $object->entry, $object->view_id );
?>
-
+