From 24c81c2538ce93092ff331c911dced7f2a9fd640 Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Tue, 28 May 2024 16:55:18 +0200 Subject: [PATCH 01/11] Find associated field by field name instead of type first. --- includes/fields/class-gravityview-fields.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/includes/fields/class-gravityview-fields.php b/includes/fields/class-gravityview-fields.php index fbfab7745..06054ce51 100644 --- a/includes/fields/class-gravityview-fields.php +++ b/includes/fields/class-gravityview-fields.php @@ -93,11 +93,20 @@ public static function get( $field_name ) { * @return GravityView_Field|false Returns false if no matching fields found */ public static function get_associated_field( $gf_field ) { - - $field_type = is_a( $gf_field, 'GF_Field' ) ? get_class( $gf_field ) : $gf_field; + $is_field = $gf_field instanceof GF_Field; + $field_class = $is_field ? get_class( $gf_field ) : $gf_field; + $field_name = $is_field && ! is_numeric( $gf_field->id ) ? $gf_field->id : null; + + if ( $field_name ) { + foreach ( self::$_fields as $field ) { + if ( $field_name === $field->name ) { + return $field; + } + } + } foreach ( self::$_fields as $field ) { - if ( $field_type === $field->_gf_field_class_name ) { + if ( $field_class === $field->_gf_field_class_name ) { return $field; } } From 5c54a9e5a75d2f35a85f54e85c37a61609e162e3 Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Tue, 28 May 2024 16:57:39 +0200 Subject: [PATCH 02/11] Add created_by field rendering for edit view. --- .../class-gravityview-field-created-by.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/includes/fields/class-gravityview-field-created-by.php b/includes/fields/class-gravityview-field-created-by.php index b842ddaaf..f668cf572 100644 --- a/includes/fields/class-gravityview-field-created-by.php +++ b/includes/fields/class-gravityview-field-created-by.php @@ -153,6 +153,25 @@ public function field_options( $field_options, $template_id, $field_id, $context return $field_options; } + + /** + * Returns the HTML for the field input. + * + * @since $ver$ + * + * @param array $form The form object. + * @param mixed $value The field value. + * @param array $entry The entry object. + * @param GF_Field $field The field object. + * + * @return string The input HTML. + */ + public function get_field_input( array $form, $value, array $entry, GF_Field $field ): string { + return sprintf( + '
%s
', + GravityView_Change_Entry_Creator::get_select_field( $entry ) + ); + } } new GravityView_Field_Created_By(); From 77a8113fd74ccc61734ae5a7e2719260578fce92 Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Tue, 28 May 2024 16:59:36 +0200 Subject: [PATCH 03/11] Add ability to change created by user: - Add Created By (User) field to the edit screen - Renders the field on the entry form - Stores the value when the user has the correct rights - Refactored to get original user from old entry data instead of post value --- ...class-gravityview-change-entry-creator.php | 194 +++++++++++++++--- 1 file changed, 166 insertions(+), 28 deletions(-) diff --git a/includes/class-gravityview-change-entry-creator.php b/includes/class-gravityview-change-entry-creator.php index 7b7cb2fa7..3507fed1a 100644 --- a/includes/class-gravityview-change-entry-creator.php +++ b/includes/class-gravityview-change-entry-creator.php @@ -17,21 +17,21 @@ function __construct() { */ add_action( 'gform_user_registered', array( $this, 'assign_new_user_to_lead' ), 10, 4 ); - // ONLY ADMIN FROM HERE ON. - if ( ! is_admin() ) { - return; - } - /** * Disable the Change Entry Creator functionality. * * @since 1.7.4 + * * @param boolean $disable Disable the Change Entry Creator functionality. Default: false. */ if ( apply_filters( 'gravityview_disable_change_entry_creator', false ) ) { return; } + add_filter( 'gravityview_entry_default_fields', [ $this, 'register_edit_field' ], 10, 3 ); + add_filter( 'gravityview/edit_entry/form_fields', [ $this, 'register_created_by_input' ], 10, 3 ); + add_filter( 'gravityview_field_visibility_caps', [ $this, 'created_by_visibility_caps' ], 15, 3 ); + /** * Use `init` to fix bbPress warning * @@ -76,7 +76,10 @@ function enqueue_selectwoo_assets() { wp_enqueue_script( 'gravityview_selectwoo', plugins_url( 'assets/lib/selectWoo/selectWoo.full.min.js', GRAVITYVIEW_FILE ), array(), $version ); wp_enqueue_style( 'gravityview_selectwoo', plugins_url( 'assets/lib/selectWoo/selectWoo.min.css', GRAVITYVIEW_FILE ), array(), $version ); - wp_enqueue_script( 'gravityview_entry_creator', plugins_url( 'assets/js/admin-entry-creator' . $script_debug . '.js', GRAVITYVIEW_FILE ), array( 'jquery', 'gravityview_selectwoo' ), $version ); + wp_enqueue_script( 'gravityview_entry_creator', plugins_url( 'assets/js/admin-entry-creator' . $script_debug . '.js', GRAVITYVIEW_FILE ), array( + 'jquery', + 'gravityview_selectwoo' + ), $version ); wp_localize_script( 'gravityview_entry_creator', @@ -134,10 +137,12 @@ function entry_creator_get_users() { * When an user is created using the User Registration add-on, assign the entry to them * * @since 1.5.1 + * * @param int $user_id WordPress User ID * @param array $config User registration feed configuration * @param array $entry GF Entry array * @param string $password User password + * * @return void * @uses RGFormsModel::update_lead_property() Modify the entry `created_by` field */ @@ -175,6 +180,7 @@ function assign_new_user_to_lead( $user_id, $config, $entry = array(), $password * Disable adding a note when changing the entry creator. * * @since 1.21.5 + * * @param boolean $disable Disable the Change Entry Creator note. Default: false. */ if ( apply_filters( 'gravityview_disable_change_entry_creator_note', false ) ) { @@ -197,6 +203,23 @@ function prevent_conflicts() { remove_action( 'gform_after_update_entry', 'gravityview_update_entry_creator', 10 ); } + /** + * Whether the current user has the rights to edit the entry creator. + * + * @since $ver$ + * + * @return bool Whether the user has rights. + */ + private function is_user_allowed(): bool { + // Todo: only show users if the user has rights to see all users. + // Can the user edit entries? + if ( ! GVCommon::has_cap( array( 'gravityforms_edit_entries', 'gravityview_edit_entries' ) ) ) { + return false; + } + + return true; + } + /** * @since 3.6.3 * @return void @@ -209,12 +232,21 @@ function load() { } // Can the user edit entries? - if ( ! GVCommon::has_cap( array( 'gravityforms_edit_entries', 'gravityview_edit_entries' ) ) ) { + if ( ! $this->is_user_allowed() ) { return; } - // If screen mode isn't set, then we're in the wrong place. - if ( empty( $_REQUEST['screen_mode'] ) ) { + /** + * If screen mode isn't set, then we're in the wrong place. + * But if we posted a valid nonce, then we are legit. + */ + if ( + empty( $_REQUEST['screen_mode'] ) + && ( + ! rgpost( 'gv_entry_creator_nonce' ) + || ! wp_verify_nonce( rgpost( 'gv_entry_creator_nonce' ), 'gv_entry_creator' ) + ) + ) { return; } @@ -223,7 +255,7 @@ function load() { add_action( 'gform_entry_info', array( &$this, 'add_select' ), 10, 2 ); - add_action( 'gform_after_update_entry', array( &$this, 'update_entry_creator' ), 10, 2 ); + add_action( 'gform_after_update_entry', array( &$this, 'update_entry_creator' ), 10, 3 ); } /** @@ -248,9 +280,10 @@ function set_screen_mode() { * * @param array $form GF entry array * @param int $entry_id Entry ID + * * @return void */ - function update_entry_creator( $form, $entry_id ) { + function update_entry_creator( $form, $entry_id, array $original_entry ) { global $current_user; @@ -260,7 +293,7 @@ function update_entry_creator( $form, $entry_id ) { RGFormsModel::update_lead_property( $entry_id, 'created_by', $created_by ); // If the creator has changed, let's add a note about who it used to be. - $originally_created_by = \GV\Utils::_POST( 'originally_created_by' ); + $originally_created_by = rgar( $original_entry, 'created_by' ); // If there's no owner and there didn't used to be, keep going if ( empty( $originally_created_by ) && empty( $created_by ) ) { @@ -297,23 +330,16 @@ function update_entry_creator( $form, $entry_id ) { } /** - * Output select element used to change the entry creator + * Returns the HTML for the user select field. * - * @param int $form_id GF Form ID - * @param array $entry GF entry array + * @since $ver$ * - * @return void + * @param array $entry The entry object. + * + * @return string The HTML. */ - function add_select( $form_id, $entry ) { - - if ( 'edit' !== \GV\Utils::_POST( 'screen_mode' ) ) { - return; - } - - $output = ''; - $output .= ''; $entry_creator_user_id = \GV\Utils::get( $entry, 'created_by' ); @@ -344,13 +370,34 @@ function add_select( $form_id, $entry ) { $user_users = _n( esc_html__( 'user', 'gk-gravityview' ), esc_html__( 'users', 'gk-gravityview' ), $remaining_users ); $message = esc_html_x( 'Use the input above to search the remaining %1$d %2$s.', '%d is replaced with user count %s is replaced with "user" or "users"', 'gk-gravityview' ); $message = sprintf( $message, $remaining_users, $user_users ); - $output .= ''; + $output .= ''; } $output .= ''; - $output .= ''; $output .= wp_nonce_field( 'gv_entry_creator', 'gv_entry_creator_nonce', false, false ); + return $output; + } + + /** + * Output select element used to change the entry creator + * + * @param int $form_id GF Form ID + * @param array $entry GF entry array + * + * @return void + */ + function add_select( $form_id, $entry ) { + + if ( 'edit' !== \GV\Utils::_POST( 'screen_mode' ) ) { + return; + } + + $output = ''; + $output .= self::get_select_field( $entry ); + echo $output; } @@ -367,6 +414,97 @@ function register_gform_noconflict( $assets ) { return $assets; } + + /** + * Registers the `created_by` field on the `Edit Entry` tab. + * + * @since $ver$ + * + * @param GF_Field[] $fields The registered fields. + * @param array $form The form object. + * @param string $zone The fields zone. + * + * @return array The updated fields array. + */ + public function register_edit_field( array $fields, array $form, string $zone ): array { + if ( 'edit' !== $zone ) { + return $fields; + } + + $meta_fields = GravityView_Fields::get_all( array( 'meta', 'gravityview' ), $zone ); + $field = $meta_fields['created_by'] ?? null; + + if ( $field ) { + $fields += $field->as_array(); + } + + return $fields; + } + + /** + * Registers the `created_by` field on the `Edit Entry` tab. + * + * @since $ver$ + * + * @param GF_Field[] $fields The registered fields. + * @param array|null $editable_fields The fields zone. + * @param array $form The form object. + * + * @return array The updated fields array. + */ + public function register_created_by_input( array $fields, ?array $editable_fields, array $form ): array { + // Don't add the `created_by` field if the user can't change it. + $editable_field_ids = array_flip( array_map( static function ( array $field ): string { + return $field['id'] ?? 0; + }, $editable_fields ?? [] ) ); + + $form = GFExport::add_default_export_fields( $form ); + $form_fields = array_column( $form['fields'], null, 'id' ); + + // Don't show field automatically, only when actively added. + if ( null === $editable_fields || ! isset( $editable_field_ids['created_by'] ) ) { + return $fields; + } + + $configuration = $editable_fields[ $editable_field_ids['created_by'] ] ?? []; + + if ( ! GVCommon::has_cap( array( $configuration['allow_edit_cap'] ?? 'manage_options' ) ) ) { + return $fields; + } + + $fields[] = $form_fields['created_by']; + + // Sort fields according to Gravity View. + $sort_order_lookup = array_flip( array_keys( $editable_field_ids ) ); + + uasort( $fields, static function ( GF_Field $a, GF_Field $b ) use ( $sort_order_lookup ): int { + return $sort_order_lookup[ $a->id ] ?? 0 <=> $sort_order_lookup[ $b->id ]; + } ); + + return $fields; + } + + /** + * Manages the visibility capabilities for the `created_by` field on the edit page. + * + * @since $ver$ + * + * @param array $caps The capabilities. + * @param string $template The template name. + * @param string $field The field name. + * + * @return array The new capabilities. + */ + public function created_by_visibility_caps( array $caps, string $template, string $field ): array { + if ( 'created_by' !== $field || false === strpos( $template, 'edit' ) ) { + return $caps; + } + + // Read users can't update the `created_by` field. + unset ( $caps['read'] ); + + return $caps; + } } new GravityView_Change_Entry_Creator(); From 18b10c502c04b117407e87359a5c63b955618a9e Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Mon, 16 Sep 2024 15:06:47 +0200 Subject: [PATCH 04/11] Add check for `list_users` and update readme --- ...class-gravityview-change-entry-creator.php | 57 +++++++++++-------- readme.txt | 1 + 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/includes/class-gravityview-change-entry-creator.php b/includes/class-gravityview-change-entry-creator.php index 3507fed1a..9d2217771 100644 --- a/includes/class-gravityview-change-entry-creator.php +++ b/includes/class-gravityview-change-entry-creator.php @@ -8,9 +8,9 @@ class GravityView_Change_Entry_Creator { /* * @var int Number of users to show in the select element */ - const DEFAULT_NUMBER_OF_USERS = 100; + public const DEFAULT_NUMBER_OF_USERS = 100; - function __construct() { + public function __construct() { /** * @since 1.5.1 @@ -55,7 +55,7 @@ function __construct() { * * @since 2.9.1 */ - function enqueue_selectwoo_assets() { + public function enqueue_selectwoo_assets() { if ( ! class_exists( 'GFForms' ) ) { return; @@ -76,10 +76,12 @@ function enqueue_selectwoo_assets() { wp_enqueue_script( 'gravityview_selectwoo', plugins_url( 'assets/lib/selectWoo/selectWoo.full.min.js', GRAVITYVIEW_FILE ), array(), $version ); wp_enqueue_style( 'gravityview_selectwoo', plugins_url( 'assets/lib/selectWoo/selectWoo.min.css', GRAVITYVIEW_FILE ), array(), $version ); - wp_enqueue_script( 'gravityview_entry_creator', plugins_url( 'assets/js/admin-entry-creator' . $script_debug . '.js', GRAVITYVIEW_FILE ), array( - 'jquery', - 'gravityview_selectwoo' - ), $version ); + wp_enqueue_script( + 'gravityview_entry_creator', + plugins_url( 'assets/js/admin-entry-creator' . $script_debug . '.js', GRAVITYVIEW_FILE ), + [ 'jquery', 'gravityview_selectwoo' ], + $version + ); wp_localize_script( 'gravityview_entry_creator', @@ -100,7 +102,7 @@ function enqueue_selectwoo_assets() { * * @since 2.9.1 */ - function entry_creator_get_users() { + public function entry_creator_get_users() { $post_var = wp_parse_args( wp_unslash( $_POST ), @@ -146,7 +148,7 @@ function entry_creator_get_users() { * @return void * @uses RGFormsModel::update_lead_property() Modify the entry `created_by` field */ - function assign_new_user_to_lead( $user_id, $config, $entry = array(), $password = '' ) { + public function assign_new_user_to_lead( $user_id, $config, $entry = array(), $password = '' ) { /** * Disable assigning the new user to the entry by returning false. @@ -195,7 +197,7 @@ function assign_new_user_to_lead( $user_id, $config, $entry = array(), $password * * @return void */ - function prevent_conflicts() { + public function prevent_conflicts() { // Plugin that was provided here: // @link https://www.gravitykit.com/support/documentation/201991205/ @@ -211,9 +213,17 @@ function prevent_conflicts() { * @return bool Whether the user has rights. */ private function is_user_allowed(): bool { - // Todo: only show users if the user has rights to see all users. + if ( ! GVCommon::has_cap( 'list_users' ) ) { + return false; + } + // Can the user edit entries? - if ( ! GVCommon::has_cap( array( 'gravityforms_edit_entries', 'gravityview_edit_entries' ) ) ) { + if ( ! GVCommon::has_cap( [ + 'gravityforms_edit_entries', + 'gravityview_edit_entries', + 'gravityview_edit_others_entries', + 'gravityview_edit_form_entries', + ] ) ) { return false; } @@ -224,7 +234,7 @@ private function is_user_allowed(): bool { * @since 3.6.3 * @return void */ - function load() { + public function load() { // Does GF exist? if ( ! class_exists( 'GFCommon' ) ) { @@ -251,11 +261,9 @@ function load() { } // Now, no validation is required in the methods; let's hook in. - add_action( 'admin_init', array( &$this, 'set_screen_mode' ) ); - - add_action( 'gform_entry_info', array( &$this, 'add_select' ), 10, 2 ); - - add_action( 'gform_after_update_entry', array( &$this, 'update_entry_creator' ), 10, 3 ); + add_action( 'admin_init', [ $this, 'set_screen_mode' ] ); + add_action( 'gform_entry_info', [ $this, 'add_select' ], 10, 2 ); + add_action( 'gform_after_update_entry', [ $this, 'update_entry_creator' ], 10, 3 ); } /** @@ -263,7 +271,7 @@ function load() { * * @return void */ - function set_screen_mode() { + public function set_screen_mode() { if ( 'view' === \GV\Utils::_POST( 'screen_mode' ) ) { return; @@ -278,12 +286,13 @@ function set_screen_mode() { /** * When the entry creator is changed, add a note to the entry * - * @param array $form GF entry array - * @param int $entry_id Entry ID + * @param array $form GF entry array + * @param int $entry_id Entry ID + * @param array $original_entry The entry before updating. * * @return void */ - function update_entry_creator( $form, $entry_id, array $original_entry ) { + public function update_entry_creator( $form, $entry_id, array $original_entry ) { global $current_user; @@ -387,7 +396,7 @@ public static function get_select_field( array $entry ): string { * * @return void */ - function add_select( $form_id, $entry ) { + public function add_select( $form_id, $entry ) { if ( 'edit' !== \GV\Utils::_POST( 'screen_mode' ) ) { return; @@ -408,7 +417,7 @@ function add_select( $form_id, $entry ) { * * @return array */ - function register_gform_noconflict( $assets ) { + public function register_gform_noconflict( $assets ) { $assets[] = 'gravityview_selectwoo'; $assets[] = 'gravityview_entry_creator'; diff --git a/readme.txt b/readme.txt index 5bd438f4b..55c77b453 100644 --- a/readme.txt +++ b/readme.txt @@ -23,6 +23,7 @@ Beautifully display your Gravity Forms entries. Learn more on [gravitykit.com](h = develop = +* Added: Entry creator can be changed from the Edit Entry Layout. * Fixed: Clearing search removed all URL query parameters and under some circumstances redirected to the homepage. * Fixed: Searching the View added duplicate search parameters to the URL. * Fixed: PHP 8.2 deprecation notice related to dynamic property creation. From dff1b6c22517739ab3c426428e1d04fc6ead83f8 Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Mon, 16 Sep 2024 15:36:52 +0200 Subject: [PATCH 05/11] Fix Code style problems --- ...class-gravityview-change-entry-creator.php | 128 ++++++++++-------- 1 file changed, 74 insertions(+), 54 deletions(-) diff --git a/includes/class-gravityview-change-entry-creator.php b/includes/class-gravityview-change-entry-creator.php index 9d2217771..dd662a4b4 100644 --- a/includes/class-gravityview-change-entry-creator.php +++ b/includes/class-gravityview-change-entry-creator.php @@ -4,18 +4,22 @@ * @since 1.2 */ class GravityView_Change_Entry_Creator { - - /* - * @var int Number of users to show in the select element + /** + * Number of users to show in the select element. + * + * @var int */ public const DEFAULT_NUMBER_OF_USERS = 100; + /** + * Initializes the hooks. + */ public function __construct() { /** * @since 1.5.1 */ - add_action( 'gform_user_registered', array( $this, 'assign_new_user_to_lead' ), 10, 4 ); + add_action( 'gform_user_registered', array( $this, 'assign_new_user_to_lead' ), 10, 3 ); /** * Disable the Change Entry Creator functionality. @@ -33,7 +37,7 @@ public function __construct() { add_filter( 'gravityview_field_visibility_caps', [ $this, 'created_by_visibility_caps' ], 15, 3 ); /** - * Use `init` to fix bbPress warning + * Use `init` to fix bbPress warning. * * @see https://bbpress.trac.wordpress.org/ticket/2309 */ @@ -41,7 +45,7 @@ public function __construct() { add_action( 'plugins_loaded', array( $this, 'prevent_conflicts' ) ); - // Enqueue and allow selectWoo UI assets + // Enqueue and allow selectWoo UI assets. add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_selectwoo_assets' ) ); add_filter( 'gform_noconflict_scripts', array( $this, 'register_gform_noconflict' ) ); add_filter( 'gform_noconflict_styles', array( $this, 'register_gform_noconflict' ) ); @@ -61,7 +65,7 @@ public function enqueue_selectwoo_assets() { return; } - if ( ! in_array( GFForms::get_page(), array( 'entry_detail_edit' ) ) ) { + if ( GFForms::get_page() !== 'entry_detail_edit' ) { return; } @@ -136,19 +140,18 @@ public function entry_creator_get_users() { } /** - * When an user is created using the User Registration add-on, assign the entry to them + * When a user is created using the User Registration add-on, assign the entry to them. * * @since 1.5.1 * - * @param int $user_id WordPress User ID - * @param array $config User registration feed configuration - * @param array $entry GF Entry array - * @param string $password User password + * @param int $user_id WordPress User ID. + * @param array $config User registration feed configuration. + * @param array $entry GF Entry array. * * @return void - * @uses RGFormsModel::update_lead_property() Modify the entry `created_by` field + * @uses RGFormsModel::update_lead_property() Modify the entry `created_by` field. */ - public function assign_new_user_to_lead( $user_id, $config, $entry = array(), $password = '' ) { + public function assign_new_user_to_lead( $user_id, $config, $entry = array() ) { /** * Disable assigning the new user to the entry by returning false. @@ -159,12 +162,12 @@ public function assign_new_user_to_lead( $user_id, $config, $entry = array(), $p */ $assign_to_lead = apply_filters( 'gravityview_assign_new_user_to_entry', true, $user_id, $config, $entry ); - // If filter returns false, do not process + // If filter returns false, do not process. if ( empty( $assign_to_lead ) ) { return; } - // Update the entry. The `false` prevents checking Akismet; `true` disables the user updated hook from firing + // Update the entry. The `false` prevents checking Akismet; `true` disables the user updated hook from firing. $result = RGFormsModel::update_entry_property( (int) $entry['id'], 'created_by', (int) $user_id, false, true ); if ( false === $result ) { @@ -173,7 +176,8 @@ public function assign_new_user_to_lead( $user_id, $config, $entry = array(), $p $note = sprintf( '%s: Failed to assign User ID #%d as the entry creator (Last database error: "%s")', $status, $user_id, $wpdb->last_error ); } else { $status = __( 'Success', 'gk-gravityview' ); - $note = sprintf( _x( '%1$s: Assigned User ID #%2$d as the entry creator.', 'First parameter: Success or error of the action. Second: User ID number', 'gk-gravityview' ), $status, $user_id ); + // Translators: %1$s contains either `Success` or `error`, and %2$d contains the User ID. + $note = sprintf( _x( '%1$s: Assigned User ID #%2$d as the entry creator.', 'First parameter: Success or error of the action. Second: User ID number', 'gk-gravityview' ), $status, $user_id ); } gravityview()->log->debug( 'GravityView_Change_Entry_Creator[assign_new_user_to_lead] - {note}', array( 'note' => $note ) ); @@ -198,9 +202,11 @@ public function assign_new_user_to_lead( $user_id, $config, $entry = array(), $p * @return void */ public function prevent_conflicts() { - - // Plugin that was provided here: - // @link https://www.gravitykit.com/support/documentation/201991205/ + /** + * Plugin that was provided here: + * + * @link https://www.gravitykit.com/support/documentation/201991205/ + */ remove_action( 'gform_entry_info', 'gravityview_change_entry_creator_form', 10 ); remove_action( 'gform_after_update_entry', 'gravityview_update_entry_creator', 10 ); } @@ -218,12 +224,14 @@ private function is_user_allowed(): bool { } // Can the user edit entries? - if ( ! GVCommon::has_cap( [ - 'gravityforms_edit_entries', - 'gravityview_edit_entries', - 'gravityview_edit_others_entries', - 'gravityview_edit_form_entries', - ] ) ) { + if ( ! GVCommon::has_cap( + [ + 'gravityforms_edit_entries', + 'gravityview_edit_entries', + 'gravityview_edit_others_entries', + 'gravityview_edit_form_entries', + ] + ) ) { return false; } @@ -277,17 +285,17 @@ public function set_screen_mode() { return; } - // If $_GET['screen_mode'] is set to edit, set $_POST value + // If $_GET['screen_mode'] is set to edit, set $_POST value. if ( 'edit' === \GV\Utils::_GET( 'screen_mode' ) ) { $_POST['screen_mode'] = 'edit'; } } /** - * When the entry creator is changed, add a note to the entry + * When the entry creator is changed, add a note to the entry. * - * @param array $form GF entry array - * @param int $entry_id Entry ID + * @param array $form GF entry array. + * @param int $entry_id Entry ID. * @param array $original_entry The entry before updating. * * @return void @@ -296,7 +304,7 @@ public function update_entry_creator( $form, $entry_id, array $original_entry ) global $current_user; - // Update the entry + // Update the entry. $created_by = absint( \GV\Utils::_POST( 'created_by' ) ); RGFormsModel::update_lead_property( $entry_id, 'created_by', $created_by ); @@ -304,19 +312,21 @@ public function update_entry_creator( $form, $entry_id, array $original_entry ) // If the creator has changed, let's add a note about who it used to be. $originally_created_by = rgar( $original_entry, 'created_by' ); - // If there's no owner and there didn't used to be, keep going + // If there's no owner and there didn't used to be, keep going. if ( empty( $originally_created_by ) && empty( $created_by ) ) { return; } - // If the values have changed + // If the values have changed. if ( absint( $originally_created_by ) !== absint( $created_by ) ) { $user_data = get_userdata( $current_user->ID ); + // Translators: %1$s contains the user's name, and %2$d contains the user ID. $user_format = _x( '%1$s (ID #%2$d)', 'The name and the ID of users who initiated changes to entry ownership', 'gk-gravityview' ); - $original_name = $created_by_name = esc_attr_x( 'No User', 'To show that the entry was unassigned from an actual user to no user.', 'gk-gravityview' ); + $created_by_name = esc_attr_x( 'No User', 'To show that the entry was unassigned from an actual user to no user.', 'gk-gravityview' ); + $original_name = $created_by_name; if ( ! empty( $originally_created_by ) ) { $originally_created_by_user_data = get_userdata( $originally_created_by ); @@ -334,6 +344,7 @@ public function update_entry_creator( $form, $entry_id, array $original_entry ) esc_attr_x( 'Deleted User', 'To show that the entry was created by a no longer existing user.', 'gk-gravityview' ); } + // Translators: %1$s contains the original user's name, %2$s contains the new user's name. GravityView_Entry_Notes::add_note( $entry_id, $current_user->ID, $user_data->display_name, sprintf( __( 'Changed entry creator from %1$s to %2$s', 'gk-gravityview' ), $original_name, $created_by_name ), 'note' ); } } @@ -357,7 +368,7 @@ public static function get_select_field( array $entry ): string { $output .= ''; - // Always show the entry creator, even when the user isn't included within the pagination limits + // Always show the entry creator, even when the user isn't included within the pagination limits. if ( ! empty( $entry_creator_user_id ) && ! empty( $entry_creator_user ) ) { $output .= ''; } @@ -376,10 +387,11 @@ public static function get_select_field( array $entry ): string { $users_displayed = self::DEFAULT_NUMBER_OF_USERS + ( ! empty( $entry_creator_user ) ? 1 : 0 ); if ( $user_count > $users_displayed ) { $remaining_users = $user_count - $users_displayed; - $user_users = _n( esc_html__( 'user', 'gk-gravityview' ), esc_html__( 'users', 'gk-gravityview' ), $remaining_users ); - $message = esc_html_x( 'Use the input above to search the remaining %1$d %2$s.', '%d is replaced with user count %s is replaced with "user" or "users"', 'gk-gravityview' ); - $message = sprintf( $message, $remaining_users, $user_users ); - $output .= ''; + $user_users = _n( 'user', 'users', $remaining_users, 'gk-gravityview' ); + // Translators: %1$d is the user count, %2$s is either `user` or `users` (singular vs. plural). + $message = esc_html_x( 'Use the input above to search the remaining %1$d %2$s.', '%d is replaced with user count %s is replaced with "user" or "users"', 'gk-gravityview' ); + $message = sprintf( $message, $remaining_users, $user_users ); + $output .= ''; } $output .= ''; @@ -389,10 +401,10 @@ public static function get_select_field( array $entry ): string { } /** - * Output select element used to change the entry creator + * Output select element used to change the entry creator. * - * @param int $form_id GF Form ID - * @param array $entry GF entry array + * @param int $form_id GF Form ID. + * @param array $entry GF entry array. * * @return void */ @@ -402,20 +414,20 @@ public function add_select( $form_id, $entry ) { return; } - $output = ''; $output .= self::get_select_field( $entry ); - echo wp_kses( $output ); + echo wp_kses( + $output, + [ + 'label' => [ 'for' => true ], + 'select' => [ + 'id' => true, + 'name' => true, + 'class' => true, + ], + 'option' => [ + 'value' => true, + 'selected' => true, + 'disabled' => true, + ], + ] + ); } /** From 57bdb1b01d349efcaebc27521ddee46cedcc1c49 Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Wed, 2 Oct 2024 19:49:24 +0200 Subject: [PATCH 07/11] Require GFExport --- includes/class-gravityview-change-entry-creator.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/class-gravityview-change-entry-creator.php b/includes/class-gravityview-change-entry-creator.php index 58f7348f8..9e5821fcc 100644 --- a/includes/class-gravityview-change-entry-creator.php +++ b/includes/class-gravityview-change-entry-creator.php @@ -489,6 +489,8 @@ public function register_edit_field( array $fields, array $form, string $zone ): * @return array The updated fields array. */ public function register_created_by_input( array $fields, ?array $editable_fields, array $form ): array { + require_once GFCommon::get_base_path() . '/export.php'; + // Don't add the `created_by` field if the user can't change it. $editable_field_ids = array_flip( array_map( From 4208ac467d6a4eaa761555c0e98881e8ed2361ec Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Fri, 11 Oct 2024 10:25:58 +0200 Subject: [PATCH 08/11] Show custom label for Created By field on entry edit --- includes/class-gravityview-change-entry-creator.php | 2 +- includes/extensions/edit-entry/class-edit-entry-render.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/class-gravityview-change-entry-creator.php b/includes/class-gravityview-change-entry-creator.php index 9e5821fcc..52f96560b 100644 --- a/includes/class-gravityview-change-entry-creator.php +++ b/includes/class-gravityview-change-entry-creator.php @@ -515,7 +515,7 @@ static function ( array $field ): string { return $fields; } - $fields[] = $form_fields['created_by']; + $fields[] = GravityView_Edit_Entry_Render::merge_field_properties( $form_fields['created_by'], $configuration ); // Sort fields according to Gravity View. $sort_order_lookup = array_flip( array_keys( $editable_field_ids ) ); diff --git a/includes/extensions/edit-entry/class-edit-entry-render.php b/includes/extensions/edit-entry/class-edit-entry-render.php index 8a3b9d143..a82678b69 100644 --- a/includes/extensions/edit-entry/class-edit-entry-render.php +++ b/includes/extensions/edit-entry/class-edit-entry-render.php @@ -2066,7 +2066,7 @@ private function filter_fields( $fields, $configured_fields ) { /** @var GF_Field $field */ foreach ( $fields as $field ) { if ( intval( $configured_field['id'] ) === intval( $field->id ) && $this->user_can_edit_field( $configured_field, false ) ) { - $edit_fields[] = $this->merge_field_properties( $field, $configured_field ); + $edit_fields[] = static::merge_field_properties( $field, $configured_field ); break; } } @@ -2083,7 +2083,7 @@ private function filter_fields( $fields, $configured_fields ) { * @since 1.5 * @return array|GF_Field */ - private function merge_field_properties( $field, $field_setting ) { + public static function merge_field_properties( $field, $field_setting ) { $return_field = $field; From 186722532c1d08db1bd85b8dda0e97c660ccc800 Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Fri, 11 Oct 2024 10:32:27 +0200 Subject: [PATCH 09/11] Show configured label instead of field label --- .../edit-entry/class-edit-entry-render.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/includes/extensions/edit-entry/class-edit-entry-render.php b/includes/extensions/edit-entry/class-edit-entry-render.php index a82678b69..74d2c9dc7 100644 --- a/includes/extensions/edit-entry/class-edit-entry-render.php +++ b/includes/extensions/edit-entry/class-edit-entry-render.php @@ -901,7 +901,7 @@ private function maybe_update_post_fields( $form ) { $value = $value[ $field_id ]; } - if( ! empty( $field->customFieldTemplateEnabled ) ) { + if ( ! empty( $field->customFieldTemplateEnabled ) ) { $value = $this->fill_post_template( $field->customFieldTemplate, $form, $entry_tmp, true ); } @@ -1095,7 +1095,8 @@ public function edit_entry_form() { ?>

- + + ?> +

maybe_print_message(); ?> @@ -1492,8 +1494,8 @@ public function modify_edit_field_input( $field_content = '', $field = null, $va // If the form has been submitted, then we don't need to pre-fill the values, // Except for fileupload type and when a field input is overridden- run always!! - if( - ( $this->is_edit_entry_submission() && !in_array( $field->get_input_type(), array( 'fileupload', 'post_image' ) ) ) + if ( + ( $this->is_edit_entry_submission() && ! in_array( $field->get_input_type(), array( 'fileupload', 'post_image' ) ) ) && false === ( $gv_field && is_callable( array( $gv_field, 'get_field_input' ) ) ) && ! GFCommon::is_product_field( $field->type ) || ! empty( $field_content ) @@ -2091,6 +2093,8 @@ public static function merge_field_properties( $field, $field_setting ) { $return_field->label = ''; } elseif ( ! empty( $field_setting['custom_label'] ) ) { $return_field->label = $field_setting['custom_label']; + } elseif ( ! empty( $field_setting['label'] ) ) { + $return_field->label = $field_setting['label']; } if ( ! empty( $field_setting['custom_class'] ) ) { From 01965df4bbb83feb3ff86423f985201eb8778455 Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Fri, 11 Oct 2024 11:14:53 +0200 Subject: [PATCH 10/11] Remove capbility notice on admin bar --- includes/class-gravityview-admin-bar.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/includes/class-gravityview-admin-bar.php b/includes/class-gravityview-admin-bar.php index abf826b42..85f9689dc 100644 --- a/includes/class-gravityview-admin-bar.php +++ b/includes/class-gravityview-admin-bar.php @@ -127,9 +127,12 @@ function add_edit_entry_link() { */ function add_edit_view_and_form_link() { /** @var WP_Admin_Bar $wp_admin_bar */ - global $wp_admin_bar; + global $wp_admin_bar, $post; - if ( ! GVCommon::has_cap( array( 'edit_gravityviews', 'edit_gravityview', 'gravityforms_edit_forms' ) ) ) { + if ( ! GVCommon::has_cap( + [ 'edit_gravityviews', 'edit_gravityview', 'gravityforms_edit_forms' ], + $post->ID + ) ) { return; } From 2cf75895f66119e753e275fd14381d8e4a4553fa Mon Sep 17 00:00:00 2001 From: Doeke Norg Date: Fri, 11 Oct 2024 11:18:34 +0200 Subject: [PATCH 11/11] Fix unit tests --- includes/class-gravityview-admin-bar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-gravityview-admin-bar.php b/includes/class-gravityview-admin-bar.php index 85f9689dc..d5004c5cd 100644 --- a/includes/class-gravityview-admin-bar.php +++ b/includes/class-gravityview-admin-bar.php @@ -131,7 +131,7 @@ function add_edit_view_and_form_link() { if ( ! GVCommon::has_cap( [ 'edit_gravityviews', 'edit_gravityview', 'gravityforms_edit_forms' ], - $post->ID + isset( $post ) ? $post->ID : null ) ) { return; }