Completed
Push — develop ( 6c202f...281de0 )
by Zack
04:23
created

GravityView_Edit_Entry   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 288
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 288
rs 10
c 0
b 0
f 0
wmc 27
lcom 2
cbo 2

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 19 2
A getInstance() 0 8 2
A load_components() 0 14 1
A add_hooks() 0 14 1
A addon_specific_hooks() 0 7 3
A add_template_path() 0 7 1
A get_nonce_key() 0 3 1
B get_edit_link() 0 30 3
A modify_field_blacklist() 0 10 3
A get_field_blacklist() 0 22 1
C check_user_cap_edit_entry() 0 66 9
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 19 and the first side effect is on line 15.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * The GravityView Edit Entry Extension
4
 *
5
 * Easily edit entries in GravityView.
6
 *
7
 * @package   GravityView
8
 * @license   GPL2+
9
 * @author    Katz Web Services, Inc.
10
 * @link      http://gravityview.co
11
 * @copyright Copyright 2014, Katz Web Services, Inc.
12
 */
13
14
if ( ! defined( 'WPINC' ) ) {
15
	die;
16
}
17
18
19
class GravityView_Edit_Entry {
20
21
    /**
22
     * @var string
23
     */
24
	static $file;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $file.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
25
26
	static $instance;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $instance.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
27
28
    /**
29
     * Component instances.
30
     * @var array
31
     */
32
    public $instances = array();
33
34
35
	function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
36
37
        self::$file = plugin_dir_path( __FILE__ );
38
39
        if( is_admin() ) {
40
            $this->load_components( 'admin' );
41
        }
42
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
43
44
        $this->load_components( 'render' );
45
46
        // If GF User Registration Add-on exists
47
        $this->load_components( 'user-registration' );
48
49
        $this->add_hooks();
50
51
		// Process hooks for addons that may or may not be present
52
		$this->addon_specific_hooks();
53
	}
54
55
56
    static function getInstance() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Coding Style introduced by
The function name getInstance is in camel caps, but expected get_instance instead as per the coding standard.
Loading history...
57
58
        if( empty( self::$instance ) ) {
59
            self::$instance = new GravityView_Edit_Entry;
60
        }
61
62
        return self::$instance;
63
    }
64
65
66
    private function load_components( $component ) {
67
68
        $dir = trailingslashit( self::$file );
69
70
        $filename  = $dir . 'class-edit-entry-' . $component . '.php';
71
        $classname = 'GravityView_Edit_Entry_' . str_replace( ' ', '_', ucwords( str_replace( '-', ' ', $component ) ) );
72
73
        // Loads component and pass extension's instance so that component can
74
        // talk each other.
75
        require_once $filename;
76
        $this->instances[ $component ] = new $classname( $this );
77
        $this->instances[ $component ]->load();
78
79
    }
80
81
    private function add_hooks() {
82
83
        // Add front-end access to Gravity Forms delete file action
84
        add_action( 'wp_ajax_nopriv_rg_delete_file', array( 'RGForms', 'delete_file') );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
85
86
        // Make sure this hook is run for non-admins
87
        add_action( 'wp_ajax_rg_delete_file', array( 'RGForms', 'delete_file') );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
88
89
        add_filter( 'gravityview_blacklist_field_types', array( $this, 'modify_field_blacklist' ), 10, 2 );
90
91
        // add template path to check for field
92
        add_filter( 'gravityview_template_paths', array( $this, 'add_template_path' ) );
93
94
    }
95
96
	/**
97
	 * Trigger hooks that are normally run in the admin for Addons, but need to be triggered manually because we're not in the admin
98
	 * @return void
99
	 */
100
	private function addon_specific_hooks() {
101
102
		if( class_exists( 'GFSignature' ) && is_callable( array( 'GFSignature', 'get_instance' ) ) ) {
103
			add_filter('gform_admin_pre_render', array( GFSignature::get_instance(), 'edit_lead_script'));
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
introduced by
No space before closing parenthesis of array is bad style
Loading history...
104
		}
105
106
	}
107
108
    /**
109
     * Include this extension templates path
110
     * @param array $file_paths List of template paths ordered
111
     */
112
    public function add_template_path( $file_paths ) {
113
114
        // Index 100 is the default GravityView template path.
115
        $file_paths[ 110 ] = self::$file;
0 ignored issues
show
introduced by
Array keys should NOT be surrounded by spaces if they only contain a string or an integer.
Loading history...
116
117
        return $file_paths;
118
    }
119
120
    /**
121
     *
122
     * Return a well formatted nonce key according to GravityView Edit Entry protocol
123
     *
124
     * @param $view_id int GravityView view id
125
     * @param $form_id int Gravity Forms form id
126
     * @param $entry_id int Gravity Forms entry id
127
     * @return string
128
     */
129
    public static function get_nonce_key( $view_id, $form_id, $entry_id ) {
130
        return sprintf( 'edit_%d_%d_%d', $view_id, $form_id, $entry_id );
131
    }
132
133
134
    /**
135
     * The edit entry link creates a secure link with a nonce
136
     *
137
     * It also mimics the URL structure Gravity Forms expects to have so that
138
     * it formats the display of the edit form like it does in the backend, like
139
     * "You can edit this post from the post page" fields, for example.
140
     *
141
     * @param $entry array Gravity Forms entry object
142
     * @param $view_id int GravityView view id
143
     * @param $post_id int GravityView Post ID where View may be embedded {@since 1.9.2}
144
     * @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/ }
145
     * @return string
146
     */
147
    public static function get_edit_link( $entry, $view_id, $post_id = null, $field_values = '' ) {
148
149
        $nonce_key = self::get_nonce_key( $view_id, $entry['form_id'], $entry['id']  );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 2 found
Loading history...
150
151
        $base = gv_entry_link( $entry, $post_id );
152
153
        $url = add_query_arg( array(
154
            'page' => 'gf_entries', // Needed for GFForms::get_page()
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
155
            'view' => 'entry', // Needed for GFForms::get_page()
0 ignored issues
show
Unused Code Comprehensibility introduced by
40% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
156
            'edit' => wp_create_nonce( $nonce_key )
157
        ), $base );
158
159
	    /**
160
	     * Allow passing params to dynamically populate entry with values
161
	     * @since 1.9.2
162
	     */
163
	    if( !empty( $field_values ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
164
165
		    if( is_array( $field_values ) ) {
166
			    // If already an array, no parse_str() needed
167
			    $params = $field_values;
168
		    } else {
169
			    parse_str( $field_values, $params );
170
		    }
171
172
		    $url = add_query_arg( $params, $url );
173
	    }
174
175
        return $url;
176
    }
177
178
	/**
179
	 * Edit mode doesn't allow certain field types.
180
	 * @param  array $fields  Existing blacklist fields
181
	 * @param  string|null $context Context
182
	 * @return array          If not edit context, original field blacklist. Otherwise, blacklist including post fields.
183
	 */
184
	public function modify_field_blacklist( $fields = array(), $context = NULL ) {
0 ignored issues
show
Coding Style introduced by
TRUE, FALSE and NULL must be lowercase; expected null, but found NULL.
Loading history...
185
186
		if( empty( $context ) || $context !== 'edit' ) {
0 ignored issues
show
introduced by
Found "!== '". Use Yoda Condition checks, you must
Loading history...
187
			return $fields;
188
		}
189
190
		$add_fields = $this->get_field_blacklist();
191
192
		return array_merge( $fields, $add_fields );
193
	}
194
195
	/**
196
	 * Returns array of field types that should not be displayed in Edit Entry
197
	 *
198
	 * @since 1.20
199
	 *
200
	 * @param array $entry Gravity Forms entry array
201
	 *
202
	 * @return array Blacklist of field types
203
	 */
204
	function get_field_blacklist( $entry = array() ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
205
206
		$fields = array(
207
			'page',
208
			'payment_status',
209
			'payment_date',
210
			'payment_amount',
211
			'is_fulfilled',
212
			'transaction_id',
213
			'transaction_type',
214
		);
215
216
		/**
217
		 * @filter `gravityview/edit_entry/field_blacklist` Array of fields that should not be displayed in Edit Entry
218
		 * @since 1.20
219
		 * @param array $fields Blacklist field type array
220
		 * @param array $entry Gravity Forms entry array
221
		 */
222
		$fields = apply_filters( 'gravityview/edit_entry/field_blacklist', $fields, $entry );
223
224
		return $fields;
225
	}
226
227
228
    /**
229
     * checks if user has permissions to edit a specific entry
230
     *
231
     * Needs to be used combined with GravityView_Edit_Entry::user_can_edit_entry for maximum security!!
232
     *
233
     * @param  array $entry Gravity Forms entry array
234
     * @param int $view_id ID of the view you want to check visibility against {@since 1.9.2}
235
     * @return bool
236
     */
237
    public static function check_user_cap_edit_entry( $entry, $view_id = 0 ) {
238
239
        // No permission by default
240
        $user_can_edit = false;
241
242
        // If they can edit any entries (as defined in Gravity Forms)
243
        // Or if they can edit other people's entries
244
        // Then we're good.
245
        if( GVCommon::has_cap( array( 'gravityforms_edit_entries', 'gravityview_edit_others_entries' ), $entry['id'] ) ) {
246
247
            do_action('gravityview_log_debug', __METHOD__ . ' - User has ability to edit all entries.');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
248
249
            $user_can_edit = true;
250
251
        } else if( !isset( $entry['created_by'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
252
253
            do_action('gravityview_log_error', 'GravityView_Edit_Entry[check_user_cap_edit_entry] Entry `created_by` doesn\'t exist.');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
254
255
            $user_can_edit = false;
256
257
        } else {
258
259
            // get user_edit setting
260
            if( empty( $view_id ) || $view_id == GravityView_View::getInstance()->getViewId() ) {
261
                // if View ID not specified or is the current view
262
                $user_edit = GravityView_View::getInstance()->getAtts('user_edit');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
263
            } else {
264
                // in case is specified and not the current view
265
                $user_edit = GVCommon::get_template_setting( $view_id, 'user_edit' );
266
            }
267
268
            $current_user = wp_get_current_user();
269
270
            // User edit is disabled
271
            if( empty( $user_edit ) ) {
272
273
                do_action('gravityview_log_debug', 'GravityView_Edit_Entry[check_user_cap_edit_entry] User Edit is disabled. Returning false.' );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
274
275
                $user_can_edit = false;
276
            }
277
278
            // User edit is enabled and the logged-in user is the same as the user who created the entry. We're good.
279
            else if( is_user_logged_in() && intval( $current_user->ID ) === intval( $entry['created_by'] ) ) {
280
281
                do_action('gravityview_log_debug', sprintf( 'GravityView_Edit_Entry[check_user_cap_edit_entry] User %s created the entry.', $current_user->ID ) );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
282
283
                $user_can_edit = true;
284
285
            } else if( ! is_user_logged_in() ) {
286
287
                do_action( 'gravityview_log_debug', __METHOD__ . ' No user defined; edit entry requires logged in user' );
288
            }
289
290
        }
291
292
        /**
293
         * @filter `gravityview/edit_entry/user_can_edit_entry` Modify whether user can edit an entry.
294
         * @since 1.15 Added `$entry` and `$view_id` parameters
295
         * @param[in,out] boolean $user_can_edit Can the current user edit the current entry? (Default: false)
296
         * @param[in] array $entry Gravity Forms entry array {@since 1.15}
297
         * @param[in] int $view_id ID of the view you want to check visibility against {@since 1.15}
298
         */
299
        $user_can_edit = apply_filters( 'gravityview/edit_entry/user_can_edit_entry', $user_can_edit, $entry, $view_id );
300
301
        return (bool)$user_can_edit;
0 ignored issues
show
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
302
    }
303
304
305
306
} // end class
307
308
//add_action( 'plugins_loaded', array('GravityView_Edit_Entry', 'getInstance'), 6 );
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
309
GravityView_Edit_Entry::getInstance();
310
311