Completed
Push — develop ( 52c683...20e9f6 )
by Zack
35:13 queued 22:35
created

GravityView_Edit_Entry_Locking::delete_lock_meta()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
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
 */
13
class GravityView_Edit_Entry_Locking {
14
	/**
15
	 * Load extension entry point.
16
	 *
17
	 * DO NOT RENAME this method. Required by the class-edit-entry.php component loader.
18
	 * @see GravityView_Edit_Entry::load_components()
19
	 *
20
	 * @since 2.5.2
21
	 *
22
	 * @return void
23
	 */
24
	public function load() {
25
		if ( ! has_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) ) ) {
26
			add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
27
		}
28
	}
29
30
	/**
31
	 * Enqueue the required scripts and styles from Gravity Forms.
32
	 *
33
	 * Called via load() and `wp_enqueue_scripts`
34
	 *
35
	 * @since 2.5.2
36
	 *
37
	 * @return void
38
	 */
39
	public function enqueue_scripts() {
40
41
		if ( ! $entry = gravityview()->request->is_edit_entry() ) {
42
			return;
43
		}
44
45
		$min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG || isset( $_GET['gform_debug'] ) ? '' : '.min';
46
		$locking_path = GFCommon::get_base_url() . '/includes/locking/';
47
48
		wp_enqueue_script( 'gforms_locking', $locking_path . "js/locking{$min}.js", array( 'jquery', 'heartbeat' ), GFCommon::$version );
49
		wp_enqueue_style( 'gforms_locking_css', $locking_path . "css/locking{$min}.css", array( 'edit' ), GFCommon::$version );
50
51
		$translations = array_map( 'wp_strip_all_tags', $this->get_strings() );
52
53
		$strings = array(
54
			'noResponse'    => $translations['no_response'],
55
			'requestAgain'  => $translations['request_again'],
56
			'requestError'  => $translations['request_error'],
57
			'gainedControl' => $translations['gained_control'],
58
			'rejected'      => $translations['request_rejected'],
59
			'pending'       => $translations['request_pending'],
60
		);
61
62
		$lock_user_id = $this->check_lock( $entry['id'] );
63
64
		$vars = array(
65
			'hasLock'    => ! $lock_user_id ? 1 : 0,
66
			'lockUI'     => $this->get_lock_ui( $lock_user_id ),
67
			'objectID'   => $entry['id'],
68
			'objectType' => 'entry',
69
			'strings'    => $strings,
70
		);
71
72
		wp_localize_script( 'gforms_locking', 'gflockingVars', $vars );
73
	}
74
75
	/**
76
	 * Returns a string with the Lock UI HTML markup.
77
	 *
78
	 * Called script enqueuing, added to JavaScript gforms_locking global variable.
79
	 *
80
	 * @since 2.5.2
81
	 *
82
	 * @see GravityView_Edit_Entry_Locking::check_lock
83
	 *
84
	 * @param int $user_id The User ID that has the current lock. Will be empty if entry is not locked
85
	 *                     or is locked to the current user.
86
	 *
87
	 * @return string The Lock UI dialog box, etc.
88
	 */
89
	public function get_lock_ui( $user_id ) {
90
		$user = get_userdata( $user_id );
91
92
		$locked = $user_id && $user;
93
94
		$hidden = $locked ? '' : ' hidden';
95
		if ( $locked ) {
96
97
			$message = '<div class="gform-locked-message">
98
                            <div class="gform-locked-avatar">' . get_avatar( $user->ID, 64 ) . '</div>
99
                            <p class="currently-editing" tabindex="0">' . esc_html( sprintf( $this->get_string( 'currently_locked' ), _x( 'the person who is editing the entry', 'Referring to the user who is currently editing a locked entry', 'gravityview' ) ) ) . '</p>
100
                            <p>
101
102
                                <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', 'gravityforms' ) . '</a>
103
                                <button id="gform-lock-request-button" class="button button-primary wp-tab-last">' . esc_html__( 'Request Control', 'gravityforms' ) . '</button>
104
                                <a class="button" onclick="history.back(-1); return false;">' . esc_html( $this->get_string( 'cancel' ) ) . '</a>
105
                            </p>
106
                            <div id="gform-lock-request-status">
107
                                <!-- placeholder -->
108
                            </div>
109
                        </div>';
110
111
		} else {
112
113
			$message = '<div class="gform-taken-over">
114
                            <div class="gform-locked-avatar"></div>
115
                            <p class="wp-tab-first" tabindex="0">
116
                                <span class="currently-editing"></span><br>
117
                            </p>
118
                            <p>
119
                                <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>
120
                                <button id="gform-reject-lock-request-button" style="display:none"  class="button button-primary wp-tab-last">' . esc_html__( 'Reject Request', 'gravityforms' ) . '</button>
121
                            </p>
122
                        </div>';
123
124
		}
125
		$html = '<div id="gform-lock-dialog" class="notification-dialog-wrap' . $hidden . '">
126
                    <div class="notification-dialog-background"></div>
127
                    <div class="notification-dialog">';
128
		$html .= $message;
129
130
		$html .= '   </div>
131
                 </div>';
132
133
		return $html;
134
	}
135
136
	/**
137
	 * Localized string for the UI.
138
	 *
139
	 * Uses gravityforms textdomain unchanged.
140
	 *
141
	 * @since 2.5.2
142
	 *
143
	 * @return array An array of translations.
144
	 */
145
	public function get_strings() {
146
		$translations = array(
147
			'currently_locked'  => __( 'This entry is currently locked. Click on the "Request Control" button to let %s know you\'d like to take over.', 'gravityforms' ),
148
			'currently_editing' => __( '%s is currently editing this entry', 'gravityforms' ),
149
			'taken_over'        => __( '%s has taken over and is currently editing this entry.', 'gravityforms' ),
150
			'lock_requested'    => __( '%s has requested permission to take over control of this entry.', 'gravityforms' ),
151
			'accept'            => __( 'Accept', 'gravityforms' ),
152
			'cancel'            => __( 'Cancel', 'gravityforms' ),
153
			'gained_control'    => __( 'You now have control', 'gravityforms' ),
154
			'request_pending'   => __( 'Pending', 'gravityforms' ),
155
			'no_response'       => __( 'No response', 'gravityforms' ),
156
			'request_again'     => __( 'Request again', 'gravityforms' ),
157
			'request_error'     => __( 'Error', 'gravityforms' ),
158
			'request_rejected'  => __( 'Your request was rejected', 'gravityforms' ),
159
		);
160
161
		$translations = array_map( 'wp_strip_all_tags', $translations );
162
163
		return $translations;
164
	}
165
166
	/**
167
	 * Get a localized string.
168
	 *
169
	 * @param string $string The string to get.
170
	 *
171
	 * @return string A localized string. See self::get_strings()
172
	 */
173
	public function get_string( $string ) {
174
		return \GV\Utils::get( $this->get_strings(), $string, '' );
175
	}
176
177
	/**
178
	 * Lock the entry... maybe.
179
	 *
180
	 * Has 3 modes of locking:
181
	 *
182
	 *  - acquire (get), which reloads the page after locking the entry
183
	 *  - release, which reloads the page after unlocking the entry
184
	 *  - default action to lock on load if not locked
185
	 *
186
	 * @param int $entry_id The entry ID.
187
	 *
188
	 * @return void
189
	 */
190
	public function maybe_lock_object( $entry_id ) {
191
		global $wp;
192
193
		$current_url = add_query_arg( $wp->query_string, '', home_url( $wp->request ) );
194
195
		if ( isset( $_GET['get-edit-lock'] ) ) {
196
			$this->set_lock( $entry_id );
197
			echo '<script>window.location = ' . json_encode( remove_query_arg( 'get-edit-lock', $current_url ) ) . ';</script>';
198
			exit();
199
		} else if ( isset( $_GET['release-edit-lock'] ) ) {
200
			$this->delete_lock_meta( $entry_id );
201
			$current_url = remove_query_arg( 'edit', $current_url );
202
			echo '<script>window.location = ' . json_encode( remove_query_arg( 'release-edit-lock', $current_url ) ) . ';</script>';
203
			exit();
204
		} else {
205
			if ( ! $user_id = $this->check_lock( $entry_id ) ) {
206
				$this->set_lock( $entry_id );
207
			}
208
		}
209
	}
210
211
	/**
212
	 * Is this entry locked to some other user?
213
	 *
214
	 * @param int $entry_id The entry ID.
215
	 *
216
	 * @return boolean Yes or no.
217
	 */
218
	public function check_lock( $entry_id ) {
219
		if ( ! $user_id = $this->get_lock_meta( $entry_id ) ) {
220
			return false;
221
		}
222
223
		if ( $user_id != get_current_user_id() ) {
224
			return $user_id;
225
		}
226
227
		return false;
228
	}
229
230
	/**
231
	 * The lock for an entry.
232
	 *
233
	 * Leverages Gravity Forms' persistent caching mechanisms.
234
	 *
235
	 * @param int $entry_id The entry ID.
236
	 *
237
	 * @return int|null The User ID or null.
238
	 */
239
	public function get_lock_meta( $entry_id ) {
240
		return GFCache::get( 'lock_entry_' . $entry_id );
241
	}
242
243
	/**
244
	 * Set the lock for an entry.
245
	 *
246
	 * @param int $entry_id The entry ID.
247
	 * @param int $user_id The user ID to lock the entry to.
248
	 *
249
	 * @return void
250
	 */
251
	public function update_lock_meta( $entry_id, $user_id ) {
252
		GFCache::set( 'lock_entry_' . $entry_id, $user_id, true, 1500 );
253
	}
254
255
	/**
256
	 * Release the lock for an entry.
257
	 *
258
	 * @param int $entry_id The entry ID.
259
	 *
260
	 * @return void
261
	 */
262
	public function delete_lock_meta( $entry_id ) {
263
		GFCache::delete( 'lock_entry_' . $entry_id );
264
	}
265
266
	/**
267
	 * Lock the entry to the current user.
268
	 *
269
	 * @since 2.5.2
270
	 *
271
	 * @param int $entry_id The entry ID.
272
	 *
273
	 * @return int|false Locked or not.
274
	 */
275
	public function set_lock( $entry_id ) {
276
277
		// Todo: check caps
278
279
		if ( 0 == ( $user_id = get_current_user_id() ) ) {
280
			return false;
281
		}
282
283
		$this->update_lock_meta( $entry_id, $user_id );
284
285
		return $user_id;
286
	}
287
}
288