GravityView  2.17
The best, easiest way to display Gravity Forms entries on your website.
class-edit-entry-locking.php
Go to the documentation of this file.
1 <?php
2 
3 /** If this file is called directly, abort. */
4 if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
5  die();
6 }
7 
8 /**
9  * An entry locking class that syncs with GFEntryLocking.
10  *
11  * @since 2.5.2
12  */
14 
15  /**
16  * Load extension entry point.
17  *
18  * DO NOT RENAME this method. Required by the class-edit-entry.php component loader.
19  * @see GravityView_Edit_Entry::load_components()
20  *
21  * @since 2.5.2
22  *
23  * @return void
24  */
25  public function load() {
26  if ( ! has_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue_scripts' ) ) ) {
27  add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue_scripts' ) );
28  }
29 
30  add_action( 'wp_ajax_gf_lock_request_entry', array( $this, 'ajax_lock_request' ), 1 );
31  add_action( 'wp_ajax_gf_reject_lock_request_entry', array( $this, 'ajax_reject_lock_request' ), 1 );
32  add_action( 'wp_ajax_nopriv_gf_lock_request_entry', array( $this, 'ajax_lock_request' ) );
33  add_action( 'wp_ajax_nopriv_gf_reject_lock_request_entry', array( $this, 'ajax_reject_lock_request' ) );
34  }
35 
36  // TODO: Convert to extending Gravity Forms
37  public function ajax_lock_request() {
38  $object_id = rgget( 'object_id' );
39  $response = $this->request_lock( $object_id );
40  echo json_encode( $response );
41  die();
42  }
43 
44  // TODO: Convert to extending Gravity Forms
45  public function ajax_reject_lock_request() {
46  $object_id = rgget( 'object_id' );
47  $response = $this->delete_lock_request_meta( $object_id );
48  echo json_encode( $response );
49  die();
50  }
51 
52  // TODO: Convert to extending Gravity Forms
53  protected function delete_lock_request_meta( $object_id ) {
54  GFCache::delete( 'lock_request_entry_' . $object_id );
55 
56  return true;
57  }
58 
59  // TODO: Convert to extending Gravity Forms
60  protected function request_lock( $object_id ) {
61  if ( 0 == ( $user_id = get_current_user_id() ) ) {
62  return false;
63  }
64 
65  $lock_holder_user_id = $this->check_lock( $object_id );
66 
67  $result = array();
68  if ( ! $lock_holder_user_id ) {
69  $this->set_lock( $object_id );
70  $result['html'] = __( 'You now have control', 'gk-gravityview' );
71  $result['status'] = 'lock_obtained';
72  } else {
73 
74  if( GVCommon::has_cap( 'gravityforms_edit_entries' ) ) {
75  $user = get_userdata( $lock_holder_user_id );
76  $result['html'] = sprintf( __( 'Your request has been sent to %s.', 'gk-gravityview' ), $user->display_name );
77  } else {
78  $result['html'] = __( 'Your request has been sent.', 'gk-gravityview' );
79  }
80 
81  $this->update_lock_request_meta( $object_id, $user_id );
82 
83  $result['status'] = 'lock_requested';
84  }
85 
86  return $result;
87  }
88 
89  protected function update_lock_request_meta( $object_id, $lock_request_value ) {
90  GFCache::set( 'lock_request_entry_' . $object_id, $lock_request_value, true, 120 );
91  }
92 
93  /**
94  * Checks whether to enqueue scripts based on:
95  *
96  * - Is it Edit Entry?
97  * - Is the entry connected to a View that has `edit_locking` enabled?
98  * - Is the entry connected to a form connected to a currently-loaded View?
99  *
100  * @internal
101  * @since 2.7
102  *
103  * @global WP_Post $post
104  *
105  * @return void
106  */
107  public function maybe_enqueue_scripts() {
108  global $post;
109 
110  if ( ! $entry = gravityview()->request->is_edit_entry() ) {
111  return;
112  }
113 
114  if ( ! $post || ! is_a( $post, 'WP_Post' ) ) {
115  return;
116  }
117 
118  $views = \GV\View_Collection::from_post( $post );
119 
120  $entry_array = $entry->as_entry();
121 
122  $continue_enqueuing = false;
123 
124  // If any Views being loaded have entry locking, enqueue the scripts
125  foreach( $views->all() as $view ) {
126 
127  // Make sure the View has edit locking enabled
128  if( ! $view->settings->get( 'edit_locking' ) ) {
129  continue;
130  }
131 
132  // Make sure that the entry belongs to one of the forms connected to one of the Views in this request
133  $joined_forms = $view::get_joined_forms( $view->ID );
134 
135  $entry_form_id = $entry_array['form_id'];
136 
137  if( ! isset( $joined_forms[ $entry_form_id ] ) ) {
138  continue;
139  }
140 
141  $continue_enqueuing = true;
142 
143  break;
144  }
145 
146  if( ! $continue_enqueuing ) {
147  return;
148  }
149 
150  $this->enqueue_scripts( $entry_array );
151  }
152 
153  /**
154  * Enqueue the required scripts and styles from Gravity Forms.
155  *
156  * Called via load() and `wp_enqueue_scripts`
157  *
158  * @since 2.5.2
159  *
160  * @param array $entry Gravity Forms entry array
161  *
162  * @return void
163  */
164  protected function enqueue_scripts( $entry ) {
165 
166  $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG || isset( $_GET['gform_debug'] ) ? '' : '.min';
167  $locking_path = GFCommon::get_base_url() . '/includes/locking/';
168 
169  wp_enqueue_script( 'gforms_locking', $locking_path . "js/locking{$min}.js", array( 'jquery', 'heartbeat' ), GFCommon::$version );
170  wp_enqueue_style( 'gforms_locking_css', $locking_path . "css/locking{$min}.css", array( 'edit' ), GFCommon::$version );
171 
172  $translations = array_map( 'wp_strip_all_tags', $this->get_strings() );
173 
174  $strings = array(
175  'noResponse' => $translations['no_response'],
176  'requestAgain' => $translations['request_again'],
177  'requestError' => $translations['request_error'],
178  'gainedControl' => $translations['gained_control'],
179  'rejected' => $translations['request_rejected'],
180  'pending' => $translations['request_pending'],
181  );
182 
183  $lock_user_id = $this->check_lock( $entry['id'] );
184 
185  $vars = array(
186  'hasLock' => ! $lock_user_id ? 1 : 0,
187  'lockUI' => $this->get_lock_ui( $lock_user_id ),
188  'objectID' => $entry['id'],
189  'objectType' => 'entry',
190  'strings' => $strings,
191  );
192 
193  wp_localize_script( 'gforms_locking', 'gflockingVars', $vars );
194  }
195 
196  /**
197  * Returns a string with the Lock UI HTML markup.
198  *
199  * Called script enqueuing, added to JavaScript gforms_locking global variable.
200  *
201  * @since 2.5.2
202  *
203  * @see GravityView_Edit_Entry_Locking::check_lock
204  *
205  * @param int $user_id The User ID that has the current lock. Will be empty if entry is not locked
206  * or is locked to the current user.
207  *
208  * @return string The Lock UI dialog box, etc.
209  */
210  public function get_lock_ui( $user_id ) {
211  $user = get_userdata( $user_id );
212 
213  $locked = $user_id && $user;
214 
215  $hidden = $locked ? '' : ' hidden';
216  if ( $locked ) {
217 
218  if( GVCommon::has_cap( 'gravityforms_edit_entries' ) ) {
219  $avatar = get_avatar( $user->ID, 64 );
220  $person_editing_text = $user->display_name;
221  } else {
222  $current_user = wp_get_current_user();
223  $avatar = get_avatar( $current_user->ID, 64 );
224  $person_editing_text = _x( 'the person who is editing the entry', 'Referring to the user who is currently editing a locked entry', 'gk-gravityview' );
225  }
226 
227  $message = '<div class="gform-locked-message">
228  <div class="gform-locked-avatar">' . $avatar . '</div>
229  <p class="currently-editing" tabindex="0">' . esc_html( sprintf( $this->get_string( 'currently_locked' ), $person_editing_text ) ) . '</p>
230  <p>
231 
232  <a id="gform-take-over-button" style="display:none" class="button button-primary wp-tab-first" href="' . esc_url( add_query_arg( 'get-edit-lock', '1' ) ) . '">' . esc_html__( 'Take Over', 'gk-gravityview' ) . '</a>
233  <button id="gform-lock-request-button" class="button button-primary wp-tab-last">' . esc_html__( 'Request Control', 'gk-gravityview' ) . '</button>
234  <a class="button" onclick="history.back(-1); return false;">' . esc_html( $this->get_string( 'cancel' ) ) . '</a>
235  </p>
236  <div id="gform-lock-request-status">
237  <!-- placeholder -->
238  </div>
239  </div>';
240 
241  } else {
242 
243  $message = '<div class="gform-taken-over">
244  <div class="gform-locked-avatar"></div>
245  <p class="wp-tab-first" tabindex="0">
246  <span class="currently-editing"></span><br>
247  </p>
248  <p>
249  <a id="gform-release-lock-button" class="button button-primary wp-tab-last" href="' . esc_url( add_query_arg( 'release-edit-lock', '1' ) ) . '">' . esc_html( $this->get_string( 'accept' ) ) . '</a>
250  <button id="gform-reject-lock-request-button" style="display:none" class="button button-primary wp-tab-last">' . esc_html__( 'Reject Request', 'gk-gravityview' ) . '</button>
251  </p>
252  </div>';
253 
254  }
255  $html = '<div id="gform-lock-dialog" class="notification-dialog-wrap' . $hidden . '">
256  <div class="notification-dialog-background"></div>
257  <div class="notification-dialog">';
258  $html .= $message;
259 
260  $html .= ' </div>
261  </div>';
262 
263  return $html;
264  }
265 
266  /**
267  * Localized string for the UI.
268  *
269  * Uses gravityforms textdomain unchanged.
270  *
271  * @since 2.5.2
272  *
273  * @return array An array of translations.
274  */
275  public function get_strings() {
276  $translations = array(
277  'currently_locked' => __( 'This entry is currently locked. Click on the "Request Control" button to let %s know you\'d like to take over.', 'gk-gravityview' ),
278  'currently_editing' => __( '%s is currently editing this entry', 'gk-gravityview' ),
279  'taken_over' => __( '%s has taken over and is currently editing this entry.', 'gk-gravityview' ),
280  'lock_requested' => __( '%s has requested permission to take over control of this entry.', 'gk-gravityview' ),
281  'accept' => __( 'Accept', 'gk-gravityview' ),
282  'cancel' => __( 'Cancel', 'gk-gravityview' ),
283  'gained_control' => __( 'You now have control', 'gk-gravityview' ),
284  'request_pending' => __( 'Pending', 'gk-gravityview' ),
285  'no_response' => __( 'No response', 'gk-gravityview' ),
286  'request_again' => __( 'Request again', 'gk-gravityview' ),
287  'request_error' => __( 'Error', 'gk-gravityview' ),
288  'request_rejected' => __( 'Your request was rejected', 'gk-gravityview' ),
289  );
290 
291  $translations = array_map( 'wp_strip_all_tags', $translations );
292 
293  return $translations;
294  }
295 
296  /**
297  * Get a localized string.
298  *
299  * @param string $string The string to get.
300  *
301  * @return string A localized string. See self::get_strings()
302  */
303  public function get_string( $string ) {
304  return \GV\Utils::get( $this->get_strings(), $string, '' );
305  }
306 
307  /**
308  * Lock the entry... maybe.
309  *
310  * Has 3 modes of locking:
311  *
312  * - acquire (get), which reloads the page after locking the entry
313  * - release, which reloads the page after unlocking the entry
314  * - default action to lock on load if not locked
315  *
316  * @param int $entry_id The entry ID.
317  *
318  * @return void
319  */
320  public function maybe_lock_object( $entry_id ) {
321  global $wp;
322 
323  $current_url = add_query_arg( $wp->query_string, '', home_url( $wp->request ) );
324 
325  if ( isset( $_GET['get-edit-lock'] ) ) {
326  $this->set_lock( $entry_id );
327  echo '<script>window.location = ' . json_encode( remove_query_arg( 'get-edit-lock', $current_url ) ) . ';</script>';
328  exit();
329  } else if ( isset( $_GET['release-edit-lock'] ) ) {
330  $this->delete_lock_meta( $entry_id );
331  $current_url = remove_query_arg( 'edit', $current_url );
332  echo '<script>window.location = ' . json_encode( remove_query_arg( 'release-edit-lock', $current_url ) ) . ';</script>';
333  exit();
334  } else {
335  if ( ! $user_id = $this->check_lock( $entry_id ) ) {
336  $this->set_lock( $entry_id );
337  }
338  }
339  }
340 
341  /**
342  * Is this entry locked to some other user?
343  *
344  * @param int $entry_id The entry ID.
345  *
346  * @return boolean Yes or no.
347  */
348  public function check_lock( $entry_id ) {
349  if ( ! $user_id = $this->get_lock_meta( $entry_id ) ) {
350  return false;
351  }
352 
353  if ( $user_id != get_current_user_id() ) {
354  return $user_id;
355  }
356 
357  return false;
358  }
359 
360  /**
361  * The lock for an entry.
362  *
363  * Leverages Gravity Forms' persistent caching mechanisms.
364  *
365  * @param int $entry_id The entry ID.
366  *
367  * @return int|null The User ID or null.
368  */
369  public function get_lock_meta( $entry_id ) {
370  return GFCache::get( 'lock_entry_' . $entry_id );
371  }
372 
373  /**
374  * Set the lock for an entry.
375  *
376  * @param int $entry_id The entry ID.
377  * @param int $user_id The user ID to lock the entry to.
378  *
379  * @return void
380  */
381  public function update_lock_meta( $entry_id, $user_id ) {
382  GFCache::set( 'lock_entry_' . $entry_id, $user_id, true, 1500 );
383  }
384 
385  /**
386  * Release the lock for an entry.
387  *
388  * @param int $entry_id The entry ID.
389  *
390  * @return void
391  */
392  public function delete_lock_meta( $entry_id ) {
393  GFCache::delete( 'lock_entry_' . $entry_id );
394  }
395 
396  /**
397  * Lock the entry to the current user.
398  *
399  * @since 2.5.2
400  *
401  * @param int $entry_id The entry ID.
402  *
403  * @return int|false Locked or not.
404  */
405  public function set_lock( $entry_id ) {
406 
407  $entry = GFAPI::get_entry( $entry_id );
408 
410  return false;
411  }
412 
413  if ( 0 === ( $user_id = get_current_user_id() ) ) {
414  return false;
415  }
416 
417  $this->update_lock_meta( $entry_id, $user_id );
418 
419  return $user_id;
420  }
421 }
get_strings()
Localized string for the UI.
maybe_lock_object( $entry_id)
Lock the entry...
if(empty( $value)) $user
delete_lock_request_meta( $object_id)
static check_user_cap_edit_entry( $entry, $view=0)
checks if user has permissions to edit a specific entry
static from_post(\WP_Post $post)
Get a list of objects inside the supplied .
global $post
Definition: delete-entry.php:7
check_lock( $entry_id)
Is this entry locked to some other user?
If this file is called directly, abort.
ajax_reject_lock_request()
update_lock_request_meta( $object_id, $lock_request_value)
request_lock( $object_id)
set_lock( $entry_id)
Lock the entry to the current user.
enqueue_scripts( $entry)
Enqueue the required scripts and styles from Gravity Forms.
load()
Load extension entry point.
get_lock_ui( $user_id)
Returns a string with the Lock UI HTML markup.
ajax_lock_request()
gravityview()
The main GravityView wrapper function.
update_lock_meta( $entry_id, $user_id)
Set the lock for an entry.
get_string( $string)
Get a localized string.
static has_cap( $caps='', $object_id=null, $user_id=null)
Alias of GravityView_Roles_Capabilities::has_cap()
$entry
Definition: notes.php:27
maybe_enqueue_scripts()
Checks whether to enqueue scripts based on:
delete_lock_meta( $entry_id)
Release the lock for an entry.
$strings
Definition: notes.php:29
get_lock_meta( $entry_id)
The lock for an entry.