Completed
Push — develop ( 128834...24c11c )
by Zack
21:52 queued 17:30
created

GravityView_Edit_Entry::get_edit_link()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5.583

Importance

Changes 0
Metric Value
cc 5
nc 6
nop 4
dl 0
loc 32
ccs 10
cts 14
cp 0.7143
crap 5.583
rs 9.0968
c 0
b 0
f 0
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 3
	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 3
        self::$file = plugin_dir_path( __FILE__ );
38
39 3
        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 3
        $this->load_components( 'render' );
45
46
        // If GF User Registration Add-on exists
47 3
        $this->load_components( 'user-registration' );
48
49 3
        $this->add_hooks();
50
51
		// Process hooks for addons that may or may not be present
52 3
		$this->addon_specific_hooks();
53 3
	}
54
55
56 4
    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 4
        if( empty( self::$instance ) ) {
59 3
            self::$instance = new GravityView_Edit_Entry;
60
        }
61
62 4
        return self::$instance;
63
    }
64
65
66 3
    private function load_components( $component ) {
67
68 3
        $dir = trailingslashit( self::$file );
69
70 3
        $filename  = $dir . 'class-edit-entry-' . $component . '.php';
71 3
        $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 3
        require_once $filename;
76 3
        $this->instances[ $component ] = new $classname( $this );
77 3
        $this->instances[ $component ]->load();
78
79 3
    }
80
81 3
    private function add_hooks() {
82
83
        // Add front-end access to Gravity Forms delete file action
84 3
        add_action( 'wp_ajax_nopriv_rg_delete_file', array( 'GFForms', '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 3
        add_action( 'wp_ajax_rg_delete_file', array( 'GFForms', 'delete_file') );
0 ignored issues
show
introduced by
No space before closing parenthesis of array is bad style
Loading history...
88
89 3
        add_filter( 'gravityview_blacklist_field_types', array( $this, 'modify_field_blacklist' ), 10, 2 );
90
91
        // add template path to check for field
92 3
        add_filter( 'gravityview_template_paths', array( $this, 'add_template_path' ) );
93
94 3
    }
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 3
	private function addon_specific_hooks() {
101
102 3
		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 3
	}
107
108
    /**
109
     * Include this extension templates path
110
     * @param array $file_paths List of template paths ordered
111
     */
112 25
    public function add_template_path( $file_paths ) {
113
114
        // Index 100 is the default GravityView template path.
115 25
        $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 25
        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 5
    public static function get_nonce_key( $view_id, $form_id, $entry_id ) {
130 5
        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 3
    public static function get_edit_link( $entry, $view_id, $post_id = null, $field_values = '' ) {
148
149 3
        $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 3
        $base = gv_entry_link( $entry, $post_id ? : $view_id  );
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 2 found
Loading history...
152
153 3
        $url = add_query_arg( array(
154 3
            'edit' => wp_create_nonce( $nonce_key )
155 3
        ), $base );
156
157 3
        if( $post_id ) {
158 2
	        $url = add_query_arg( array( 'gvid' => $view_id ), $url );
159
        }
160
161
	    /**
162
	     * Allow passing params to dynamically populate entry with values
163
	     * @since 1.9.2
164
	     */
165 3
	    if( !empty( $field_values ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
166
167
		    if( is_array( $field_values ) ) {
168
			    // If already an array, no parse_str() needed
169
			    $params = $field_values;
170
		    } else {
171
			    parse_str( $field_values, $params );
172
		    }
173
174
		    $url = add_query_arg( $params, $url );
175
	    }
176
177 3
        return $url;
178
    }
179
180
	/**
181
	 * Edit mode doesn't allow certain field types.
182
	 * @param  array $fields  Existing blacklist fields
183
	 * @param  string|null $context Context
184
	 * @return array          If not edit context, original field blacklist. Otherwise, blacklist including post fields.
185
	 */
186
	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...
187
188
		if( empty( $context ) || $context !== 'edit' ) {
0 ignored issues
show
introduced by
Found "!== '". Use Yoda Condition checks, you must
Loading history...
189
			return $fields;
190
		}
191
192
		$add_fields = $this->get_field_blacklist();
193
194
		return array_merge( $fields, $add_fields );
195
	}
196
197
	/**
198
	 * Returns array of field types that should not be displayed in Edit Entry
199
	 *
200
	 * @since 1.20
201
	 *
202
	 * @param array $entry Gravity Forms entry array
203
	 *
204
	 * @return array Blacklist of field types
205
	 */
206 3
	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...
207
208
		$fields = array(
209 3
			'page',
210
			'payment_status',
211
			'payment_date',
212
			'payment_amount',
213
			'is_fulfilled',
214
			'transaction_id',
215
			'transaction_type',
216
			'captcha',
217
			'honeypot',
218
		);
219
220
		/**
221
		 * @filter `gravityview/edit_entry/field_blacklist` Array of fields that should not be displayed in Edit Entry
222
		 * @since 1.20
223
		 * @param array $fields Blacklist field type array
224
		 * @param array $entry Gravity Forms entry array
225
		 */
226 3
		$fields = apply_filters( 'gravityview/edit_entry/field_blacklist', $fields, $entry );
227
228 3
		return $fields;
229
	}
230
231
232
    /**
233
     * checks if user has permissions to edit a specific entry
234
     *
235
     * Needs to be used combined with GravityView_Edit_Entry::user_can_edit_entry for maximum security!!
236
     *
237
     * @param  array $entry Gravity Forms entry array
238
     * @param int $view_id ID of the view you want to check visibility against {@since 1.9.2}. Required since 2.0
239
     * @return bool
240
     */
241 5
    public static function check_user_cap_edit_entry( $entry, $view_id = 0 ) {
242
243
        // No permission by default
244 5
        $user_can_edit = false;
245
246
        // If they can edit any entries (as defined in Gravity Forms)
247
        // Or if they can edit other people's entries
248
        // Then we're good.
249 5
        if( GVCommon::has_cap( array( 'gravityforms_edit_entries', 'gravityview_edit_others_entries' ), $entry['id'] ) ) {
250
251 5
            gravityview()->log->debug( 'User has ability to edit all entries.' );
252
253 5
            $user_can_edit = true;
254
255 2
        } else if( !isset( $entry['created_by'] ) ) {
0 ignored issues
show
introduced by
Expected 1 space after "!"; 0 found
Loading history...
256
257 1
            gravityview()->log->error( 'Entry `created_by` doesn\'t exist.');
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
258
259 1
            $user_can_edit = false;
260
261
        } else {
262
263
            // get user_edit setting
264 2
            if( empty( $view_id ) || $view_id == GravityView_View::getInstance()->getViewId() ) {
265
                // if View ID not specified or is the current view
266
				// @deprecated path
267
                $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...
268
            } else {
269
                // in case is specified and not the current view
270 2
                $user_edit = GVCommon::get_template_setting( $view_id, 'user_edit' );
271
            }
272
273 2
            $current_user = wp_get_current_user();
274
275
            // User edit is disabled
276 2
            if( empty( $user_edit ) ) {
277
278 2
                gravityview()->log->debug( 'User Edit is disabled. Returning false.' );
279
280 2
                $user_can_edit = false;
281
            }
282
283
            // User edit is enabled and the logged-in user is the same as the user who created the entry. We're good.
284 1
            else if( is_user_logged_in() && intval( $current_user->ID ) === intval( $entry['created_by'] ) ) {
285
286 1
                gravityview()->log->debug( 'User {user_id} created the entry.', array( 'user_id', $current_user->ID ) );
287
288 1
                $user_can_edit = true;
289
290 1
            } else if( ! is_user_logged_in() ) {
291
292
                gravityview()->log->debug( 'No user defined; edit entry requires logged in user' );
293
            }
294
295
        }
296
297
        /**
298
         * @filter `gravityview/edit_entry/user_can_edit_entry` Modify whether user can edit an entry.
299
         * @since 1.15 Added `$entry` and `$view_id` parameters
300
         * @param[in,out] boolean $user_can_edit Can the current user edit the current entry? (Default: false)
301
         * @param[in] array $entry Gravity Forms entry array {@since 1.15}
302
         * @param[in] int $view_id ID of the view you want to check visibility against {@since 1.15}
303
         */
304 5
        $user_can_edit = apply_filters( 'gravityview/edit_entry/user_can_edit_entry', $user_can_edit, $entry, $view_id );
305
306 5
        return (bool)$user_can_edit;
0 ignored issues
show
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
307
    }
308
309
310
311
} // end class
312
313
//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...
314
GravityView_Edit_Entry::getInstance();
315
316