From 722abdda423ea5ab0a1a9bc5e6c53a77ac70259e Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Thu, 7 May 2015 18:11:17 -0600 Subject: [PATCH 01/21] Get started --- includes/class-gravityview-roles.php | 150 +++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 includes/class-gravityview-roles.php diff --git a/includes/class-gravityview-roles.php b/includes/class-gravityview-roles.php new file mode 100644 index 0000000000..4478a1a1db --- /dev/null +++ b/includes/class-gravityview-roles.php @@ -0,0 +1,150 @@ +get_core_caps(); + foreach ( $capabilities as $cap_group ) { + foreach ( $cap_group as $cap ) { + $wp_roles->add_cap( 'administrator', $cap ); + } + } + + } + } + + /** + * Gets the core post type capabilities + * + * @access public + * @since 1.4.4 + * @return array $capabilities Core post type capabilities + */ + public function get_core_caps() { + $capabilities = array(); + + $capability_types = array( 'gravityview', 'gravityview_comment' ); + + foreach ( $capability_types as $capability_type ) { + $capabilities[ $capability_type ] = array( + // Post type + "edit_{$capability_type}", + "read_{$capability_type}", + "delete_{$capability_type}", + "edit_{$capability_type}s", + "edit_others_{$capability_type}s", + "publish_{$capability_type}s", + "read_private_{$capability_type}s", + "delete_{$capability_type}s", + "delete_private_{$capability_type}s", + "delete_published_{$capability_type}s", + "delete_others_{$capability_type}s", + "edit_private_{$capability_type}s", + "edit_published_{$capability_type}s", + + // Terms + "manage_{$capability_type}_terms", + "edit_{$capability_type}_terms", + "delete_{$capability_type}_terms", + "assign_{$capability_type}_terms", + ); + } + + return $capabilities; + } + + + /** + * Remove core post type capabilities (called on uninstall) + * + * @access public + * @since 1.5.2 + * @return void + */ + public function remove_caps() { + global $wp_roles; + + if ( class_exists( 'WP_Roles' ) ) { + if ( ! isset( $wp_roles ) ) { + $wp_roles = new WP_Roles(); + } + } + + if ( is_object( $wp_roles ) ) { + + /** Remove the Main Post Type Capabilities */ + $capabilities = $this->get_core_caps(); + + foreach ( $capabilities as $cap_group ) { + foreach ( $cap_group as $cap ) { + $wp_roles->remove_cap( 'administrator', $cap ); + } + } + + } + } +} From b570c86fac345e68b5d03acf52cf1457edf654b9 Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Sun, 6 Sep 2015 16:42:52 -0600 Subject: [PATCH 02/21] GV has no terms currently --- includes/class-gravityview-roles.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/includes/class-gravityview-roles.php b/includes/class-gravityview-roles.php index 4478a1a1db..f04d3daff9 100644 --- a/includes/class-gravityview-roles.php +++ b/includes/class-gravityview-roles.php @@ -105,12 +105,6 @@ public function get_core_caps() { "delete_others_{$capability_type}s", "edit_private_{$capability_type}s", "edit_published_{$capability_type}s", - - // Terms - "manage_{$capability_type}_terms", - "edit_{$capability_type}_terms", - "delete_{$capability_type}_terms", - "assign_{$capability_type}_terms", ); } From 20c59b22dc2a1b1d5256c5ceda3119611760ffe5 Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Sun, 6 Sep 2015 17:07:05 -0600 Subject: [PATCH 03/21] Add to main plugin file --- gravityview.php | 5 +++++ includes/class-gravityview-roles.php | 17 +++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/gravityview.php b/gravityview.php index 1949d43493..74a71f504c 100644 --- a/gravityview.php +++ b/gravityview.php @@ -71,6 +71,7 @@ require_once( GRAVITYVIEW_DIR . 'includes/class-common.php'); require_once( GRAVITYVIEW_DIR . 'includes/connector-functions.php'); require_once( GRAVITYVIEW_DIR . 'includes/class-gravityview-compatibility.php' ); +require_once( GRAVITYVIEW_DIR . 'includes/class-gravityview-roles.php' ); /** Register Post Types and Rewrite Rules */ require_once( GRAVITYVIEW_DIR . 'includes/class-post-types.php'); @@ -218,6 +219,10 @@ public static function activate( $network_wide = false ) { // Clear settings transient delete_transient( 'redux_edd_license_license_valid' ); + + $roles = GravityView_Roles::get_instance(); + $roles->add_roles(); + $roles->add_caps(); } diff --git a/includes/class-gravityview-roles.php b/includes/class-gravityview-roles.php index f04d3daff9..914b55cfab 100644 --- a/includes/class-gravityview-roles.php +++ b/includes/class-gravityview-roles.php @@ -30,6 +30,11 @@ */ class GravityView_Roles { + /** + * @var GravityView_Roles|null + */ + static $instance = null; + /** * Get things going * @@ -37,6 +42,18 @@ class GravityView_Roles { */ public function __construct() {} + /** + * @return GravityView_Roles + */ + public static function get_instance() { + + if( ! self::$instance ) { + self::$instance = new self; + } + + return self::$instance; + } + /** * Add new shop roles with default WP caps * From 1ade16987cfe6e1d687a0e24f92a14b9577c9e24 Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Sun, 6 Sep 2015 17:25:38 -0600 Subject: [PATCH 04/21] Add setting for delete on uninstall, uninstall class --- includes/class-gravityview-roles.php | 15 ++++++ includes/class-settings.php | 19 +++++++ uninstall.php | 76 +++++++++++++++++++++++++++- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/includes/class-gravityview-roles.php b/includes/class-gravityview-roles.php index 914b55cfab..048d44bf3b 100644 --- a/includes/class-gravityview-roles.php +++ b/includes/class-gravityview-roles.php @@ -64,6 +64,21 @@ public static function get_instance() { public function add_roles() { } + /** + * Remove roles + * + * @access public + * @since 1.4.4 + * @return void + */ + public function remove_roles() { + global $wp_roles; + /*$gravityview_roles = array( '' ); + foreach ( $gravityview_roles as $role ) { + remove_role( $role ); + }*/ + } + /** * Add new shop-specific capabilities * diff --git a/includes/class-settings.php b/includes/class-settings.php index 878f527741..909a1644a5 100644 --- a/includes/class-settings.php +++ b/includes/class-settings.php @@ -477,6 +477,7 @@ private function get_default_settings() { 'license_key_status' => '', 'support-email' => get_bloginfo( 'admin_email' ), 'no-conflict-mode' => '0', + 'delete-on-uninstall' => '0', ); return $defaults; @@ -570,6 +571,24 @@ public function app_settings_fields() { ), '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' ), ), + array( + 'name' => 'delete-on-uninstall', + 'type' => 'radio', + 'label' => __( 'Remove Data on Uninstall?', 'gravityview' ), + 'default_value' => $default_settings['delete-on-uninstall'], + 'horizontal' => 1, + 'choices' => array( + array( + 'label' => _x('On', 'Setting: On or off', 'gravityview'), + 'value' => '1' + ), + array( + 'label' => _x('Off', 'Setting: On or off', 'gravityview'), + 'value' => '0', + ), + ), + 'description' => __( 'Enable if you want GravityView to delete all of its data when the plugin is deleted.', 'gravityview' ), + ), ) ); diff --git a/uninstall.php b/uninstall.php index ca6e2df480..3c0ad90913 100644 --- a/uninstall.php +++ b/uninstall.php @@ -14,4 +14,78 @@ exit; } -// @TODO: Define uninstall functionality here \ No newline at end of file + +class GravityView_Uninstall { + + /** + * GravityView_Uninstall constructor. + */ + public function __construct() { + + include_once plugin_dir_path( __FILE__ ) . 'includes/class-settings.php'; + + include_once plugin_dir_path( __FILE__ ) . 'includes/class-gravityview-roles.php'; + + $delete = GravityView_Settings::get_instance()->get_app_setting('delete-on-uninstall'); + + if( empty( $delete ) ) { + var_dump('DO NOT DELETE'); + } else { + var_dump('DELETE!'); + } + + die(); // Take out later, of course + + $this->init(); + } + + private function init() { + $this->delete_options(); + $this->delete_posts(); + $this->delete_capabilities(); + $this->delete_roles(); + $this->delete_capabilities(); + $this->delete_entry_meta(); + } + + /** + * Delete all GravityView-generated entry meta + * @todo + */ + private function delete_entry_meta() { + } + + private function delete_roles() { + GravityView_Roles::get_instance()->remove_roles(); + } + + private function delete_capabilities() { + GravityView_Roles::get_instance()->remove_caps(); + } + + /** + * Delete all the GravityView custom post type objects + */ + private function delete_posts() { + $items = get_posts( array( + 'post_type' => 'gravityview', + 'post_status' => 'any', + 'numberposts' => -1, + 'fields' => 'ids' + ) ); + + if ( $items ) { + foreach ( $items as $item ) { + wp_delete_post( $item, true ); + } + } + } + + private function delete_options() { + delete_option( 'gravityformsaddon_gravityview_version' ); + delete_option( 'gravityview_cache_blacklist' ); + delete_option( 'gravityformsaddon_gravityview_app_settings' ); + } +} + +new GravityView_Uninstall; \ No newline at end of file From 975f0b2589ad5be801f5a1a0e4e4b2cb1c1c8ebe Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Mon, 7 Sep 2015 11:27:20 -0600 Subject: [PATCH 05/21] Complete the uninstall functionality --- includes/class-settings.php | 13 +++-- uninstall.php | 102 ++++++++++++++++++++++++++++-------- 2 files changed, 89 insertions(+), 26 deletions(-) diff --git a/includes/class-settings.php b/includes/class-settings.php index 909a1644a5..afd1365610 100644 --- a/includes/class-settings.php +++ b/includes/class-settings.php @@ -569,7 +569,7 @@ public function app_settings_fields() { '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' ), + '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.'), ), array( 'name' => 'delete-on-uninstall', @@ -579,19 +579,22 @@ public function app_settings_fields() { 'horizontal' => 1, 'choices' => array( array( - 'label' => _x('On', 'Setting: On or off', 'gravityview'), - 'value' => '1' + '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.') ), ), array( - 'label' => _x('Off', 'Setting: On or off', 'gravityview'), + '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.') ), ), ), - 'description' => __( 'Enable if you want GravityView to delete all of its data when the plugin is deleted.', 'gravityview' ), + 'description' => sprintf( __( 'Should GravityView content be removed from the site when the GravityView plugin is deleted?', 'gravityview' ), __('Permanently Delete', 'gravityview') ), ), ) ); + /** * Redux backward compatibility * @since 1.7.4 diff --git a/uninstall.php b/uninstall.php index 3c0ad90913..a21fce8d0f 100644 --- a/uninstall.php +++ b/uninstall.php @@ -6,7 +6,7 @@ * @author Zack Katz * @license ToBeDefined * @link http://gravityview.co - * @copyright Copyright 2013, Katz Web Services, Inc. + * @copyright Copyright 2015, Katz Web Services, Inc. */ // If uninstall not called from WordPress, then exit @@ -14,59 +14,110 @@ exit; } - +/** + * Delete GravityView content when GravityView is uninstalled, if the setting is set to "Delete on Uninstall" + * @since 1.14 + */ class GravityView_Uninstall { - /** - * GravityView_Uninstall constructor. - */ public function __construct() { - include_once plugin_dir_path( __FILE__ ) . 'includes/class-settings.php'; + /** @define "$file_path" "./" */ + $file_path = plugin_dir_path( __FILE__ ); - include_once plugin_dir_path( __FILE__ ) . 'includes/class-gravityview-roles.php'; + include_once $file_path . 'includes/class-settings.php'; + include_once $file_path . 'includes/class-gravityview-roles.php'; + /** + * Only delete content and settings if "Delete on Uninstall?" setting is "Permanently Delete" + * @var string|null $delete NULL if not configured (previous versions); "0" if false, "delete" if delete + */ $delete = GravityView_Settings::get_instance()->get_app_setting('delete-on-uninstall'); - if( empty( $delete ) ) { - var_dump('DO NOT DELETE'); - } else { - var_dump('DELETE!'); + if( 'delete' === $delete ) { + $this->fire_everything(); } - - die(); // Take out later, of course - - $this->init(); } - private function init() { + /** + * Delete GravityView Views, settings, roles, caps, etc. + * @see https://youtu.be/FXy_DO6IZOA?t=35s + * @since 1.14 + */ + private function fire_everything() { $this->delete_options(); $this->delete_posts(); - $this->delete_capabilities(); $this->delete_roles(); $this->delete_capabilities(); $this->delete_entry_meta(); + $this->delete_entry_notes(); } /** - * Delete all GravityView-generated entry meta - * @todo + * Delete GravityView "approved entry" meta + * @since 1.14 */ private function delete_entry_meta() { + global $wpdb; + + $meta_table = class_exists( 'GFFormsModel' ) ? GFFormsModel::get_lead_meta_table_name() : $wpdb->prefix . 'rg_lead_meta'; + + $sql = " + DELETE FROM $meta_table + WHERE ( + `meta_key` = 'is_approved' + ); + "; + + $wpdb->query( $sql ); + } + + /** + * Delete all GravityView-generated entry notes + * @since 1.14 + */ + private function delete_entry_notes() { + global $wpdb; + + $notes_table = class_exists( 'GFFormsModel' ) ? GFFormsModel::get_lead_notes_table_name() : $wpdb->prefix . 'rg_lead_notes'; + + $disapproved = __('Disapproved the Entry for GravityView', 'gravityview'); + $approved = __('Approved the Entry for GravityView', 'gravityview'); + + $sql = $wpdb->prepare( " + DELETE FROM $notes_table + WHERE ( + `note_type` = 'gravityview' OR + `value` = %s OR + `value` = %s + ); + ", $approved, $disapproved ); + + $wpdb->query( $sql ); } + /** + * Delete roles added by GravityView + * @since 1.14 + */ private function delete_roles() { GravityView_Roles::get_instance()->remove_roles(); } + /** + * Delete capabilities added by GravityView + * @since 1.14 + */ private function delete_capabilities() { GravityView_Roles::get_instance()->remove_caps(); } /** - * Delete all the GravityView custom post type objects + * Delete all the GravityView custom post type posts + * @since 1.14 */ private function delete_posts() { + $items = get_posts( array( 'post_type' => 'gravityview', 'post_status' => 'any', @@ -81,10 +132,19 @@ private function delete_posts() { } } + /** + * Delete GravityView options + * @since 1.14 + */ private function delete_options() { + + delete_option( 'gravityformsaddon_gravityview_app_settings' ); delete_option( 'gravityformsaddon_gravityview_version' ); delete_option( 'gravityview_cache_blacklist' ); - delete_option( 'gravityformsaddon_gravityview_app_settings' ); + + delete_transient( 'gravityview_edd-activate_valid' ); + delete_transient( 'gravityview_edd-deactivate_valid' ); + delete_transient( 'gravityview_dismissed_notices' ); } } From 34fb1b86035cee29b00af8ef911db57cd889ebaa Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Mon, 7 Sep 2015 17:01:53 -0600 Subject: [PATCH 06/21] Complete mapping caps to core roles Also, remove custom roles for now. --- gravityview.php | 4 +- includes/class-gravityview-roles.php | 223 +++++++++++++++++---------- includes/class-post-types.php | 1 + uninstall.php | 8 - 4 files changed, 140 insertions(+), 96 deletions(-) diff --git a/gravityview.php b/gravityview.php index 74a71f504c..3aa84b8c07 100644 --- a/gravityview.php +++ b/gravityview.php @@ -220,9 +220,7 @@ public static function activate( $network_wide = false ) { // Clear settings transient delete_transient( 'redux_edd_license_license_valid' ); - $roles = GravityView_Roles::get_instance(); - $roles->add_roles(); - $roles->add_caps(); + GravityView_Roles::get_instance()->add_caps(); } diff --git a/includes/class-gravityview-roles.php b/includes/class-gravityview-roles.php index 048d44bf3b..6e3c624ea9 100644 --- a/includes/class-gravityview-roles.php +++ b/includes/class-gravityview-roles.php @@ -2,10 +2,6 @@ /** * Roles and Capabilities * - * TODO: https://github.com/easydigitaldownloads/Easy-Digital-Downloads/blob/master/uninstall.php#L67-L73 - * TODO: https://github.com/easydigitaldownloads/Easy-Digital-Downloads/blob/master/includes/install.php#L135-L138 - * TODO: https://github.com/easydigitaldownloads/Easy-Digital-Downloads/blob/master/includes/install.php#L205-L231 - * * @see https://github.com/easydigitaldownloads/Easy-Digital-Downloads/blob/master/includes/class-edd-roles.php Easy Digital Downloads FTW * @package GravityView * @license GPL2+ @@ -23,10 +19,7 @@ * * This class handles the role creation and assignment of capabilities for those roles. * - * These roles let us have Shop Accountants, Shop Workers, etc, each of whom can do - * certain things within the EDD store - * - * @since 1.4.4 + * @since 1.14 */ class GravityView_Roles { @@ -36,13 +29,7 @@ class GravityView_Roles { static $instance = null; /** - * Get things going - * - * @since 1.4.4 - */ - public function __construct() {} - - /** + * @since 1.14 * @return GravityView_Roles */ public static function get_instance() { @@ -55,122 +42,188 @@ public static function get_instance() { } /** - * Add new shop roles with default WP caps + * Get things going * - * @access public - * @since 1.4.4 - * @return void + * @since 1.14 + */ + public function __construct() { + $this->add_hooks(); + } + + /** + * Call hooks + * @since 1.14 */ - public function add_roles() { + private function add_hooks() { + add_filter( 'members_get_capabilities', array( $this, 'members_get_capabilities' ) ); } /** - * Remove roles + * Add GravityView capabilities to the Members plugin * - * @access public - * @since 1.4.4 - * @return void + * @since 1.14 + * @param array $caps Existing capabilities registered with Members + * @return array Modified capabilities array */ - public function remove_roles() { + public function members_get_capabilities( $caps ) { + return array_merge( $caps, $this->all_caps('all') ); + } + + /** + * Retrieves the global WP_Roles instance and instantiates it if necessary. + * + * @see wp_roles() This method uses the exact same code as wp_roles(), here for backward compatibility + * + * @global WP_Roles $wp_roles WP_Roles global instance. + * + * @return WP_Roles WP_Roles global instance if not already instantiated. + */ + function wp_roles() { global $wp_roles; - /*$gravityview_roles = array( '' ); - foreach ( $gravityview_roles as $role ) { - remove_role( $role ); - }*/ + + if ( ! isset( $wp_roles ) ) { + $wp_roles = new WP_Roles(); + } + return $wp_roles; } /** - * Add new shop-specific capabilities + * Add capabilities to their respective roles * - * @access public - * @since 1.4.4 - * @global WP_Roles $wp_roles + * @since 1.14 * @return void */ public function add_caps() { - global $wp_roles; - if ( class_exists('WP_Roles') ) { - if ( ! isset( $wp_roles ) ) { - $wp_roles = new WP_Roles(); - } - } + $wp_roles = $this->wp_roles(); if ( is_object( $wp_roles ) ) { - // Add the main post type capabilities - $capabilities = $this->get_core_caps(); - foreach ( $capabilities as $cap_group ) { - foreach ( $cap_group as $cap ) { - $wp_roles->add_cap( 'administrator', $cap ); + foreach( $wp_roles->get_names() as $role_slug => $role_label ) { + + $capabilities = $this->all_caps( $role_slug ); + + foreach( $capabilities as $cap ) { + $wp_roles->add_cap( $role_slug, $cap ); } } - } } /** - * Gets the core post type capabilities + * Get an array of GravityView capabilities + * + * @see get_post_type_capabilities() * - * @access public - * @since 1.4.4 - * @return array $capabilities Core post type capabilities + * @since 1.14 + * + * @param string $role If set, get the caps for a specific role. Pass 'all' to get all caps in a flat array. Default: '' + * + * @return array If $role is set, flat array of caps. Otherwise, a multi-dimensional array of roles and their caps with the following keys: 'administrator', 'editor', 'author', 'contributor', 'subscriber' */ - public function get_core_caps() { + public function all_caps( $role = '' ) { + + $administrator = array( + // Settings + 'gravityview_view_settings', + 'gravityview_edit_settings', + ); + + // Edit, publish, delete own and others' stuff + $editor = array( + 'edit_others_gravityviews', + 'read_private_gravityviews', + 'delete_private_gravityviews', + 'delete_others_gravityviews', + 'edit_private_gravityviews', + 'publish_gravityviews', + 'delete_published_gravityviews', + 'edit_published_gravityviews', + + // GF caps + 'gravityview_edit_others_entries', + + // GF caps + 'gravityview_view_others_entry_notes', + 'gravityview_moderate_entries', + 'gravityview_delete_others_entries', + ); + + // Edit, publish and delete own stuff + $author = array( + + // GF caps + 'gravityview_edit_entries', + 'gravityview_view_entry_notes', + 'gravityview_delete_entries', + + ); + + // Edit and delete drafts but not publish + $contributor = array( + 'edit_gravityview', + 'edit_gravityviews', + 'delete_gravityview', + 'delete_gravityviews', + ); + + // Read only + $subscriber = array( + 'read_gravityview', + ); + $capabilities = array(); - $capability_types = array( 'gravityview', 'gravityview_comment' ); - - foreach ( $capability_types as $capability_type ) { - $capabilities[ $capability_type ] = array( - // Post type - "edit_{$capability_type}", - "read_{$capability_type}", - "delete_{$capability_type}", - "edit_{$capability_type}s", - "edit_others_{$capability_type}s", - "publish_{$capability_type}s", - "read_private_{$capability_type}s", - "delete_{$capability_type}s", - "delete_private_{$capability_type}s", - "delete_published_{$capability_type}s", - "delete_others_{$capability_type}s", - "edit_private_{$capability_type}s", - "edit_published_{$capability_type}s", - ); + switch( $role ) { + case 'subscriber': + $capabilities = $subscriber; + break; + case 'contributor': + $capabilities = array_merge( $contributor, $subscriber ); + break; + case 'author': + $capabilities = array_merge( $author, $contributor, $subscriber ); + break; + case 'editor': + $capabilities = array_merge( $editor, $author, $contributor, $subscriber ); + break; + case 'administrator': + case 'all': + $capabilities = array_merge( $administrator, $editor, $author, $contributor, $subscriber ); + break; + } + + // If role is set, return empty array if not exists + if( $role ) { + return isset( $capabilities[ $role ] ) ? $capabilities[ $role ] : array(); } - return $capabilities; + // By default, return multi-dimensional array of all caps + return compact( 'administrator', 'editor', 'author', 'contributor', 'subscriber' ); } /** - * Remove core post type capabilities (called on uninstall) + * Remove all GravityView caps from all roles * - * @access public - * @since 1.5.2 + * @since 1.14 * @return void */ public function remove_caps() { - global $wp_roles; - if ( class_exists( 'WP_Roles' ) ) { - if ( ! isset( $wp_roles ) ) { - $wp_roles = new WP_Roles(); - } - } + $wp_roles = $this->wp_roles(); if ( is_object( $wp_roles ) ) { - /** Remove the Main Post Type Capabilities */ - $capabilities = $this->get_core_caps(); + /** Remove all GravityView caps from all roles */ + $capabilities = $this->all_caps('all'); - foreach ( $capabilities as $cap_group ) { - foreach ( $cap_group as $cap ) { - $wp_roles->remove_cap( 'administrator', $cap ); + // Loop through each role and remove GV caps + foreach( $wp_roles->get_names() as $role_slug => $role_name ) { + foreach ( $capabilities as $cap ) { + $wp_roles->remove_cap( $role_slug, $cap ); } } - } } } diff --git a/includes/class-post-types.php b/includes/class-post-types.php index 7d3b073a3b..0a06f9e92b 100644 --- a/includes/class-post-types.php +++ b/includes/class-post-types.php @@ -94,6 +94,7 @@ public static function init_post_types() { 'slug' => apply_filters( 'gravityview_slug', 'view' ) ), 'capability_type' => 'page', + 'map_meta_cap' => true, ); register_post_type( 'gravityview', $args ); diff --git a/uninstall.php b/uninstall.php index a21fce8d0f..bef7f83485 100644 --- a/uninstall.php +++ b/uninstall.php @@ -96,14 +96,6 @@ private function delete_entry_notes() { $wpdb->query( $sql ); } - /** - * Delete roles added by GravityView - * @since 1.14 - */ - private function delete_roles() { - GravityView_Roles::get_instance()->remove_roles(); - } - /** * Delete capabilities added by GravityView * @since 1.14 From 4bbf4f0e1246ee5b26050197588e9360649b7852 Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Mon, 7 Sep 2015 17:08:07 -0600 Subject: [PATCH 07/21] Rename class to GravityView_Roles_Capabilities() --- gravityview.php | 4 ++-- ...s.php => class-gravityview-roles-capabilities.php} | 11 +++++------ uninstall.php | 2 +- 3 files changed, 8 insertions(+), 9 deletions(-) rename includes/{class-gravityview-roles.php => class-gravityview-roles-capabilities.php} (94%) diff --git a/gravityview.php b/gravityview.php index 3aa84b8c07..7658102abd 100644 --- a/gravityview.php +++ b/gravityview.php @@ -71,7 +71,7 @@ require_once( GRAVITYVIEW_DIR . 'includes/class-common.php'); require_once( GRAVITYVIEW_DIR . 'includes/connector-functions.php'); require_once( GRAVITYVIEW_DIR . 'includes/class-gravityview-compatibility.php' ); -require_once( GRAVITYVIEW_DIR . 'includes/class-gravityview-roles.php' ); +require_once( GRAVITYVIEW_DIR . 'includes/class-gravityview-roles-capabilities.php' ); /** Register Post Types and Rewrite Rules */ require_once( GRAVITYVIEW_DIR . 'includes/class-post-types.php'); @@ -220,7 +220,7 @@ public static function activate( $network_wide = false ) { // Clear settings transient delete_transient( 'redux_edd_license_license_valid' ); - GravityView_Roles::get_instance()->add_caps(); + GravityView_Roles_Capabilities::get_instance()->add_caps(); } diff --git a/includes/class-gravityview-roles.php b/includes/class-gravityview-roles-capabilities.php similarity index 94% rename from includes/class-gravityview-roles.php rename to includes/class-gravityview-roles-capabilities.php index 6e3c624ea9..bdc59a2a84 100644 --- a/includes/class-gravityview-roles.php +++ b/includes/class-gravityview-roles-capabilities.php @@ -2,10 +2,9 @@ /** * Roles and Capabilities * - * @see https://github.com/easydigitaldownloads/Easy-Digital-Downloads/blob/master/includes/class-edd-roles.php Easy Digital Downloads FTW * @package GravityView * @license GPL2+ - * @since // TODO + * @since 1.14 * @author Katz Web Services, Inc. * @link http://gravityview.co * @copyright Copyright 2015, Katz Web Services, Inc. @@ -21,16 +20,16 @@ * * @since 1.14 */ -class GravityView_Roles { +class GravityView_Roles_Capabilities { /** - * @var GravityView_Roles|null + * @var GravityView_Roles_Capabilities|null */ static $instance = null; /** * @since 1.14 - * @return GravityView_Roles + * @return GravityView_Roles_Capabilities */ public static function get_instance() { @@ -51,7 +50,7 @@ public function __construct() { } /** - * Call hooks + * Add Members plugin hook * @since 1.14 */ private function add_hooks() { diff --git a/uninstall.php b/uninstall.php index bef7f83485..32d65b728d 100644 --- a/uninstall.php +++ b/uninstall.php @@ -101,7 +101,7 @@ private function delete_entry_notes() { * @since 1.14 */ private function delete_capabilities() { - GravityView_Roles::get_instance()->remove_caps(); + GravityView_Roles_Capabilities::get_instance()->remove_caps(); } /** From acf8dc137edf556f32f3f9eb50dd150da41dff01 Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 8 Sep 2015 12:35:12 -0600 Subject: [PATCH 08/21] Remove undefined method --- uninstall.php | 1 - 1 file changed, 1 deletion(-) diff --git a/uninstall.php b/uninstall.php index 32d65b728d..bf21391aa6 100644 --- a/uninstall.php +++ b/uninstall.php @@ -47,7 +47,6 @@ public function __construct() { private function fire_everything() { $this->delete_options(); $this->delete_posts(); - $this->delete_roles(); $this->delete_capabilities(); $this->delete_entry_meta(); $this->delete_entry_notes(); From f29716d183ed2b8fa3800fe7b0719180940cfa5d Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 8 Sep 2015 12:39:26 -0600 Subject: [PATCH 09/21] Move tests to new helper-functions file And rename the API test to match expected class and file names --- includes/class-api.php | 119 --------- includes/helper-functions.php | 120 +++++++++ tests/unit-tests/GravityView_API_Test.php | 297 +++++++++++++++++++++ tests/unit-tests/helper-functions_Test.php | 248 +++++++++++++++++ 4 files changed, 665 insertions(+), 119 deletions(-) create mode 100644 tests/unit-tests/GravityView_API_Test.php create mode 100644 tests/unit-tests/helper-functions_Test.php diff --git a/includes/class-api.php b/includes/class-api.php index 72ba5c0572..7fa3e9029c 100644 --- a/includes/class-api.php +++ b/includes/class-api.php @@ -874,125 +874,6 @@ function gravityview_get_the_term_list( $post_id, $link = true, $taxonomy = 'pos } -/** - * Do a _very_ basic match for second-level TLD domains, like `.co.uk` - * - * Ideally, we'd use https://github.com/jeremykendall/php-domain-parser to check for this, but it's too much work for such a basic functionality. Maybe if it's needed more in the future. So instead, we use [Basic matching regex](http://stackoverflow.com/a/12372310). - * @param string $domain Domain to check if it's a TLD or subdomain - * @return string Extracted domain if it has a subdomain - */ -function _gravityview_strip_subdomain( $string_maybe_has_subdomain ) { - - if( preg_match("/(?P[a-z0-9][a-z0-9\-]{1,63}\.(?:com\.|co\.|net\.|org\.|firm\.|me\.|school\.|law\.|gov\.|mod\.|msk\.|irkutsks\.|sa\.|act\.|police\.|plc\.|ac\.|tm\.|asso\.|biz\.|pro\.|cg\.|telememo\.)?[a-z\.]{2,6})$/i", $string_maybe_has_subdomain, $matches ) ) { - return $matches['domain']; - } else { - return $string_maybe_has_subdomain; - } -} - - -/** - * Convert a whole link into a shorter link for display - * - * @since 1.1 - * - * @param string $value Existing URL - * @return string If parse_url doesn't find a 'host', returns original value. Otherwise, returns formatted link. - */ -function gravityview_format_link( $value = null ) { - - - $parts = parse_url( $value ); - - // No domain? Strange...show the original text. - if( empty( $parts['host'] ) ) { - return $value; - } - - // Start with empty value for the return URL - $return = ''; - - /** - * @filter `gravityview_anchor_text_striphttp` Strip scheme from the displayed URL? - * @since 1.5.1 - * @param boolean $enable Whether to strip the scheme. Return false to show scheme. (default: true)\n - * If true: `http://example.com => example.com` - */ - if( false === apply_filters('gravityview_anchor_text_striphttp', true) ) { - - if( isset( $parts['scheme'] ) ) { - $return .= $parts['scheme']; - } - - } - - // The domain, which may contain a subdomain - $domain = $parts['host']; - - /** - * @filter `gravityview_anchor_text_stripwww` Strip www from the domain? - * @since 1.5.1 - * @param boolean $enable Whether to strip www. Return false to show www. (default: true)\n - * If true: `www.example.com => example.com` - */ - $strip_www = apply_filters('gravityview_anchor_text_stripwww', true ); - - if( $strip_www ) { - $domain = str_replace('www.', '', $domain ); - } - - /** - * @filter `gravityview_anchor_text_nosubdomain` Strip subdomains from the domain? - * @since 1.5.1 - * @param boolean $enable Whether to strip subdomains. Return false to show subdomains. (default: true)\n - * If true: `http://demo.example.com => example.com` \n - * If false: `http://demo.example.com => demo.example.com` - */ - $strip_subdomains = apply_filters('gravityview_anchor_text_nosubdomain', true); - - if( $strip_subdomains ) { - - $domain = _gravityview_strip_subdomain( $parts['host'] ); - - } - - // Add the domain - $return .= $domain; - - /** - * @filter `gravityview_anchor_text_rootonly` Display link path going only to the base directory, not a sub-directory or file? - * @since 1.5.1 - * @param boolean $enable Whether to enable "root only". Return false to show full path. (default: true)\n - * If true: `http://example.com/sub/directory/page.html => example.com` \n - * If false: `http://example.com/sub/directory/page.html => example.com/sub/directory/page.html` - */ - $root_only = apply_filters('gravityview_anchor_text_rootonly', true); - - if( empty( $root_only ) ) { - - if( isset( $parts['path'] ) ) { - $return .= $parts['path']; - } - } - - /** - * @filter `gravityview_anchor_text_noquerystring` Strip the query string from the end of the URL? - * @since 1.5.1 - * @param boolean $enable Whether to enable "root only". Return false to show full path. (default: true)\n - * If true: `http://example.com/?query=example => example.com` - */ - $strip_query_string = apply_filters('gravityview_anchor_text_noquerystring', true ); - - if( empty( $strip_query_string ) ) { - - if( isset( $parts['query'] ) ) { - $return .= '?'.$parts['query']; - } - - } - - return $return; -} /** * Get all views processed so far for the current page load diff --git a/includes/helper-functions.php b/includes/helper-functions.php index b8de95fa47..ff6e95ccea 100644 --- a/includes/helper-functions.php +++ b/includes/helper-functions.php @@ -152,4 +152,124 @@ function gravityview_number_format( $number, $decimals = '' ) { $number = number_format_i18n( $number, (int)$decimals ); return $number; +} + + +/** + * Convert a whole link into a shorter link for display + * + * @since 1.1 + * + * @param string $value Existing URL + * @return string If parse_url doesn't find a 'host', returns original value. Otherwise, returns formatted link. + */ +function gravityview_format_link( $value = null ) { + + + $parts = parse_url( $value ); + + // No domain? Strange...show the original text. + if( empty( $parts['host'] ) ) { + return $value; + } + + // Start with empty value for the return URL + $return = ''; + + /** + * @filter `gravityview_anchor_text_striphttp` Strip scheme from the displayed URL? + * @since 1.5.1 + * @param boolean $enable Whether to strip the scheme. Return false to show scheme. (default: true)\n + * If true: `http://example.com => example.com` + */ + if( false === apply_filters('gravityview_anchor_text_striphttp', true) ) { + + if( isset( $parts['scheme'] ) ) { + $return .= $parts['scheme']; + } + + } + + // The domain, which may contain a subdomain + $domain = $parts['host']; + + /** + * @filter `gravityview_anchor_text_stripwww` Strip www from the domain? + * @since 1.5.1 + * @param boolean $enable Whether to strip www. Return false to show www. (default: true)\n + * If true: `www.example.com => example.com` + */ + $strip_www = apply_filters('gravityview_anchor_text_stripwww', true ); + + if( $strip_www ) { + $domain = str_replace('www.', '', $domain ); + } + + /** + * @filter `gravityview_anchor_text_nosubdomain` Strip subdomains from the domain? + * @since 1.5.1 + * @param boolean $enable Whether to strip subdomains. Return false to show subdomains. (default: true)\n + * If true: `http://demo.example.com => example.com` \n + * If false: `http://demo.example.com => demo.example.com` + */ + $strip_subdomains = apply_filters('gravityview_anchor_text_nosubdomain', true); + + if( $strip_subdomains ) { + + $domain = _gravityview_strip_subdomain( $parts['host'] ); + + } + + // Add the domain + $return .= $domain; + + /** + * @filter `gravityview_anchor_text_rootonly` Display link path going only to the base directory, not a sub-directory or file? + * @since 1.5.1 + * @param boolean $enable Whether to enable "root only". Return false to show full path. (default: true)\n + * If true: `http://example.com/sub/directory/page.html => example.com` \n + * If false: `http://example.com/sub/directory/page.html => example.com/sub/directory/page.html` + */ + $root_only = apply_filters('gravityview_anchor_text_rootonly', true); + + if( empty( $root_only ) ) { + + if( isset( $parts['path'] ) ) { + $return .= $parts['path']; + } + } + + /** + * @filter `gravityview_anchor_text_noquerystring` Strip the query string from the end of the URL? + * @since 1.5.1 + * @param boolean $enable Whether to enable "root only". Return false to show full path. (default: true)\n + * If true: `http://example.com/?query=example => example.com` + */ + $strip_query_string = apply_filters('gravityview_anchor_text_noquerystring', true ); + + if( empty( $strip_query_string ) ) { + + if( isset( $parts['query'] ) ) { + $return .= '?'.$parts['query']; + } + + } + + return $return; +} + +/** + * Do a _very_ basic match for second-level TLD domains, like `.co.uk` + * + * Ideally, we'd use https://github.com/jeremykendall/php-domain-parser to check for this, but it's too much work for such a basic functionality. Maybe if it's needed more in the future. So instead, we use [Basic matching regex](http://stackoverflow.com/a/12372310). + * @param string $domain Domain to check if it's a TLD or subdomain + * @return string Extracted domain if it has a subdomain + */ +function _gravityview_strip_subdomain( $string_maybe_has_subdomain ) { + + if( preg_match("/(?P[a-z0-9][a-z0-9\-]{1,63}\.(?:com\.|co\.|net\.|org\.|firm\.|me\.|school\.|law\.|gov\.|mod\.|msk\.|irkutsks\.|sa\.|act\.|police\.|plc\.|ac\.|tm\.|asso\.|biz\.|pro\.|cg\.|telememo\.)?[a-z\.]{2,6})$/i", $string_maybe_has_subdomain, $matches ) ) { + return $matches['domain']; + } else { + return $string_maybe_has_subdomain; + } } \ No newline at end of file diff --git a/tests/unit-tests/GravityView_API_Test.php b/tests/unit-tests/GravityView_API_Test.php new file mode 100644 index 0000000000..c55644b838 --- /dev/null +++ b/tests/unit-tests/GravityView_API_Test.php @@ -0,0 +1,297 @@ +form = GV_Unit_Tests_Bootstrap::instance()->get_form(); + $this->form_id = GV_Unit_Tests_Bootstrap::instance()->get_form_id(); + + $this->entry = GV_Unit_Tests_Bootstrap::instance()->get_entry(); + $this->entry_id = GV_Unit_Tests_Bootstrap::instance()->get_entry_id(); + + } + + /** + * @covers GravityView_API::replace_variables() + * @covers GravityView_Merge_Tags::replace_variables() + */ + public function test_replace_variables() { + + $entry = GV_Unit_Tests_Bootstrap::instance()->get_entry(); + + $form = GV_Unit_Tests_Bootstrap::instance()->get_form(); + + // No match + $this->assertEquals( 'no bracket', GravityView_API::replace_variables( 'no bracket', $form, $entry ) ); + + // Include bracket with nomatch + $this->assertEquals( $entry['id'] . ' {nomatch}', GravityView_API::replace_variables( '{entry_id} {nomatch}', $form, $entry ) ); + + // Match tag, empty value + $this->assertEquals( '', GravityView_API::replace_variables( '{user:example}', $form, $entry ) ); + + // Open matching tag + $this->assertEquals( '{entry_id', GravityView_API::replace_variables( '{entry_id', $form, $entry ) ); + + // Form ID + $this->assertEquals( $form['id'], GravityView_API::replace_variables( '{form_id}', $form, $entry ) ); + + // Form title + $this->assertEquals( 'Example '.$form['title'], GravityView_API::replace_variables( 'Example {form_title}', $form, $entry ) ); + + $this->assertEquals( $entry['post_id'], GravityView_API::replace_variables( '{post_id}', $form, $entry ) ); + + $this->assertEquals( date( 'm/d/Y' ), GravityView_API::replace_variables( '{date_mdy}', $form, $entry ) ); + + $this->assertEquals( get_option( 'admin_email' ), GravityView_API::replace_variables( '{admin_email}', $form, $entry ) ); + + $user = wp_set_current_user( $entry['created_by'] ); + + // Test new Roles merge tag + $this->assertEquals( implode( ', ', $user->roles ), GravityView_API::replace_variables( '{created_by:roles}', $form, $entry ) ); + + $user->add_role( 'editor' ); + + // Test new Roles merge tag again, with another role. + $this->assertEquals( implode( ', ', $user->roles ), GravityView_API::replace_variables( '{created_by:roles}', $form, $entry ) ); + + $var_content = '

I expect Entry #{entry_id} will be in Form #{form_id}

'; + $expected_content = '

I expect Entry #'.$entry['id'].' will be in Form #'.$form['id'].'

'; + $this->assertEquals( $expected_content, GravityView_API::replace_variables( $var_content, $form, $entry ) ); + + } + + /** + * @covers GravityView_API::field_class() + */ + public function test_field_class() { + + $entry = $this->entry; + + $form = $this->form; + + $field_id = 2; + + $field = GFFormsModel::get_field( $form, $field_id); + + $this->assertEquals( 'gv-field-'.$form['id'].'-'.$field_id, GravityView_API::field_class( $field, $form, $entry ) ); + + $field['custom_class'] = 'custom-class-{entry_id}'; + + // Test the replace_variables functionality + $this->assertEquals( 'custom-class-'.$entry['id'].' gv-field-'.$form['id'].'-'.$field_id, GravityView_API::field_class( $field, $form, $entry ) ); + + $field['custom_class'] = 'testing,!@@($)*$ 12383'; + + // Test the replace_variables functionality + $this->assertEquals( 'testing 12383 gv-field-'.$form['id'].'-'.$field_id, GravityView_API::field_class( $field, $form, $entry ) ); + + } + + /** + * @uses GravityView_API_Test::_override_no_entries_text_output() + * @covers GravityView_API::no_results() + */ + public function test_no_results() { + + global $gravityview_view; + + $gravityview_view = GravityView_View::getInstance(); + + $gravityview_view->curr_start = false; + $gravityview_view->curr_end = false; + $gravityview_view->curr_search = false; + + // Not in search by default + $this->assertEquals( 'No entries match your request.', GravityView_API::no_results( false ) ); + $this->assertEquals( '

No entries match your request.

'."\n", GravityView_API::no_results( true ) ); + // Pretend we're in search + $gravityview_view->curr_search = true; + + $this->assertEquals( 'This search returned no results.', GravityView_API::no_results( false ) ); + $this->assertEquals( '

This search returned no results.

'."\n", GravityView_API::no_results( true ) ); + + + // Add the filter that modifies output + add_filter( 'gravitview_no_entries_text', array( $this, '_override_no_entries_text_output' ), 10, 2 ); + + // Test to make sure the $is_search parameter is passed correctly + $this->assertEquals( 'SEARCH override the no entries text output', GravityView_API::no_results( false ) ); + + $gravityview_view->curr_search = false; + + // Test to make sure the $is_search parameter is passed correctly + $this->assertEquals( 'NO SEARCH override the no entries text output', GravityView_API::no_results( false ) ); + + // Remove the filter for later + remove_filter( 'gravitview_no_entries_text', array( $this, '_override_no_entries_text_output' ) ); + + } + + public function _override_no_entries_text_output( $previous, $is_search = false ) { + + if ( $is_search ) { + return 'SEARCH override the no entries text output'; + } else { + return 'NO SEARCH override the no entries text output'; + } + + } + + public function _get_new_view_id() { + + $view_array = array( + 'post_content' => '', + 'post_type' => 'gravityview', + 'post_status' => 'publish', + ); + + // Add the View + $view_post_type_id = wp_insert_post( $view_array ); + + // Set the form ID + update_post_meta( $view_post_type_id, '_gravityview_form_id', $this->form_id ); + + // Set the View settigns + update_post_meta( $view_post_type_id, '_gravityview_template_settings', GravityView_View_Data::get_default_args() ); + + // Set the template to be table + update_post_meta( $view_post_type_id, '_gravityview_directory_template', 'default_table' ); + + return $view_post_type_id; + + } + + /** + * @internal Make sure this test is above the test_directory_link() test so that one doesn't pollute $post + */ + public function test_gravityview_get_current_views() { + + $fe = GravityView_frontend::getInstance(); + + // Clear the data so that gravityview_get_current_views() runs parse_content() + $fe->gv_output_data = null; + + $view_post_type_id = $this->_get_new_view_id(); + + global $post; + + $post = get_post( $view_post_type_id ); + + $this->assertEquals( $view_post_type_id, $post->ID ); + + $current_views = gravityview_get_current_views(); + + // Check if the view post is set + $this->assertTrue( isset( $current_views[ $view_post_type_id ] ) ); + + // When the view is added, the key is set to the View ID and the `id` is also set to that + $this->assertEquals( $view_post_type_id, $current_views[ $view_post_type_id ]['id'] ); + + // Just one View + $this->assertEquals( 1, count( $current_views ) ); + + $second_view_post_type_id = $this->_get_new_view_id(); + + $fe->gv_output_data->add_view( $second_view_post_type_id ); + + $second_current_views = gravityview_get_current_views(); + + // Check to make sure add_view worked properly + $this->assertEquals( $second_view_post_type_id, $second_current_views[ $second_view_post_type_id ]['id'] ); + + // Now two Views + $this->assertEquals( 2, count( $second_current_views ) ); + + } + + /** + * @covers GravityView_API::directory_link() + */ + public function test_directory_link( ) { + $post_array = array( + 'post_content' => 'asdasdsd', + 'post_type' => 'post', + 'post_status' => 'publish', + ); + + $post_id = wp_insert_post( $post_array ); + + $view_post_type_id = $this->_get_new_view_id(); + + $_GET['pagenum'] = 2; + + $add_pagination = false; + $this->assertEquals( site_url( '?p=' . $post_id ), GravityView_API::directory_link( $post_id, $add_pagination ) ); + + $add_pagination = true; + $this->assertEquals( site_url( '?p=' . $post_id . '&pagenum=2' ), GravityView_API::directory_link( $post_id, $add_pagination ) ); + + // Make sure the cache is working properly + $this->assertEquals( site_url( '?p=' . $post_id ), wp_cache_get( 'gv_directory_link_' . $post_id ) ); + + // + // Use $gravityview_view data + // + global $gravityview_view; + global $post; + + $post = get_post( $view_post_type_id ); + + GravityView_frontend::getInstance()->parse_content(); + + $gravityview_view->setViewId( $view_post_type_id ); + + // Test post_id has been set + $gravityview_view->setPostId( $post_id ); + + /* TODO - fix this assertion */ + $this->assertEquals( site_url( '?p=' . $post_id . '&pagenum=2' ), GravityView_API::directory_link() ); + + $gravityview_view->setPostId( $post_id ); + + // + // TESTING AJAX + // + define( 'DOING_AJAX', true ); + + // No passed post_id; use $_POST when DOING_AJAX is set + $this->assertNull( GravityView_API::directory_link() ); + + $_POST['post_id'] = $post_id; + // No passed post_id; use $_POST when DOING_AJAX is set + $this->assertEquals( site_url( '?p=' . $post_id . '&pagenum=2' ), GravityView_API::directory_link() ); + + } + +} diff --git a/tests/unit-tests/helper-functions_Test.php b/tests/unit-tests/helper-functions_Test.php new file mode 100644 index 0000000000..e1600a762c --- /dev/null +++ b/tests/unit-tests/helper-functions_Test.php @@ -0,0 +1,248 @@ + gravityview_sanitize_html_class( 'example' ), + + // Don't strip dashes + 'example-dash' => gravityview_sanitize_html_class( 'example-dash' ), + + // Keep spaces + 'example dash' => gravityview_sanitize_html_class( 'example dash' ), + + // Implode with spaces + 'example dash bar' => gravityview_sanitize_html_class( array( 'example', 'dash', 'bar' ) ), + + // Again, don't strip spaces and implode + 'example-dash bar' => gravityview_sanitize_html_class( array( 'example-dash', 'bar' ) ), + + // Don't strip numbers or caps + 'Foo Bar0' => gravityview_sanitize_html_class( array( 'Foo', 'Bar0' ) ), + + // Strip not A-Z a-z 0-9 _ - + 'Foo Bar2_-' => gravityview_sanitize_html_class( 'Foo Bar2!_-' ), + ); + + foreach ( $classes as $expected => $formatted ) { + $this->assertEquals( $expected, $formatted ); + } + + } + + /** + * @group helperfunctions + */ + public function test_gravityview_format_link_DEFAULT() { + + $urls = array( + + // NOT URL + 'asdsadas' => 'asdsadas', + + // Path to root directory + 'http://example.com/example/' => 'example.com', + 'http://example.com/example/1/2/3/4/5/6/7/?example=123' => 'example.com', + 'https://example.com/example/page.html' => 'example.com', + + // No WWW + 'http://example.com' => 'example.com', // http + 'https://example.com' => 'example.com', // https + 'https://example.com/' => 'example.com', // trailing slash + 'https://example.com?example=123' => 'example.com', // no slash qv + 'https://example.com/?example=123' => 'example.com', // trailing slash qv + + // strip WWW + 'http://www.example.com' => 'example.com', // http + 'https://www.example.com' => 'example.com', // https + 'https://www.example.com/' => 'example.com', // trailing slash + 'https://www.example.com?example=123' => 'example.com', // no slash qv + 'https://www.example.com/?example=123' => 'example.com', // trailing slash qv + 'https://www.example.com/?example=123&test<0>=123' => 'example.com', // complex qv + + // strip subdomain + 'http://demo.example.com' => 'example.com', // http + 'https://demo.example.com' => 'example.com', // https + 'https://demo.example.com/' => 'example.com', // trailing slash + 'https://demo.example.com?example=123' => 'example.com', // no slash qv + 'https://demo.example.com/?example=123' => 'example.com', // trailing slash qv + + // Don't strip actual domain when using 2nd tier TLD + 'http://example.ac.za' => 'example.ac.za', + 'http://example.gov.za' => 'example.gov.za', + 'http://example.law.za' => 'example.law.za', + 'http://example.school.za' => 'example.school.za', + 'http://example.me.uk' => 'example.me.uk', + 'http://example.tm.fr' => 'example.tm.fr', + 'http://example.asso.fr' => 'example.asso.fr', + 'http://example.com.fr' => 'example.com.fr', + 'http://example.telememo.au' => 'example.telememo.au', + 'http://example.cg.yu' => 'example.cg.yu', + 'http://example.msk.ru' => 'example.msk.ru', + 'http://example.irkutsks.ru' => 'example.irkutsks.ru', + 'http://example.com.ru' => 'example.com.ru', + 'http://example.sa.au' => 'example.sa.au', + 'http://example.act.au' => 'example.act.au', + 'http://example.net.uk' => 'example.net.uk', + 'http://example.police.uk' => 'example.police.uk', + 'http://example.plc.uk' => 'example.plc.uk', + 'http://example.co.uk' => 'example.co.uk', + 'http://example.gov.uk' => 'example.gov.uk', + 'http://example.mod.uk' => 'example.mod.uk', + + // Strip subdomains in 2nd tier TLD + 'http://demo.example.ac.za' => 'example.ac.za', + 'http://demo.example.gov.za' => 'example.gov.za', + 'http://demo.example.law.za' => 'example.law.za', + 'http://demo.example.school.za' => 'example.school.za', + 'http://demo.example.me.uk' => 'example.me.uk', + 'http://demo.example.tm.fr' => 'example.tm.fr', + 'http://demo.example.asso.fr' => 'example.asso.fr', + 'http://demo.example.com.fr' => 'example.com.fr', + 'http://demo.example.telememo.au' => 'example.telememo.au', + 'http://demo.example.cg.yu' => 'example.cg.yu', + 'http://demo.example.msk.ru' => 'example.msk.ru', + 'http://demo.example.irkutsks.ru' => 'example.irkutsks.ru', + 'http://demo.example.com.ru' => 'example.com.ru', + 'http://demo.example.sa.au' => 'example.sa.au', + 'http://demo.example.act.au' => 'example.act.au', + 'http://demo.example.net.uk' => 'example.net.uk', + 'http://demo.example.police.uk' => 'example.police.uk', + 'http://demo.example.plc.uk' => 'example.plc.uk', + 'http://demo.example.co.uk' => 'example.co.uk', + 'http://demo.example.gov.uk' => 'example.gov.uk', + 'http://demo.example.mod.uk' => 'example.mod.uk', + ); + + foreach ( $urls as $original => $expected ) { + + $formatted = gravityview_format_link( $original ); + + $this->assertEquals( $expected, $formatted, 'Failed the formatting test' ); + + } + + } + + /** + * @group helperfunctions + */ + public function test_gravityview_format_link_WHEN_FILTER_ROOTONLY_FALSE() { + + // SET FILTER TO FALSE + add_filter( 'gravityview_anchor_text_rootonly', '__return_false' ); + + $urls = array( + + // DO NOT strip subdomains in 2nd tier TLD + 'http://example.com/path/to/webpage' => 'example.com/path/to/webpage', + 'http://example.com/path/to/webpage/' => 'example.com/path/to/webpage/', + 'http://example.com/webpage/?aasdasd=asdasd&asdasdasd=484ignasf' => 'example.com/webpage/', + 'http://example.com/webpage.html' => 'example.com/webpage.html', + ); + + foreach ( $urls as $original => $expected ) { + + $formatted = gravityview_format_link( $original ); + + $this->assertEquals( $expected, $formatted, 'Failed the formatting test' ); + + } + + // RETURN FILTER TO TRUE + add_filter( 'gravityview_anchor_text_rootonly', '__return_true' ); + + } + + /** + * @group helperfunctions + */ + public function test_gravityview_format_link_WHEN_FILTER_NOSUBDOMAIN_FALSE() { + + // SET FILTER TO FALSE + add_filter( 'gravityview_anchor_text_nosubdomain', '__return_false' ); + + $urls = array( + + // DO NOT strip subdomains in 2nd tier TLD + 'http://demo.example.ac.za' => 'demo.example.ac.za', + 'http://demo.example.gov.za' => 'demo.example.gov.za', + 'http://demo.example.law.za' => 'demo.example.law.za', + 'http://demo.example.school.za' => 'demo.example.school.za', + 'http://demo.example.me.uk' => 'demo.example.me.uk', + 'http://demo.example.tm.fr' => 'demo.example.tm.fr', + 'http://demo.example.asso.fr' => 'demo.example.asso.fr', + 'http://demo.example.com.fr' => 'demo.example.com.fr', + 'http://demo.example.telememo.au' => 'demo.example.telememo.au', + 'http://demo.example.cg.yu' => 'demo.example.cg.yu', + 'http://demo.example.msk.ru' => 'demo.example.msk.ru', + 'http://demo.example.irkutsks.ru' => 'demo.example.irkutsks.ru', + 'http://demo.example.com.ru' => 'demo.example.com.ru', + 'http://demo.example.sa.au' => 'demo.example.sa.au', + 'http://demo.example.act.au' => 'demo.example.act.au', + 'http://demo.example.net.uk' => 'demo.example.net.uk', + 'http://demo.example.police.uk' => 'demo.example.police.uk', + 'http://demo.example.plc.uk' => 'demo.example.plc.uk', + 'http://demo.example.co.uk' => 'demo.example.co.uk', + 'http://demo.example.gov.uk' => 'demo.example.gov.uk', + 'http://demo.example.mod.uk' => 'demo.example.mod.uk', + ); + + foreach ( $urls as $original => $expected ) { + + $formatted = gravityview_format_link( $original ); + + $this->assertEquals( $expected, $formatted, 'Failed the formatting test' ); + + } + + // RETURN FILTER TO TRUE + add_filter( 'gravityview_anchor_text_nosubdomain', '__return_true' ); + + } + + /** + * @group helperfunctions + */ + public function test_gravityview_format_link_WHEN_FILTER_NOQUERYSTRING_FALSE() { + + // SET FILTER TO FALSE + add_filter( 'gravityview_anchor_text_noquerystring', '__return_false' ); + + $urls = array( + + // NOT URL + 'asdsadas' => 'asdsadas', + + // No WWW + 'https://example.com?example=123' => 'example.com?example=123', // no slash qv + 'https://example.com/?example=123' => 'example.com?example=123', // trailing slash qv + + // strip WWW + 'https://www.example.com?example=123' => 'example.com?example=123', // no slash qv + 'https://www.example.com/?example=123' => 'example.com?example=123', // trailing slash qv + + // no subdomain + 'https://demo.example.com?example=123' => 'example.com?example=123', // no slash qv + 'https://demo.example.com/?example=123' => 'example.com?example=123', // trailing slash qv + ); + + foreach ( $urls as $original => $expected ) { + + $formatted = gravityview_format_link( $original ); + + $this->assertEquals( $expected, $formatted, 'Failed the formatting test' ); + + } + + // RETURN FILTER TO TRUE + add_filter( 'gravityview_anchor_text_noquerystring', '__return_true' ); + } +} From f5c2f620dd1c1b337059e6c2ccf1cf18b4d05f9d Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 8 Sep 2015 12:39:45 -0600 Subject: [PATCH 10/21] Renamed the file --- tests/unit-tests/connector-API_Test.php | 536 ------------------------ 1 file changed, 536 deletions(-) delete mode 100644 tests/unit-tests/connector-API_Test.php diff --git a/tests/unit-tests/connector-API_Test.php b/tests/unit-tests/connector-API_Test.php deleted file mode 100644 index d87469bf4b..0000000000 --- a/tests/unit-tests/connector-API_Test.php +++ /dev/null @@ -1,536 +0,0 @@ -form = GV_Unit_Tests_Bootstrap::instance()->get_form(); - $this->form_id = GV_Unit_Tests_Bootstrap::instance()->get_form_id(); - - $this->entry = GV_Unit_Tests_Bootstrap::instance()->get_entry(); - $this->entry_id = GV_Unit_Tests_Bootstrap::instance()->get_entry_id(); - } - - /** - * @covers GravityView_API::replace_variables() - * @covers GravityView_Merge_Tags::replace_variables() - */ - public function test_replace_variables() { - - $entry = GV_Unit_Tests_Bootstrap::instance()->get_entry(); - - $form = GV_Unit_Tests_Bootstrap::instance()->get_form(); - - // No match - $this->assertEquals( 'no bracket', GravityView_API::replace_variables( 'no bracket', $form, $entry ) ); - - // Include bracket with nomatch - $this->assertEquals( $entry['id'] . ' {nomatch}', GravityView_API::replace_variables( '{entry_id} {nomatch}', $form, $entry ) ); - - // Match tag, empty value - $this->assertEquals( '', GravityView_API::replace_variables( '{user:example}', $form, $entry ) ); - - // Open matching tag - $this->assertEquals( '{entry_id', GravityView_API::replace_variables( '{entry_id', $form, $entry ) ); - - // Form ID - $this->assertEquals( $form['id'], GravityView_API::replace_variables( '{form_id}', $form, $entry ) ); - - // Form title - $this->assertEquals( 'Example '.$form['title'], GravityView_API::replace_variables( 'Example {form_title}', $form, $entry ) ); - - $this->assertEquals( $entry['post_id'], GravityView_API::replace_variables( '{post_id}', $form, $entry ) ); - - $this->assertEquals( date( 'm/d/Y' ), GravityView_API::replace_variables( '{date_mdy}', $form, $entry ) ); - - $this->assertEquals( get_option( 'admin_email' ), GravityView_API::replace_variables( '{admin_email}', $form, $entry ) ); - - $user = wp_set_current_user( $entry['created_by'] ); - - // Test new Roles merge tag - $this->assertEquals( implode( ', ', $user->roles ), GravityView_API::replace_variables( '{created_by:roles}', $form, $entry ) ); - - $user->add_role( 'editor' ); - - // Test new Roles merge tag again, with another role. - $this->assertEquals( implode( ', ', $user->roles ), GravityView_API::replace_variables( '{created_by:roles}', $form, $entry ) ); - - $var_content = '

I expect Entry #{entry_id} will be in Form #{form_id}

'; - $expected_content = '

I expect Entry #'.$entry['id'].' will be in Form #'.$form['id'].'

'; - $this->assertEquals( $expected_content, GravityView_API::replace_variables( $var_content, $form, $entry ) ); - - } - - /** - * @covers GravityView_API::field_class() - */ - public function test_field_class() { - - $entry = $this->entry; - - $form = $this->form; - - $field_id = 2; - - $field = GFFormsModel::get_field( $form, $field_id); - - $this->assertEquals( 'gv-field-'.$form['id'].'-'.$field_id, GravityView_API::field_class( $field, $form, $entry ) ); - - $field['custom_class'] = 'custom-class-{entry_id}'; - - // Test the replace_variables functionality - $this->assertEquals( 'custom-class-'.$entry['id'].' gv-field-'.$form['id'].'-'.$field_id, GravityView_API::field_class( $field, $form, $entry ) ); - - $field['custom_class'] = 'testing,!@@($)*$ 12383'; - - // Test the replace_variables functionality - $this->assertEquals( 'testing 12383 gv-field-'.$form['id'].'-'.$field_id, GravityView_API::field_class( $field, $form, $entry ) ); - - } - - /** - * @uses GravityView_API_Test::_override_no_entries_text_output() - * @covers GravityView_API::no_results() - */ - public function test_no_results() { - - global $gravityview_view; - - $gravityview_view = GravityView_View::getInstance(); - - $gravityview_view->curr_start = false; - $gravityview_view->curr_end = false; - $gravityview_view->curr_search = false; - - // Not in search by default - $this->assertEquals( 'No entries match your request.', GravityView_API::no_results( false ) ); - $this->assertEquals( '

No entries match your request.

'."\n", GravityView_API::no_results( true ) ); - // Pretend we're in search - $gravityview_view->curr_search = true; - - $this->assertEquals( 'This search returned no results.', GravityView_API::no_results( false ) ); - $this->assertEquals( '

This search returned no results.

'."\n", GravityView_API::no_results( true ) ); - - - // Add the filter that modifies output - add_filter( 'gravitview_no_entries_text', array( $this, '_override_no_entries_text_output' ), 10, 2 ); - - // Test to make sure the $is_search parameter is passed correctly - $this->assertEquals( 'SEARCH override the no entries text output', GravityView_API::no_results( false ) ); - - $gravityview_view->curr_search = false; - - // Test to make sure the $is_search parameter is passed correctly - $this->assertEquals( 'NO SEARCH override the no entries text output', GravityView_API::no_results( false ) ); - - // Remove the filter for later - remove_filter( 'gravitview_no_entries_text', array( $this, '_override_no_entries_text_output' ) ); - - } - - public function _override_no_entries_text_output( $previous, $is_search = false ) { - - if ( $is_search ) { - return 'SEARCH override the no entries text output'; - } else { - return 'NO SEARCH override the no entries text output'; - } - - } - - public function _get_new_view_id() { - - $view_array = array( - 'post_content' => '', - 'post_type' => 'gravityview', - 'post_status' => 'publish', - ); - - // Add the View - $view_post_type_id = wp_insert_post( $view_array ); - - // Set the form ID - update_post_meta( $view_post_type_id, '_gravityview_form_id', $this->form_id ); - - // Set the View settigns - update_post_meta( $view_post_type_id, '_gravityview_template_settings', GravityView_View_Data::get_default_args() ); - - // Set the template to be table - update_post_meta( $view_post_type_id, '_gravityview_directory_template', 'default_table' ); - - return $view_post_type_id; - - } - - /** - * @internal Make sure this test is above the test_directory_link() test so that one doesn't pollute $post - */ - public function test_gravityview_get_current_views() { - - $fe = GravityView_frontend::getInstance(); - - // Clear the data so that gravityview_get_current_views() runs parse_content() - $fe->gv_output_data = null; - - $view_post_type_id = $this->_get_new_view_id(); - - global $post; - - $post = get_post( $view_post_type_id ); - - $this->assertEquals( $view_post_type_id, $post->ID ); - - $current_views = gravityview_get_current_views(); - - // Check if the view post is set - $this->assertTrue( isset( $current_views[ $view_post_type_id ] ) ); - - // When the view is added, the key is set to the View ID and the `id` is also set to that - $this->assertEquals( $view_post_type_id, $current_views[ $view_post_type_id ]['id'] ); - - // Just one View - $this->assertEquals( 1, count( $current_views ) ); - - $second_view_post_type_id = $this->_get_new_view_id(); - - $fe->gv_output_data->add_view( $second_view_post_type_id ); - - $second_current_views = gravityview_get_current_views(); - - // Check to make sure add_view worked properly - $this->assertEquals( $second_view_post_type_id, $second_current_views[ $second_view_post_type_id ]['id'] ); - - // Now two Views - $this->assertEquals( 2, count( $second_current_views ) ); - - } - - public function test_directory_link( ) { - $post_array = array( - 'post_content' => 'asdasdsd', - 'post_type' => 'post', - 'post_status' => 'publish', - ); - - $post_id = wp_insert_post( $post_array ); - - $view_post_type_id = $this->_get_new_view_id(); - - $_GET['pagenum'] = 2; - - $add_pagination = false; - $this->assertEquals( site_url( '?p=' . $post_id ), GravityView_API::directory_link( $post_id, $add_pagination ) ); - - $add_pagination = true; - $this->assertEquals( site_url( '?p=' . $post_id . '&pagenum=2' ), GravityView_API::directory_link( $post_id, $add_pagination ) ); - - // Make sure the cache is working properly - $this->assertEquals( site_url( '?p=' . $post_id ), wp_cache_get( 'gv_directory_link_' . $post_id ) ); - - // - // Use $gravityview_view data - // - global $gravityview_view; - global $post; - - $post = get_post( $view_post_type_id ); - - GravityView_frontend::getInstance()->parse_content(); - - $gravityview_view->setViewId( $view_post_type_id ); - - // Test post_id has been set - $gravityview_view->setPostId( $post_id ); - - /* TODO - fix this assertion */ - $this->assertEquals( site_url( '?p=' . $post_id . '&pagenum=2' ), GravityView_API::directory_link() ); - - $gravityview_view->setPostId( $post_id ); - - // - // TESTING AJAX - // - define( 'DOING_AJAX', true ); - - // No passed post_id; use $_POST when DOING_AJAX is set - $this->assertNull( GravityView_API::directory_link() ); - - $_POST['post_id'] = $post_id; - // No passed post_id; use $_POST when DOING_AJAX is set - $this->assertEquals( site_url( '?p=' . $post_id . '&pagenum=2' ), GravityView_API::directory_link() ); - - } - - /** - * - */ - public function test_gravityview_sanitize_html_class() { - - $classes = array( - - // basic - 'example' => gravityview_sanitize_html_class( 'example' ), - - // Don't strip dashes - 'example-dash' => gravityview_sanitize_html_class( 'example-dash' ), - - // Keep spaces - 'example dash' => gravityview_sanitize_html_class( 'example dash' ), - - // Implode with spaces - 'example dash bar' => gravityview_sanitize_html_class( array( 'example', 'dash', 'bar' ) ), - - // Again, don't strip spaces and implode - 'example-dash bar' => gravityview_sanitize_html_class( array( 'example-dash', 'bar' ) ), - - // Don't strip numbers or caps - 'Foo Bar0' => gravityview_sanitize_html_class( array( 'Foo', 'Bar0' ) ), - - // Strip not A-Z a-z 0-9 _ - - 'Foo Bar2_-' => gravityview_sanitize_html_class( 'Foo Bar2!_-' ), - ); - - foreach ( $classes as $expected => $formatted ) { - $this->assertEquals( $expected, $formatted ); - } - - } - - /** - * @group api - */ - public function test_gravityview_format_link_DEFAULT() { - - $urls = array( - - // NOT URL - 'asdsadas' => 'asdsadas', - - // Path to root directory - 'http://example.com/example/' => 'example.com', - 'http://example.com/example/1/2/3/4/5/6/7/?example=123' => 'example.com', - 'https://example.com/example/page.html' => 'example.com', - - // No WWW - 'http://example.com' => 'example.com', // http - 'https://example.com' => 'example.com', // https - 'https://example.com/' => 'example.com', // trailing slash - 'https://example.com?example=123' => 'example.com', // no slash qv - 'https://example.com/?example=123' => 'example.com', // trailing slash qv - - // strip WWW - 'http://www.example.com' => 'example.com', // http - 'https://www.example.com' => 'example.com', // https - 'https://www.example.com/' => 'example.com', // trailing slash - 'https://www.example.com?example=123' => 'example.com', // no slash qv - 'https://www.example.com/?example=123' => 'example.com', // trailing slash qv - 'https://www.example.com/?example=123&test<0>=123' => 'example.com', // complex qv - - // strip subdomain - 'http://demo.example.com' => 'example.com', // http - 'https://demo.example.com' => 'example.com', // https - 'https://demo.example.com/' => 'example.com', // trailing slash - 'https://demo.example.com?example=123' => 'example.com', // no slash qv - 'https://demo.example.com/?example=123' => 'example.com', // trailing slash qv - - // Don't strip actual domain when using 2nd tier TLD - 'http://example.ac.za' => 'example.ac.za', - 'http://example.gov.za' => 'example.gov.za', - 'http://example.law.za' => 'example.law.za', - 'http://example.school.za' => 'example.school.za', - 'http://example.me.uk' => 'example.me.uk', - 'http://example.tm.fr' => 'example.tm.fr', - 'http://example.asso.fr' => 'example.asso.fr', - 'http://example.com.fr' => 'example.com.fr', - 'http://example.telememo.au' => 'example.telememo.au', - 'http://example.cg.yu' => 'example.cg.yu', - 'http://example.msk.ru' => 'example.msk.ru', - 'http://example.irkutsks.ru' => 'example.irkutsks.ru', - 'http://example.com.ru' => 'example.com.ru', - 'http://example.sa.au' => 'example.sa.au', - 'http://example.act.au' => 'example.act.au', - 'http://example.net.uk' => 'example.net.uk', - 'http://example.police.uk' => 'example.police.uk', - 'http://example.plc.uk' => 'example.plc.uk', - 'http://example.co.uk' => 'example.co.uk', - 'http://example.gov.uk' => 'example.gov.uk', - 'http://example.mod.uk' => 'example.mod.uk', - - // Strip subdomains in 2nd tier TLD - 'http://demo.example.ac.za' => 'example.ac.za', - 'http://demo.example.gov.za' => 'example.gov.za', - 'http://demo.example.law.za' => 'example.law.za', - 'http://demo.example.school.za' => 'example.school.za', - 'http://demo.example.me.uk' => 'example.me.uk', - 'http://demo.example.tm.fr' => 'example.tm.fr', - 'http://demo.example.asso.fr' => 'example.asso.fr', - 'http://demo.example.com.fr' => 'example.com.fr', - 'http://demo.example.telememo.au' => 'example.telememo.au', - 'http://demo.example.cg.yu' => 'example.cg.yu', - 'http://demo.example.msk.ru' => 'example.msk.ru', - 'http://demo.example.irkutsks.ru' => 'example.irkutsks.ru', - 'http://demo.example.com.ru' => 'example.com.ru', - 'http://demo.example.sa.au' => 'example.sa.au', - 'http://demo.example.act.au' => 'example.act.au', - 'http://demo.example.net.uk' => 'example.net.uk', - 'http://demo.example.police.uk' => 'example.police.uk', - 'http://demo.example.plc.uk' => 'example.plc.uk', - 'http://demo.example.co.uk' => 'example.co.uk', - 'http://demo.example.gov.uk' => 'example.gov.uk', - 'http://demo.example.mod.uk' => 'example.mod.uk', - ); - - foreach ( $urls as $original => $expected ) { - - $formatted = gravityview_format_link( $original ); - - $this->assertEquals( $expected, $formatted, 'Failed the formatting test' ); - - } - - } - - /** - * @group api - */ - public function test_gravityview_format_link_WHEN_FILTER_ROOTONLY_FALSE() { - - // SET FILTER TO FALSE - add_filter( 'gravityview_anchor_text_rootonly', '__return_false' ); - - $urls = array( - - // DO NOT strip subdomains in 2nd tier TLD - 'http://example.com/path/to/webpage' => 'example.com/path/to/webpage', - 'http://example.com/path/to/webpage/' => 'example.com/path/to/webpage/', - 'http://example.com/webpage/?aasdasd=asdasd&asdasdasd=484ignasf' => 'example.com/webpage/', - 'http://example.com/webpage.html' => 'example.com/webpage.html', - ); - - foreach ( $urls as $original => $expected ) { - - $formatted = gravityview_format_link( $original ); - - $this->assertEquals( $expected, $formatted, 'Failed the formatting test' ); - - } - - // RETURN FILTER TO TRUE - add_filter( 'gravityview_anchor_text_rootonly', '__return_true' ); - - } - - /** - * @group api - */ - public function test_gravityview_format_link_WHEN_FILTER_NOSUBDOMAIN_FALSE() { - - // SET FILTER TO FALSE - add_filter( 'gravityview_anchor_text_nosubdomain', '__return_false' ); - - $urls = array( - - // DO NOT strip subdomains in 2nd tier TLD - 'http://demo.example.ac.za' => 'demo.example.ac.za', - 'http://demo.example.gov.za' => 'demo.example.gov.za', - 'http://demo.example.law.za' => 'demo.example.law.za', - 'http://demo.example.school.za' => 'demo.example.school.za', - 'http://demo.example.me.uk' => 'demo.example.me.uk', - 'http://demo.example.tm.fr' => 'demo.example.tm.fr', - 'http://demo.example.asso.fr' => 'demo.example.asso.fr', - 'http://demo.example.com.fr' => 'demo.example.com.fr', - 'http://demo.example.telememo.au' => 'demo.example.telememo.au', - 'http://demo.example.cg.yu' => 'demo.example.cg.yu', - 'http://demo.example.msk.ru' => 'demo.example.msk.ru', - 'http://demo.example.irkutsks.ru' => 'demo.example.irkutsks.ru', - 'http://demo.example.com.ru' => 'demo.example.com.ru', - 'http://demo.example.sa.au' => 'demo.example.sa.au', - 'http://demo.example.act.au' => 'demo.example.act.au', - 'http://demo.example.net.uk' => 'demo.example.net.uk', - 'http://demo.example.police.uk' => 'demo.example.police.uk', - 'http://demo.example.plc.uk' => 'demo.example.plc.uk', - 'http://demo.example.co.uk' => 'demo.example.co.uk', - 'http://demo.example.gov.uk' => 'demo.example.gov.uk', - 'http://demo.example.mod.uk' => 'demo.example.mod.uk', - ); - - foreach ( $urls as $original => $expected ) { - - $formatted = gravityview_format_link( $original ); - - $this->assertEquals( $expected, $formatted, 'Failed the formatting test' ); - - } - - // RETURN FILTER TO TRUE - add_filter( 'gravityview_anchor_text_nosubdomain', '__return_true' ); - - } - - /** - * @group api - */ - public function test_gravityview_format_link_WHEN_FILTER_NOQUERYSTRING_FALSE() { - - // SET FILTER TO FALSE - add_filter( 'gravityview_anchor_text_noquerystring', '__return_false' ); - - $urls = array( - - // NOT URL - 'asdsadas' => 'asdsadas', - - // No WWW - 'https://example.com?example=123' => 'example.com?example=123', // no slash qv - 'https://example.com/?example=123' => 'example.com?example=123', // trailing slash qv - - // strip WWW - 'https://www.example.com?example=123' => 'example.com?example=123', // no slash qv - 'https://www.example.com/?example=123' => 'example.com?example=123', // trailing slash qv - - // no subdomain - 'https://demo.example.com?example=123' => 'example.com?example=123', // no slash qv - 'https://demo.example.com/?example=123' => 'example.com?example=123', // trailing slash qv - ); - - foreach ( $urls as $original => $expected ) { - - $formatted = gravityview_format_link( $original ); - - $this->assertEquals( $expected, $formatted, 'Failed the formatting test' ); - - } - - // RETURN FILTER TO TRUE - add_filter( 'gravityview_anchor_text_noquerystring', '__return_true' ); - } -} From df445cf77a7a13e92a341e006f822e654a681134 Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 8 Sep 2015 12:40:27 -0600 Subject: [PATCH 11/21] Start of Factory class for GF objects --- tests/bootstrap.php | 7 +- tests/factory.php | 102 ++++++++++++++++++++++ tests/unit-tests/GravityView_API_Test.php | 2 + 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 tests/factory.php diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 2d016b5a2c..53587d2016 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -60,7 +60,9 @@ public function __construct() { // load the WP testing environment require_once( $this->wp_tests_dir . '/includes/bootstrap.php' ); - // set up Gravity View + require_once $this->tests_dir . '/factory.php'; + + // set up GravityView $this->install(); } @@ -73,6 +75,9 @@ public function load() { require_once $this->plugin_dir . '/tmp/gravityforms/gravityforms.php'; require_once $this->plugin_dir . '/gravityview.php'; + /* Remove temporary tables which causes problems with GF */ + remove_all_filters( 'query', 10 ); + // set up Gravity Forms database @GFForms::setup( true ); diff --git a/tests/factory.php b/tests/factory.php new file mode 100644 index 0000000000..53ed42a578 --- /dev/null +++ b/tests/factory.php @@ -0,0 +1,102 @@ +entry = new GF_UnitTest_Factory_For_Entry( $this ); + $this->form = new GF_UnitTest_Factory_For_Form( $this ); + + } +} + +class GF_UnitTest_Factory_For_Entry extends WP_UnitTest_Factory_For_Thing { + + function __construct( $factory = null ) { + parent::__construct( $factory ); + $this->default_generation_definitions = array( + '1' => 'Value for field one', + '2' => 'Value for field two', + '3' => '3.33333', + 'ip' => '127.0.0.1', + 'source_url' => 'http://example.com/wordpress/?gf_page=preview&id=16', + 'user_agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.78.2 (KHTML, like Gecko) Version/7.0.6 Safari/537.78.2', + 'payment_status' => 'Processing', + 'payment_date' => '2014-08-29 20:55:06', + 'payment_amount' => '0.01', + 'transaction_id' => 'asdfpaoj442gpoagfadf', + 'created_by' => 1, + 'status' => 'active', + 'date_created' => '2014-08-29 18:25:39', + ); + } + + function create_object( $args ) { + return GFAPI::add_entry( $args ); + } + + function get_object_by_id( $object_id ) { + return GFAPI::get_entry( $object_id ); + } + + /** + * @param $object + * @param $fields + * + * @return mixed + */ + function update_object( $entry_id = '', $entry = array() ) { + return GFAPI::update_entry( $entry_id, $entry ); + } +} + +class GF_UnitTest_Factory_For_Form extends WP_UnitTest_Factory_For_Thing { + + function __construct( $factory = null ) { + parent::__construct( $factory ); + $this->default_generation_definitions = array( + 'title' => 'This is the form title', + 'fields' => array( + new GF_Field_Text(array( + 'id' => 1, + 'label' => 'Label for field one (text)', + 'choices' => array(), + 'inputs' => '', + )), + new GF_Field_Hidden(array( + 'id' => 2, + 'label' => 'Label for field two (hidden)', + 'choices' => array(), + 'inputs' => '', + )), + new GF_Field_Number(array( + 'id' => 3, + 'label' => 'Label for field three (number)', + 'choices' => array(), + 'inputs' => '', + )) + ), + ); + } + + function create_object( $file, $parent = 0, $args = array() ) { + return GFAPI::add_form( $args ); + } + + function get_object_by_id( $object_id ) { + return GFAPI::get_form( $object_id ); + } + + function update_object( $object, $fields ) {} +} \ No newline at end of file diff --git a/tests/unit-tests/GravityView_API_Test.php b/tests/unit-tests/GravityView_API_Test.php index c55644b838..5eb7967d86 100644 --- a/tests/unit-tests/GravityView_API_Test.php +++ b/tests/unit-tests/GravityView_API_Test.php @@ -39,6 +39,8 @@ function setUp() { $this->entry = GV_Unit_Tests_Bootstrap::instance()->get_entry(); $this->entry_id = GV_Unit_Tests_Bootstrap::instance()->get_entry_id(); + $this->factory = new GF_UnitTest_Factory( $this ); + } /** From 114f2dfcbcfb4a46d91c09e2eec1d7323c4232f4 Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 8 Sep 2015 12:40:55 -0600 Subject: [PATCH 12/21] Start of uninstall test --- .../unit-tests/GravityView_Uninstall_Test.php | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 tests/unit-tests/GravityView_Uninstall_Test.php diff --git a/tests/unit-tests/GravityView_Uninstall_Test.php b/tests/unit-tests/GravityView_Uninstall_Test.php new file mode 100644 index 0000000000..cf34f29862 --- /dev/null +++ b/tests/unit-tests/GravityView_Uninstall_Test.php @@ -0,0 +1,50 @@ +plugin_dir . '/uninstall.php'; + + + $this->form = GV_Unit_Tests_Bootstrap::instance()->get_form(); + $this->form_id = GV_Unit_Tests_Bootstrap::instance()->get_form_id(); + + $this->entry = GV_Unit_Tests_Bootstrap::instance()->get_entry(); + $this->entry_id = GV_Unit_Tests_Bootstrap::instance()->get_entry_id(); + + do_action( 'deactivate_gravityview/gravityview.php' ); + } + + /** + * @group uninstall + */ + function test_gravityview_has_shortcode_r() { + + + + } +} From 9896edb322d2a5acbedc516ad2318e6e46afdd7e Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 29 Sep 2015 14:55:09 -0600 Subject: [PATCH 13/21] Fix issue Fix issue where xdebug_log file wasn't created sometimes. --- tests/bin/install.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/bin/install.sh b/tests/bin/install.sh index f0ba65d6c6..1c24192c1f 100755 --- a/tests/bin/install.sh +++ b/tests/bin/install.sh @@ -78,10 +78,18 @@ install_db() { fi # create database - mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA + mysqladmin CREATE $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA; +} + +# Create xdebug log, if not correctly installed by Vagrant +# See https://github.com/Varying-Vagrant-Vagrants/VVV/issues/621 +fix_vagrant_permissions() { + sudo touch /tmp/xdebug-remote.log; + sudo chmod 666 /tmp/xdebug-remote.log; } install_wp install_depencency install_test_suite install_db +fix_vagrant_permissions \ No newline at end of file From e03863f0c0b25a502a461776eeb25d8251e6ce4b Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 29 Sep 2015 14:55:56 -0600 Subject: [PATCH 14/21] Add support for GravityView errors to be output in CLI `gravityview_log_error` and `gravityview_log_debug`. `gravityview_log_debug` only if `phpdebug --debug --verbose` is used. --- tests/bootstrap.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 53587d2016..18c8ce1d96 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -57,6 +57,13 @@ public function __construct() { // load GV tests_add_filter( 'muplugins_loaded', array( $this, 'load' ) ); + tests_add_filter( 'gravityview_log_error', array( $this, 'test_print_log'), 10, 3 ); + + // Log debug if passed to `phpunit` like: `phpunit --debug --verbose` + if( in_array( '--debug', (array)$_SERVER['argv'], true ) && in_array( '--verbose', (array)$_SERVER['argv'], true ) ) { + tests_add_filter( 'gravityview_log_debug', array( $this, 'test_print_log' ), 10, 3 ); + } + // load the WP testing environment require_once( $this->wp_tests_dir . '/includes/bootstrap.php' ); @@ -66,6 +73,15 @@ public function __construct() { $this->install(); } + public function test_print_log( $message = '', $data = null ) { + $error = array( + 'message' => $message, + 'data' => $data, + 'backtrace' => function_exists('wp_debug_backtrace_summary') ? wp_debug_backtrace_summary( null, 3 ) : '', + ); + fwrite(STDERR, print_r( $error, true ) ); + } + /** * Load GravityView * From 4aea94b7ace2cfcf1dd000df7f3a29a2ff4fee26 Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 29 Sep 2015 14:58:48 -0600 Subject: [PATCH 15/21] Add custom user factory * Override `create()` to fetch existing user if exists * Add `set()` as `wp_set_current_user()` alias --- tests/factory.php | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/factory.php b/tests/factory.php index 53ed42a578..9bdb4a6cc2 100644 --- a/tests/factory.php +++ b/tests/factory.php @@ -12,13 +12,67 @@ class GF_UnitTest_Factory extends WP_UnitTest_Factory { */ public $entry; + /** + * @var GV_UnitTest_Factory_For_User + */ + public $user; + function __construct() { parent::__construct(); + $this->user = new GV_UnitTest_Factory_For_User( $this ); + $this->entry = new GF_UnitTest_Factory_For_Entry( $this ); $this->form = new GF_UnitTest_Factory_For_Form( $this ); } + +} + +class GV_UnitTest_Factory_For_User extends WP_UnitTest_Factory_For_User { + + function create( $args = array(), $generation_definitions = array() ) { + $user = false; + if( ! empty( $args['user_login'] ) ) { + $user = get_user_by( 'login', $args['user_login'] ); + } else if( ! empty( $args['id'] ) ) { + $user = get_user_by( 'id', $args['id'] ); + } + + return $user ? $user->ID : parent::create( $args, $generation_definitions ); + } + + /** + * Create the user, then set the current user to the created user. + * + * @param array $args + * @param null $generation_definitions + * + * @return bool|WP_User + */ + function create_and_set( $args = array(), $generation_definitions = null ) { + + $user_id = $this->create( $args, $generation_definitions ); + + if( ! $user_id || is_wp_error( $user_id ) ) { + return false; + } + + return $this->set( $user_id ); + } + + /** + * Alias for wp_set_current_user() + * + * @see wp_set_current_user() + * + * @param $user_id + * + * @return WP_User + */ + function set( $user_id ) { + return wp_set_current_user( $user_id ); + } } class GF_UnitTest_Factory_For_Entry extends WP_UnitTest_Factory_For_Thing { From c020a641ff63ac03fe956c4ae1f9faf039a88ebb Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 29 Sep 2015 14:59:51 -0600 Subject: [PATCH 16/21] Add a View factory --- tests/factory.php | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/factory.php b/tests/factory.php index 9bdb4a6cc2..2a9d123ec4 100644 --- a/tests/factory.php +++ b/tests/factory.php @@ -12,6 +12,11 @@ class GF_UnitTest_Factory extends WP_UnitTest_Factory { */ public $entry; + /** + * @var GV_UnitTest_Factory_For_View + */ + public $view; + /** * @var GV_UnitTest_Factory_For_User */ @@ -25,6 +30,53 @@ function __construct() { $this->entry = new GF_UnitTest_Factory_For_Entry( $this ); $this->form = new GF_UnitTest_Factory_For_Form( $this ); + $this->view = new GV_UnitTest_Factory_For_View( $this ); + + } +} + +class GV_UnitTest_Factory_For_View extends WP_UnitTest_Factory_For_Post { + + /** + * @param GF_UnitTest_Factory $factory + */ + function __construct( $factory = null ) { + + parent::__construct( $factory ); + + $form = $factory->form->create_and_get(); + + $this->default_generation_definitions = array( + 'post_status' => 'publish', + 'post_title' => new WP_UnitTest_Generator_Sequence( 'GravityView title %s' ), + 'post_content' => '', + 'post_excerpt' => '', + 'post_type' => 'gravityview', + 'form_id' => $form['id'], + 'settings' => GravityView_View_Data::get_default_args(), + ); + } + + function create_object( $args ) { + $insert_post_response = parent::create_object( $args ); + + if( $insert_post_response && !is_wp_error( $insert_post_response ) ) { + + $view_meta = array( + '_gravityview_form_id' => $args['form_id'], + '_gravityview_template_settings' => $args['settings'], + '_gravityview_directory_template' => 'preset_business_data', + '_gravityview_directory_widgets' => 'a:0:{}', + '_gravityview_directory_fields' => 'a:1:{s:23:"directory_table-columns";a:3:{s:13:"535d63d1488b0";a:9:{s:2:"id";s:1:"4";s:5:"label";s:13:"Business Name";s:10:"show_label";s:1:"1";s:12:"custom_label";s:0:"";s:12:"custom_class";s:0:"";s:12:"show_as_link";s:1:"0";s:13:"search_filter";s:1:"0";s:13:"only_loggedin";s:1:"0";s:17:"only_loggedin_cap";s:4:"read";}s:13:"535d63d379a3c";a:9:{s:2:"id";s:2:"12";s:5:"label";s:20:"Business Description";s:10:"show_label";s:1:"1";s:12:"custom_label";s:0:"";s:12:"custom_class";s:0:"";s:12:"show_as_link";s:1:"0";s:13:"search_filter";s:1:"0";s:13:"only_loggedin";s:1:"0";s:17:"only_loggedin_cap";s:4:"read";}s:13:"535d63dc735a6";a:9:{s:2:"id";s:1:"2";s:5:"label";s:7:"Address";s:10:"show_label";s:1:"1";s:12:"custom_label";s:0:"";s:12:"custom_class";s:0:"";s:12:"show_as_link";s:1:"0";s:13:"search_filter";s:1:"0";s:13:"only_loggedin";s:1:"0";s:17:"only_loggedin_cap";s:4:"read";}}}', + ); + + foreach ( $view_meta as $meta_key => $meta_value ) { + $meta_value = maybe_unserialize( $meta_value ); + update_post_meta( $insert_post_response, $meta_key, $meta_value ); + } + } + + return $insert_post_response; } } From 8d0437b807925e3282b171acd3d24e36f152ab7b Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 29 Sep 2015 15:00:14 -0600 Subject: [PATCH 17/21] Auto-increment form title --- tests/factory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/factory.php b/tests/factory.php index 2a9d123ec4..8a7a6e21b4 100644 --- a/tests/factory.php +++ b/tests/factory.php @@ -172,7 +172,7 @@ class GF_UnitTest_Factory_For_Form extends WP_UnitTest_Factory_For_Thing { function __construct( $factory = null ) { parent::__construct( $factory ); $this->default_generation_definitions = array( - 'title' => 'This is the form title', + 'title' => new WP_UnitTest_Generator_Sequence( 'Form Title %s' ), 'fields' => array( new GF_Field_Text(array( 'id' => 1, From 3505930de5f59f445872404b38fb0b09b71d0ea9 Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 29 Sep 2015 15:30:46 -0600 Subject: [PATCH 18/21] Almost full coverage of the GravityView_Edit_Entry class --- .../GravityView_Edit_Entry_Test.php | 289 ++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 tests/unit-tests/GravityView_Edit_Entry_Test.php diff --git a/tests/unit-tests/GravityView_Edit_Entry_Test.php b/tests/unit-tests/GravityView_Edit_Entry_Test.php new file mode 100644 index 0000000000..612ed86961 --- /dev/null +++ b/tests/unit-tests/GravityView_Edit_Entry_Test.php @@ -0,0 +1,289 @@ +factory = new GF_UnitTest_Factory( $this ); + } + + /** + * @covers GravityView_Edit_Entry::getInstance() + */ + function test_getInstance() { + $this->assertTrue( GravityView_Edit_Entry::getInstance() instanceof GravityView_Edit_Entry ); + } + + /** + * @covers GravityView_Edit_Entry::get_edit_link() + */ + function test_get_edit_link() { + + $form = $this->factory->form->create_and_get(); + + $editor = $this->factory->user->create_and_set( array( + 'user_login' => 'editor', + 'role' => 'editor' + ) ); + + $entry = $this->factory->entry->create_and_get( array( + 'form_id' => $form['id'], + 'created_by' => $editor->ID, + ) ); + + $view = $this->factory->view->create_and_get(array( + 'form_id' => $form['id'], + 'settings' => array( + 'user_edit' => 1 + ), + )); + + $post_id = $this->factory->post->create(array( + 'post_title' => new WP_UnitTest_Generator_Sequence( __METHOD__ . ' %s' ), + 'post_content' => sprintf( '[gravityview id="%d"]', $view->ID ), + )); + + $nonce_key = GravityView_Edit_Entry::get_nonce_key( $view->ID, $entry['form_id'], $entry['id'] ); + + $nonce = wp_create_nonce( $nonce_key ); + + ### + ### NO POST + ### + $edit_link_no_post = GravityView_Edit_Entry::get_edit_link( $entry, $view->ID ); + + $this->assertEquals( '?page=gf_entries&view=entry&edit='.$nonce, $edit_link_no_post ); + + $args = array( + 'p' => $post_id, + 'entry' => $entry['id'], + 'gvid' => $view->ID, + 'page' => 'gf_entries', + 'view' => 'entry', + 'edit' => $nonce, + ); + + // The test thinks we have multiple Views. Correct that. + GravityView_View::getInstance()->setViewId( $view->ID ); + + ### + ### WITH POST + ### + $edit_link_with_post = GravityView_Edit_Entry::get_edit_link( $entry, $view->ID, $post_id ); + + $this->assertEquals( add_query_arg( $args, 'http://example.org/' ), $edit_link_with_post ); + + } + + /** + * @covers GravityView_Edit_Entry::add_template_path + */ + public function test_add_template_path() { + + $template_paths = GravityView_Edit_Entry::getInstance()->add_template_path( array() ); + + $expected = array( + 110 => GravityView_Edit_Entry::$file + ); + + $this->assertEquals( $expected, $template_paths ); + } + + /** + * @covers GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view_id = 0 ) + */ + public function test_check_user_cap_edit_entry() { + + $form = $this->factory->form->create_and_get(); + + $view_user_edit_enabled = $this->factory->view->create_and_get(array( + 'form_id' => $form['id'], + 'settings' => array( + 'user_edit' => 1 + ), + )); + + $view_user_edit_disabled = $this->factory->view->create_and_get(array( + 'form_id' => $form['id'], + 'settings' => array( + 'user_edit' => 0 + ), + )); + + $author_id = $this->factory->user->create( array( + 'user_login' => 'author', + 'role' => 'author' + ) ); + + $subscriber_id = $this->factory->user->create( array( + 'user_login' => 'subscriber', + 'role' => 'subscriber' + ) ); + + $contributor_id = $this->factory->user->create( array( + 'user_login' => 'contributor', + 'role' => 'contributor' + ) ); + + $editor_id = $this->factory->user->create( array( + 'user_login' => 'editor', + 'role' => 'editor' + ) ); + + $entry = $this->factory->entry->create_and_get( array( + 'form_id' => $form['id'], + 'created_by' => $editor_id + ) ); + + ##### + ##### Test Entry with "Created By" + ##### + + $this->factory->user->set( $editor_id ); + + // User Edit Enabled + $this->assertTrue( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view_user_edit_enabled->ID ) ); + + // User Edit Disabled + $this->assertFalse( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view_user_edit_disabled->ID ) ); + + /** @var WP_User $admin */ + $admin = $this->factory->user->create_and_get( array( + 'user_login' => 'admin', + 'role' => 'administrator' + ) ); + + $admin->add_cap('gravityforms_edit_entries'); + + $admin_id = $admin->ID; + + ##### + ##### Test Admin always being able to edit + ##### + + $this->factory->user->set( $admin_id ); + + // Admin always can edit + $this->assertTrue( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view_user_edit_enabled->ID ) ); + + // Admin always can edit + $this->assertTrue( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view_user_edit_disabled->ID ) ); + + ##### + ##### Test Entry _without_ "Created By" + ##### + + $entry_without_created_by = $this->factory->entry->create_and_get( array( + 'form_id' => $form['id'], + 'created_by' => $editor_id + ) ); + + unset( $entry_without_created_by['created_by'] ); + + $this->factory->user->set( $admin_id ); + + // Admin always can edit, even without "created_by" + $this->assertTrue( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry_without_created_by, $view_user_edit_disabled->ID ) ); + + $this->factory->user->set( $editor_id ); + + $this->assertFalse( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry_without_created_by, $view->ID ) ); + + ##### + ##### Test TRUE Filter + ##### + + add_filter( 'gravityview/edit_entry/user_can_edit_entry', '__return_true' ); + + // Should be true anyway + $this->factory->user->set( $admin_id ); + $this->assertTrue( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view->ID ) ); + $this->assertTrue( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry_without_created_by, $view->ID ) ); + + // Should be false, but we have filter set to true + $this->factory->user->set( $editor_id ); + $this->assertTrue( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry_without_created_by, $view->ID ) ); + $this->assertTrue( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view->ID ) ); + + // Should be false, but we have filter set to true + $this->factory->user->set( $contributor_id ); + $this->assertTrue( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view->ID ) ); + $this->assertTrue( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry_without_created_by, $view->ID ) ); + + remove_filter( 'gravityview/edit_entry/user_can_edit_entry', '__return_true' ); + + + ##### + ##### Test FALSE Filter + ##### + + add_filter( 'gravityview/edit_entry/user_can_edit_entry', '__return_false' ); + + // Should be true but the filter is set to false + $this->factory->user->set( $admin_id ); + $this->assertFalse( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view->ID ) ); + $this->assertFalse( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry_without_created_by, $view->ID ) ); + + // Should be true, but we have filter set to false + $this->factory->user->set( $editor_id ); + $this->assertFalse( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view->ID ) ); + + // Should be false, and we have filter set to false + $this->factory->user->set( $contributor_id ); + $this->assertFalse( GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view->ID ) ); + + remove_filter( 'gravityview/edit_entry/user_can_edit_entry', '__return_false' ); + + } + + /** + * @covers GravityView_Edit_Entry::get_nonce_key() + */ + public function test_get_nonce_key() { + + $view_id = 1; + $form_id = 2; + $entry_id = 3; + + $nonce_key = GravityView_Edit_Entry::get_nonce_key( $view_id, $form_id, $entry_id ); + + $this->assertEquals( $nonce_key, sprintf( 'edit_%d_%d_%d', $view_id, $form_id, $entry_id ) ); + + } + + +} From ef6f6f4850ee34a8c440ecdcea5d65bf38316e9c Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 29 Sep 2015 15:30:58 -0600 Subject: [PATCH 19/21] Improve docblocks --- .../extensions/edit-entry/class-edit-entry.php | 15 +++++++++------ tests/factory.php | 11 +++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/includes/extensions/edit-entry/class-edit-entry.php b/includes/extensions/edit-entry/class-edit-entry.php index 39c94f5fd0..4e30c15916 100644 --- a/includes/extensions/edit-entry/class-edit-entry.php +++ b/includes/extensions/edit-entry/class-edit-entry.php @@ -65,7 +65,7 @@ static function getInstance() { } - function load_components( $component ) { + private function load_components( $component ) { $dir = trailingslashit( self::$file ); @@ -111,7 +111,7 @@ private function addon_specific_hooks() { * Include this extension templates path * @param array $file_paths List of template paths ordered */ - function add_template_path( $file_paths ) { + public function add_template_path( $file_paths ) { // Index 100 is the default GravityView template path. $file_paths[ 110 ] = self::$file; @@ -128,7 +128,7 @@ function add_template_path( $file_paths ) { * @param $entry_id int Gravity Forms entry id * @return string */ - static function get_nonce_key( $view_id, $form_id, $entry_id ) { + public static function get_nonce_key( $view_id, $form_id, $entry_id ) { return sprintf( 'edit_%d_%d_%d', $view_id, $form_id, $entry_id ); } @@ -146,7 +146,7 @@ static function get_nonce_key( $view_id, $form_id, $entry_id ) { * @param string|array $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" {@since 1.9.2} {@see https://www.gravityhelp.com/documentation/article/allow-field-to-be-populated-dynamically/ } * @return string */ - static function get_edit_link( $entry, $view_id, $post_id = null, $field_values = '' ) { + public static function get_edit_link( $entry, $view_id, $post_id = null, $field_values = '' ) { $nonce_key = self::get_nonce_key( $view_id, $entry['form_id'], $entry['id'] ); @@ -268,9 +268,12 @@ public static function check_user_cap_edit_entry( $entry, $view_id = 0 ) { } /** - * @param boolean $user_can_edit Can the current user edit the current entry? (Default: false) + * @filter `gravityview/edit_entry/user_can_edit_entry` Modify whether user can edit an entry. + * @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} */ - $user_can_edit = apply_filters( 'gravityview/edit_entry/user_can_edit_entry', $user_can_edit ); + $user_can_edit = apply_filters( 'gravityview/edit_entry/user_can_edit_entry', $user_can_edit, $entry, $view_id ); return (bool)$user_can_edit; } diff --git a/tests/factory.php b/tests/factory.php index 8a7a6e21b4..2d498c7c17 100644 --- a/tests/factory.php +++ b/tests/factory.php @@ -28,6 +28,7 @@ function __construct() { $this->user = new GV_UnitTest_Factory_For_User( $this ); $this->entry = new GF_UnitTest_Factory_For_Entry( $this ); + $this->form = new GF_UnitTest_Factory_For_Form( $this ); $this->view = new GV_UnitTest_Factory_For_View( $this ); @@ -129,8 +130,13 @@ function set( $user_id ) { class GF_UnitTest_Factory_For_Entry extends WP_UnitTest_Factory_For_Thing { + /** + * @param GF_UnitTest_Factory $factory + */ function __construct( $factory = null ) { + parent::__construct( $factory ); + $this->default_generation_definitions = array( '1' => 'Value for field one', '2' => 'Value for field two', @@ -169,8 +175,13 @@ function update_object( $entry_id = '', $entry = array() ) { class GF_UnitTest_Factory_For_Form extends WP_UnitTest_Factory_For_Thing { + /** + * @param GF_UnitTest_Factory $factory + */ function __construct( $factory = null ) { + parent::__construct( $factory ); + $this->default_generation_definitions = array( 'title' => new WP_UnitTest_Generator_Sequence( 'Form Title %s' ), 'fields' => array( From f9535f3bffc7c3e522b799efffc0652732e42d24 Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 29 Sep 2015 16:03:27 -0600 Subject: [PATCH 20/21] Try to fix build --- tests/bin/install.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bin/install.sh b/tests/bin/install.sh index 1c24192c1f..a8c913b9e5 100755 --- a/tests/bin/install.sh +++ b/tests/bin/install.sh @@ -84,8 +84,8 @@ install_db() { # Create xdebug log, if not correctly installed by Vagrant # See https://github.com/Varying-Vagrant-Vagrants/VVV/issues/621 fix_vagrant_permissions() { - sudo touch /tmp/xdebug-remote.log; - sudo chmod 666 /tmp/xdebug-remote.log; + touch /tmp/xdebug-remote.log; + chmod 666 /tmp/xdebug-remote.log; } install_wp From 9900e392401bca5cb7b63f6286b97f193d0ad5ae Mon Sep 17 00:00:00 2001 From: Zack Katz Date: Tue, 29 Sep 2015 16:06:21 -0600 Subject: [PATCH 21/21] Fix `Trying to @cover or @use not existing method "GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view_id = 0)` --- tests/unit-tests/GravityView_Edit_Entry_Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit-tests/GravityView_Edit_Entry_Test.php b/tests/unit-tests/GravityView_Edit_Entry_Test.php index 612ed86961..f1ec35a8db 100644 --- a/tests/unit-tests/GravityView_Edit_Entry_Test.php +++ b/tests/unit-tests/GravityView_Edit_Entry_Test.php @@ -124,7 +124,7 @@ public function test_add_template_path() { } /** - * @covers GravityView_Edit_Entry::check_user_cap_edit_entry( $entry, $view_id = 0 ) + * @covers GravityView_Edit_Entry::check_user_cap_edit_entry() */ public function test_check_user_cap_edit_entry() {