PluginProbe
Elementor Website Builder – more than just a page builder / 4.0.7
Elementor Website Builder – more than just a page builder v4.0.7
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / modules / components / document-lock-manager.php

document-lock-manager.php in Elementor Website Builder – more than just a page builder 4.0.7, at modules/components/document-lock-manager.php

176 lines 4.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Modules\Components;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit; // Exit if accessed directly.
6 }
7
8 /**
9 * Manages document locking for Elementor documents.
10 *
11 * This class handles locking/unlocking documents to prevent multiple users
12 * from editing the same document simultaneously.
13 */
14 class Document_Lock_Manager {
15 // 5 minutes
16 const DEFAULT_TIME = 60 * 5;
17
18 private $lock_duration;
19 private const LOCK_USER_META = '_lock_user';
20 private const LOCK_TIME_META = '_lock_time';
21 private const LOCK_EDIT_LOCK_META = '_edit_lock';
22
23 /**
24 * Initialize the lock manager.
25 *
26 * @param int $lock_duration Lock duration in seconds (default: 300 = 5 minutes)
27 */
28 public function __construct( $lock_duration = self::DEFAULT_TIME ) {
29 $this->lock_duration = $lock_duration;
30 }
31
32 /**
33 * Lock a document for the current user.
34 *
35 * @param int $document_id The document ID to lock
36 * @return bool True if lock was successful, false otherwise
37 */
38 public function lock( $document_id ) {
39 try {
40 $user_id = get_current_user_id();
41 if ( ! $user_id ) {
42 return false;
43 }
44
45 $post = get_post( $document_id );
46 if ( ! $post ) {
47 return false;
48 }
49
50 if ( $this->is_lock_expired( $document_id ) ) {
51 $this->unlock( $document_id );
52 }
53
54 $existing_lock = $this->get_lock_data( $document_id );
55 if ( $existing_lock['locked_by'] ) {
56 return false;
57 }
58
59 update_post_meta( $document_id, self::LOCK_USER_META, $user_id );
60 update_post_meta( $document_id, self::LOCK_TIME_META, time() );
61
62 if ( ! function_exists( 'wp_set_post_lock' ) ) {
63 require_once ABSPATH . 'wp-admin/includes/post.php';
64 }
65
66 wp_set_post_lock( $document_id );
67
68 return true;
69 } catch ( \Exception $e ) {
70 error_log( 'Document lock error: ' . $e->getMessage() );
71 return false;
72 }
73 }
74
75 /**
76 * Unlock a document.
77 *
78 * @param int $document_id The document ID to unlock
79 * @return bool True if unlock was successful, false otherwise
80 */
81 public function unlock( $document_id ) {
82 try {
83
84 delete_post_meta( $document_id, self::LOCK_USER_META );
85 delete_post_meta( $document_id, self::LOCK_TIME_META );
86 delete_post_meta( $document_id, self::LOCK_EDIT_LOCK_META );
87
88 return true;
89 } catch ( \Exception $e ) {
90 error_log( 'Document unlock error: ' . $e->getMessage() );
91 return false;
92 }
93 }
94
95 /**
96 * Check if a document is currently locked.
97 *
98 * @param int $document_id The document ID to check
99 * @return array Lock data with 'locked_by' (int|null), 'locked_at' (int|null)
100 */
101 public function get_lock_data( $document_id ) {
102 $locked_by = $this->get_document_lock_user( $document_id );
103 $locked_at = $this->get_document_lock_time( $document_id );
104
105 return [
106 'locked_by' => $locked_by,
107 'locked_at' => $locked_at,
108 ];
109 }
110
111 /**
112 * Check if a document lock has expired.
113 *
114 * @param int $document_id The document ID to check
115 * @return bool True if lock exists and is expired, false if not locked or not expired
116 */
117 public function is_lock_expired( $document_id ) {
118 $lock_data = $this->get_lock_data( $document_id );
119 if ( ! $lock_data['locked_by'] ) {
120 return false;
121 }
122
123 return $lock_data['locked_at'] && (int) $lock_data['locked_at'] + $this->lock_duration <= time();
124 }
125
126 /**
127 * Extend the lock for a document.
128 *
129 * @param int $document_id The document ID
130 * @return bool True if extended successfully, false if not locked or locked by another user
131 */
132 public function extend_lock( $document_id ) {
133 $lock_data = $this->get_lock_data( $document_id );
134 if ( ! $lock_data['locked_by'] ) {
135 return false;
136 }
137
138 $current_user_id = get_current_user_id();
139 if ( (int) $lock_data['locked_by'] !== (int) $current_user_id ) {
140 return false;
141 }
142
143 update_post_meta( $document_id, self::LOCK_TIME_META, time() );
144 return true;
145 }
146
147 public function get_document_lock_user( $document_id ) {
148 $lock_user_meta = get_post_meta( $document_id, self::LOCK_USER_META, true );
149 if ( $lock_user_meta ) {
150 return (int) $lock_user_meta;
151 }
152
153 if ( ! function_exists( 'wp_check_post_lock' ) ) {
154 require_once ABSPATH . 'wp-admin/includes/post.php';
155 }
156
157 $wp_lock_user = wp_check_post_lock( $document_id );
158 return $wp_lock_user ? (int) $wp_lock_user : null;
159 }
160
161 /**
162 * Get the lock time of a document.
163 *
164 * @param int $document_id The document ID to check
165 * @return int|null Lock time, or null if not locked
166 */
167 public function get_document_lock_time( $document_id ) {
168 $lock_time = get_post_meta( $document_id, self::LOCK_TIME_META, true );
169 if ( $lock_time ) {
170 return (int) $lock_time;
171 }
172
173 return null;
174 }
175 }
176