Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/elementor/modules/history/revisions-manager.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + <?php
2 + namespace Elementor\Modules\History;
3 +
4 + use Elementor\Core\Base\Document;
5 + use Elementor\Core\Common\Modules\Ajax\Module as Ajax;
6 + use Elementor\Core\Files\CSS\Post as Post_CSS;
7 + use Elementor\Plugin;
8 + use Elementor\Utils;
9 +
10 + if ( ! defined( 'ABSPATH' ) ) {
11 + exit; // Exit if accessed directly.
12 + }
13 +
14 + /**
15 + * Elementor history revisions manager.
16 + *
17 + * Elementor history revisions manager handler class is responsible for
18 + * registering and managing Elementor revisions manager.
19 + *
20 + * @since 1.7.0
21 + */
22 + class Revisions_Manager {
23 +
24 + /**
25 + * Maximum number of revisions to display.
26 + */
27 + const MAX_REVISIONS_TO_DISPLAY = 50;
28 +
29 + /**
30 + * Authors list.
31 + *
32 + * Holds all the authors.
33 + *
34 + * @access private
35 + *
36 + * @var array
37 + */
38 + private static $authors = [];
39 +
40 + /**
41 + * History revisions manager constructor.
42 + *
43 + * Initializing Elementor history revisions manager.
44 + *
45 + * @since 1.7.0
46 + * @access public
47 + */
48 + public function __construct() {
49 + self::register_actions();
50 + }
51 +
52 + /**
53 + * @since 1.7.0
54 + * @access public
55 + * @static
56 + */
57 + public static function handle_revision() {
58 + add_filter( 'wp_save_post_revision_check_for_changes', '__return_false' );
59 + }
60 +
61 + /**
62 + * @since 2.0.0
63 + * @access public
64 + * @static
65 + *
66 + * @param $post_content
67 + * @param $post_id
68 + *
69 + * @return string
70 + */
71 + public static function avoid_delete_auto_save( $post_content, $post_id ) {
72 + // Add a temporary string in order the $post will not be equal to the $autosave
73 + // in edit-form-advanced.php:210
74 + $document = Plugin::$instance->documents->get( $post_id );
75 +
76 + if ( $document && $document->is_built_with_elementor() ) {
77 + $post_content .= '<!-- Created with Elementor -->';
78 + }
79 +
80 + return $post_content;
81 + }
82 +
83 + /**
84 + * @since 2.0.0
85 + * @access public
86 + * @static
87 + */
88 + public static function remove_temp_post_content() {
89 + global $post;
90 +
91 + $document = Plugin::$instance->documents->get( $post->ID );
92 +
93 + if ( ! $document || ! $document->is_built_with_elementor() ) {
94 + return;
95 + }
96 +
97 + $post->post_content = str_replace( '<!-- Created with Elementor -->', '', $post->post_content );
98 + }
99 +
100 + /**
101 + * @since 1.7.0
102 + * @access public
103 + * @static
104 + *
105 + * @param int $post_id
106 + * @param array $query_args
107 + * @param bool $parse_result
108 + *
109 + * @return array
110 + */
111 + public static function get_revisions( $post_id = 0, $query_args = [], $parse_result = true ) {
112 + $post = get_post( $post_id );
113 +
114 + if ( ! $post || empty( $post->ID ) ) {
115 + return [];
116 + }
117 +
118 + $revisions = [];
119 +
120 + $default_query_args = [
121 + 'posts_per_page' => self::MAX_REVISIONS_TO_DISPLAY,
122 + 'meta_key' => '_elementor_data',
123 + ];
124 +
125 + $query_args = array_merge( $default_query_args, $query_args );
126 +
127 + $posts = wp_get_post_revisions( $post->ID, $query_args );
128 +
129 + if ( ! wp_revisions_enabled( $post ) ) {
130 + $autosave = Utils::get_post_autosave( $post->ID );
131 + if ( $autosave ) {
132 + if ( $parse_result ) {
133 + array_unshift( $posts, $autosave );
134 + } else {
135 + array_unshift( $posts, $autosave->ID );
136 + }
137 + }
138 + }
139 +
140 + if ( $parse_result ) {
141 + array_unshift( $posts, $post );
142 + } else {
143 + array_unshift( $posts, $post->ID );
144 + return $posts;
145 + }
146 +
147 + $current_time = current_time( 'timestamp' );
148 +
149 + /** @var \WP_Post $revision */
150 + foreach ( $posts as $revision ) {
151 + $date = date_i18n( _x( 'M j @ H:i', 'revision date format', 'elementor' ), strtotime( $revision->post_modified ) );
152 +
153 + $human_time = human_time_diff( strtotime( $revision->post_modified ), $current_time );
154 +
155 + if ( $revision->ID === $post->ID ) {
156 + $type = 'current';
157 + $type_label = esc_html__( 'Current Version', 'elementor' );
158 + } elseif ( false !== strpos( $revision->post_name, 'autosave' ) ) {
159 + $type = 'autosave';
160 + $type_label = esc_html__( 'Autosave', 'elementor' );
161 + } else {
162 + $type = 'revision';
163 + $type_label = esc_html__( 'Revision', 'elementor' );
164 + }
165 +
166 + if ( ! isset( self::$authors[ $revision->post_author ] ) ) {
167 + self::$authors[ $revision->post_author ] = [
168 + 'avatar' => get_avatar( $revision->post_author, 22 ),
169 + 'display_name' => get_the_author_meta( 'display_name', $revision->post_author ),
170 + ];
171 + }
172 +
173 + $revisions[] = [
174 + 'id' => $revision->ID,
175 + 'author' => self::$authors[ $revision->post_author ]['display_name'],
176 + 'timestamp' => strtotime( $revision->post_modified ),
177 + 'date' => sprintf(
178 + /* translators: 1: Human readable time difference, 2: Date. */
179 + esc_html__( '%1$s ago (%2$s)', 'elementor' ),
180 + '<time>' . $human_time . '</time>',
181 + '<time>' . $date . '</time>'
182 + ),
183 + 'type' => $type,
184 + 'typeLabel' => $type_label,
185 + 'gravatar' => self::$authors[ $revision->post_author ]['avatar'],
186 + ];
187 + }
188 +
189 + return $revisions;
190 + }
191 +
192 + /**
193 + * @since 1.9.2
194 + * @access public
195 + * @static
196 + */
197 + public static function update_autosave( $autosave_data ) {
198 + self::save_revision( $autosave_data['ID'] );
199 + }
200 +
201 + /**
202 + * @since 1.7.0
203 + * @access public
204 + * @static
205 + */
206 + public static function save_revision( $revision_id ) {
207 + $parent_id = wp_is_post_revision( $revision_id );
208 +
209 + if ( $parent_id ) {
210 + Plugin::$instance->db->safe_copy_elementor_meta( $parent_id, $revision_id );
211 + }
212 + }
213 +
214 + /**
215 + * @since 1.7.0
216 + * @access public
217 + * @static
218 + */
219 + public static function restore_revision( $parent_id, $revision_id ) {
220 + $parent = Plugin::$instance->documents->get( $parent_id );
221 + $revision = Plugin::$instance->documents->get( $revision_id );
222 +
223 + if ( ! $parent || ! $revision ) {
224 + return;
225 + }
226 +
227 + $is_built_with_elementor = $revision->is_built_with_elementor();
228 +
229 + $parent->set_is_built_with_elementor( $is_built_with_elementor );
230 +
231 + if ( ! $is_built_with_elementor ) {
232 + return;
233 + }
234 +
235 + Plugin::$instance->db->copy_elementor_meta( $revision_id, $parent_id );
236 +
237 + $post_css = Post_CSS::create( $parent_id );
238 +
239 + $post_css->update();
240 + }
241 +
242 + /**
243 + * @since 2.3.0
244 + * @access public
245 + * @static
246 + *
247 + * @param $data
248 + *
249 + * @return array
250 + * @throws \Exception If the revision ID is not set.
251 + */
252 + public static function ajax_get_revision_data( array $data ) {
253 + if ( ! isset( $data['id'] ) ) {
254 + throw new \Exception( 'You must set the revision ID.' );
255 + }
256 +
257 + $revision = Plugin::$instance->documents->get_with_permissions( $data['id'] );
258 +
259 + return [
260 + 'settings' => $revision->get_settings(),
261 + 'elements' => $revision->get_elements_data(),
262 + ];
263 + }
264 +
265 + /**
266 + * @since 1.7.0
267 + * @access public
268 + * @static
269 + */
270 + public static function add_revision_support_for_all_post_types() {
271 + $post_types = get_post_types_by_support( 'elementor' );
272 + foreach ( $post_types as $post_type ) {
273 + add_post_type_support( $post_type, 'revisions' );
274 + }
275 + }
276 +
277 + /**
278 + * @since 2.0.0
279 + * @access public
280 + * @static
281 + * @param array $return_data
282 + * @param Document $document
283 + *
284 + * @return array
285 + */
286 + public static function on_ajax_save_builder_data( $return_data, $document ) {
287 + $post_id = $document->get_main_id();
288 +
289 + $latest_revisions = self::get_revisions(
290 + $post_id, [
291 + 'posts_per_page' => 1,
292 + ]
293 + );
294 +
295 + $all_revision_ids = self::get_revisions(
296 + $post_id, [
297 + 'fields' => 'ids',
298 + ], false
299 + );
300 +
301 + // Send revisions data only if has revisions.
302 + if ( ! empty( $latest_revisions ) ) {
303 + $current_revision_id = self::current_revision_id( $post_id );
304 +
305 + $return_data = array_replace_recursive( $return_data, [
306 + 'config' => [
307 + 'document' => [
308 + 'revisions' => [
309 + 'current_id' => $current_revision_id,
310 + ],
311 + ],
312 + ],
313 + 'latest_revisions' => $latest_revisions,
314 + 'revisions_ids' => $all_revision_ids,
315 + ] );
316 + }
317 +
318 + return $return_data;
319 + }
320 +
321 + /**
322 + * @since 1.7.0
323 + * @access public
324 + * @static
325 + */
326 + public static function db_before_save( $status, $has_changes ) {
327 + if ( $has_changes ) {
328 + self::handle_revision();
329 + }
330 + }
331 +
332 + public static function document_config( $settings, $post_id ) {
333 + $settings['revisions'] = [
334 + 'enabled' => ( $post_id && wp_revisions_enabled( get_post( $post_id ) ) ),
335 + 'current_id' => self::current_revision_id( $post_id ),
336 + ];
337 +
338 + return $settings;
339 + }
340 +
341 + /**
342 + * Localize settings.
343 + *
344 + * Add new localized settings for the revisions manager.
345 + *
346 + * Fired by `elementor/editor/editor_settings` filter.
347 + *
348 + * @since 1.7.0
349 + * @deprecated 3.1.0
350 + * @access public
351 + * @static
352 + */
353 + public static function editor_settings() {
354 + Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.1.0' );
355 +
356 + return [];
357 + }
358 +
359 + /**
360 + * @throws \Exception If the user doesn't have permissions or not found.
361 + */
362 + public static function ajax_get_revisions( $data ) {
363 + Plugin::$instance->documents->check_permissions( $data['editor_post_id'] );
364 +
365 + return self::get_revisions();
366 + }
367 +
368 + /**
369 + * @since 2.3.0
370 + * @access public
371 + * @static
372 + */
373 + public static function register_ajax_actions( Ajax $ajax ) {
374 + $ajax->register_ajax_action( 'get_revisions', [ __CLASS__, 'ajax_get_revisions' ] );
375 + $ajax->register_ajax_action( 'get_revision_data', [ __CLASS__, 'ajax_get_revision_data' ] );
376 + }
377 +
378 + /**
379 + * @since 1.7.0
380 + * @access private
381 + * @static
382 + */
383 + private static function register_actions() {
384 + add_action( 'wp_restore_post_revision', [ __CLASS__, 'restore_revision' ], 10, 2 );
385 + add_action( 'init', [ __CLASS__, 'add_revision_support_for_all_post_types' ], 9999 );
386 + add_filter( 'elementor/document/config', [ __CLASS__, 'document_config' ], 10, 2 );
387 + add_action( 'elementor/db/before_save', [ __CLASS__, 'db_before_save' ], 10, 2 );
388 + add_action( '_wp_put_post_revision', [ __CLASS__, 'save_revision' ] );
389 + add_action( 'wp_creating_autosave', [ __CLASS__, 'update_autosave' ] );
390 + add_action( 'elementor/ajax/register_actions', [ __CLASS__, 'register_ajax_actions' ] );
391 +
392 + // Hack to avoid delete the auto-save revision in WP editor.
393 + add_filter( 'edit_post_content', [ __CLASS__, 'avoid_delete_auto_save' ], 10, 2 );
394 + add_action( 'edit_form_after_title', [ __CLASS__, 'remove_temp_post_content' ] );
395 +
396 + if ( wp_doing_ajax() ) {
397 + add_filter( 'elementor/documents/ajax_save/return_data', [ __CLASS__, 'on_ajax_save_builder_data' ], 10, 2 );
398 + }
399 + }
400 +
401 + /**
402 + * @since 1.9.0
403 + * @access private
404 + * @static
405 + */
406 + private static function current_revision_id( $post_id ) {
407 + $current_revision_id = $post_id;
408 + $autosave = Utils::get_post_autosave( $post_id );
409 +
410 + if ( is_object( $autosave ) ) {
411 + $current_revision_id = $autosave->ID;
412 + }
413 +
414 + return $current_revision_id;
415 + }
416 + }
417 +