PluginProbe
Elementor Website Builder – more than just a page builder / 3.35.0
Elementor Website Builder – more than just a page builder v3.35.0
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 / includes / settings / tools.php

tools.php in Elementor Website Builder – more than just a page builder 3.35.0, at includes/settings/tools.php

508 lines 16.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor;
3
4 use Elementor\Core\Admin\Menu\Admin_Menu_Manager;
5 use Elementor\Core\Admin\Menu\Main as MainMenu;
6 use Elementor\Core\Kits\Manager;
7 use Elementor\Includes\Settings\AdminMenuItems\Tools_Menu_Item;
8 use Elementor\Modules\EditorOne\Classes\Menu_Data_Provider;
9 use Elementor\Includes\Settings\AdminMenuItems\Editor_One_Tools_Menu;
10
11 if ( ! defined( 'ABSPATH' ) ) {
12 exit; // Exit if accessed directly.
13 }
14
15 /**
16 * Elementor "Tools" page in WordPress Dashboard.
17 *
18 * Elementor settings page handler class responsible for creating and displaying
19 * Elementor "Tools" page in WordPress dashboard.
20 *
21 * @since 1.0.0
22 */
23 class Tools extends Settings_Page {
24
25 const CAPABILITY = 'manage_options';
26
27 /**
28 * Settings page ID for Elementor tools.
29 */
30 const PAGE_ID = 'elementor-tools';
31
32 private function register_admin_menu( MainMenu $menu ) {
33 $menu->add_submenu( [
34 'page_title' => esc_html__( 'Tools', 'elementor' ),
35 'menu_title' => esc_html__( 'Tools', 'elementor' ),
36 'menu_slug' => self::PAGE_ID,
37 'function' => [ $this, 'display_settings_page' ],
38 'index' => 50,
39 ] );
40 }
41
42 /**
43 * Clear cache.
44 *
45 * Delete post meta containing the post CSS file data. And delete the actual
46 * CSS files from the upload directory.
47 *
48 * Fired by `wp_ajax_elementor_clear_cache` action.
49 *
50 * @since 1.0.0
51 * @access public
52 */
53 public function ajax_elementor_clear_cache() {
54 check_ajax_referer( 'elementor_clear_cache', '_nonce' );
55
56 if ( ! current_user_can( static::CAPABILITY ) ) {
57 wp_send_json_error( 'Permission denied' );
58 }
59
60 Plugin::$instance->files_manager->clear_cache();
61
62 wp_send_json_success();
63 }
64
65 public function admin_post_elementor_site_clear_cache() {
66 check_ajax_referer( 'elementor_site_clear_cache' );
67
68 if ( ! current_user_can( static::CAPABILITY ) ) {
69 wp_die( 'Permission denied' );
70 }
71
72 Plugin::$instance->files_manager->clear_cache();
73
74 $http_referer = wp_get_raw_referer();
75 if ( empty( $http_referer ) ) {
76 $http_referer = admin_url( 'admin.php?page=' . static::PAGE_ID );
77 }
78
79 wp_safe_redirect( $http_referer );
80 die;
81 }
82
83 /**
84 * Recreate kit.
85 *
86 * Recreate default kit (only when default kit does not exist).
87 *
88 * Fired by `wp_ajax_elementor_recreate_kit` action.
89 *
90 * @since 1.0.0
91 * @access public
92 */
93 public function ajax_elementor_recreate_kit() {
94 check_ajax_referer( 'elementor_recreate_kit', '_nonce' );
95
96 if ( ! current_user_can( static::CAPABILITY ) ) {
97 wp_send_json_error( 'Permission denied' );
98 }
99
100 $kit = Plugin::$instance->kits_manager->get_active_kit();
101
102 if ( $kit->get_id() ) {
103 wp_send_json_error( [ 'message' => esc_html__( 'There\'s already an active kit.', 'elementor' ) ], 400 );
104 }
105
106 $created_default_kit = Plugin::$instance->kits_manager->create_default();
107
108 if ( ! $created_default_kit ) {
109 wp_send_json_error( [ 'message' => esc_html__( 'An error occurred while trying to create a kit.', 'elementor' ) ], 500 );
110 }
111
112 update_option( Manager::OPTION_ACTIVE, $created_default_kit );
113
114 wp_send_json_success( esc_html__( 'New kit have been created successfully', 'elementor' ) );
115 }
116
117 /**
118 * Replace URLs.
119 *
120 * Sends an ajax request to replace old URLs to new URLs. This method also
121 * updates all the Elementor data.
122 *
123 * Fired by `wp_ajax_elementor_replace_url` action.
124 *
125 * @since 1.1.0
126 * @access public
127 */
128 public function ajax_elementor_replace_url() {
129 check_ajax_referer( 'elementor_replace_url', '_nonce' );
130
131 if ( ! current_user_can( static::CAPABILITY ) ) {
132 wp_send_json_error( 'Permission denied' );
133 }
134
135 $from = Utils::get_super_global_value( $_POST, 'from' ) ?? '';
136 $to = Utils::get_super_global_value( $_POST, 'to' ) ?? '';
137
138 try {
139 $results = Utils::replace_urls( $from, $to );
140 wp_send_json_success( $results );
141 } catch ( \Exception $e ) {
142 wp_send_json_error( $e->getMessage() );
143 }
144 }
145
146 /**
147 * Elementor version rollback.
148 *
149 * Rollback to previous Elementor version.
150 *
151 * Fired by `admin_post_elementor_rollback` action.
152 *
153 * @since 1.5.0
154 * @access public
155 */
156 public function post_elementor_rollback() {
157 check_admin_referer( 'elementor_rollback' );
158
159 if ( ! static::can_user_rollback_versions() ) {
160 wp_die( esc_html__( 'Not allowed to rollback versions', 'elementor' ) );
161 }
162
163 $rollback_versions = $this->get_rollback_versions();
164 $version = Utils::get_super_global_value( $_GET, 'version' );
165
166 if ( empty( $version ) || ! in_array( $version, $rollback_versions, true ) ) {
167 wp_die( esc_html__( 'An error occurred, the selected version is invalid. Try selecting different version.', 'elementor' ) );
168 }
169
170 /**
171 * Filter to allow override the rollback process.
172 * Should return an instance of `Rollback` class.
173 *
174 * @since 3.16.0
175 *
176 * @param Rollback|null $rollback The rollback instance.
177 * @param string $version The version to roll back to.
178 */
179 $rollback = apply_filters( 'elementor/settings/rollback', null, $version );
180
181 if ( ! ( $rollback instanceof Rollback ) ) {
182 $plugin_slug = basename( ELEMENTOR__FILE__, '.php' );
183
184 $rollback = new Rollback( [
185 'version' => $version,
186 'plugin_name' => ELEMENTOR_PLUGIN_BASE,
187 'plugin_slug' => $plugin_slug,
188 'package_url' => sprintf( 'https://downloads.wordpress.org/plugin/%s.%s.zip', $plugin_slug, $version ),
189 ] );
190 }
191
192 $rollback->run();
193
194 wp_die(
195 '', esc_html__( 'Rollback to Previous Version', 'elementor' ), [
196 'response' => 200,
197 ]
198 );
199 }
200
201 /**
202 * Tools page constructor.
203 *
204 * Initializing Elementor "Tools" page.
205 *
206 * @since 1.0.0
207 * @access public
208 */
209 public function __construct() {
210 parent::__construct();
211
212 add_action( 'elementor/admin/menu/register', function( Admin_Menu_Manager $admin_menu ) {
213 if ( ! $this->is_editor_one_active() ) {
214 $admin_menu->register( static::PAGE_ID, new Tools_Menu_Item( $this ) );
215 }
216 }, Settings::ADMIN_MENU_PRIORITY + 20 );
217
218 add_action( 'elementor/editor-one/menu/register', function ( Menu_Data_Provider $menu_data_provider ) {
219 $this->register_editor_one_menu( $menu_data_provider );
220 } );
221
222 add_action( 'wp_ajax_elementor_clear_cache', [ $this, 'ajax_elementor_clear_cache' ] );
223 add_action( 'admin_post_elementor_site_clear_cache', [ $this, 'admin_post_elementor_site_clear_cache' ] );
224 add_action( 'wp_ajax_elementor_replace_url', [ $this, 'ajax_elementor_replace_url' ] );
225 add_action( 'wp_ajax_elementor_recreate_kit', [ $this, 'ajax_elementor_recreate_kit' ] );
226
227 add_action( 'admin_post_elementor_rollback', [ $this, 'post_elementor_rollback' ] );
228 }
229
230 private function register_editor_one_menu( Menu_Data_Provider $menu_data_provider ) {
231 $menu_data_provider->register_menu( new Editor_One_Tools_Menu() );
232 }
233
234 private function is_editor_one_active(): bool {
235 return (bool) Plugin::instance()->modules_manager->get_modules( 'editor-one' );
236 }
237
238 public function get_warning_span( string $text ): string {
239 $is_editor_one_enabled = Plugin::$instance->experiments->is_feature_active( 'e_editor_one' );
240 $color = $is_editor_one_enabled ? 'var(--e-one-palette-error-main)' : 'red';
241 return sprintf( '<span style="color: %s;">%s</span>', esc_attr( $color ), esc_html( $text ) );
242 }
243
244 private function get_rollback_versions() {
245 $rollback_versions = get_transient( 'elementor_rollback_versions_' . ELEMENTOR_VERSION );
246
247 if ( false === $rollback_versions ) {
248 $max_versions = 30;
249
250 $versions = apply_filters( 'elementor/settings/rollback/versions', [] );
251
252 if ( empty( $versions ) ) {
253 require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
254
255 $plugin_information = plugins_api(
256 'plugin_information', [
257 'slug' => 'elementor',
258 ]
259 );
260
261 if ( empty( $plugin_information->versions ) || ! is_array( $plugin_information->versions ) ) {
262 return [];
263 }
264
265 uksort( $plugin_information->versions, 'version_compare' );
266 $versions = array_keys( array_reverse( $plugin_information->versions ) );
267 }
268
269 $rollback_versions = [];
270
271 $current_index = 0;
272 foreach ( $versions as $version ) {
273 if ( $max_versions <= $current_index ) {
274 break;
275 }
276
277 $lowercase_version = strtolower( $version );
278 $is_valid_rollback_version = ! preg_match( '/(trunk|beta|rc|dev)/i', $lowercase_version );
279
280 /**
281 * Is rollback version is valid.
282 *
283 * Filters the check whether the rollback version is valid.
284 *
285 * @param bool $is_valid_rollback_version Whether the rollback version is valid.
286 */
287 $is_valid_rollback_version = apply_filters(
288 'elementor/settings/tools/rollback/is_valid_rollback_version',
289 $is_valid_rollback_version,
290 $lowercase_version
291 );
292
293 if ( ! $is_valid_rollback_version ) {
294 continue;
295 }
296
297 if ( version_compare( $version, ELEMENTOR_VERSION, '>=' ) ) {
298 continue;
299 }
300
301 ++$current_index;
302 $rollback_versions[] = $version;
303 }
304
305 set_transient( 'elementor_rollback_versions_' . ELEMENTOR_VERSION, $rollback_versions, WEEK_IN_SECONDS );
306 }
307
308 return $rollback_versions;
309 }
310
311 /**
312 * Create tabs.
313 *
314 * Return the tools page tabs, sections and fields.
315 *
316 * @since 1.5.0
317 * @access protected
318 *
319 * @return array An array with the page tabs, sections and fields.
320 */
321 protected function create_tabs() {
322 $rollback_html = '<select class="elementor-rollback-select">';
323
324 foreach ( $this->get_rollback_versions() as $version ) {
325 $rollback_html .= "<option value='{$version}'>$version</option>";
326 }
327 $rollback_html .= '</select>';
328
329 $tabs = [
330 'general' => [
331 'label' => esc_html__( 'General', 'elementor' ),
332 'sections' => [
333 'tools' => [
334 'fields' => [
335 'clear_cache' => [
336 'label' => esc_html__( 'Elementor Cache', 'elementor' ),
337 'field_args' => [
338 'type' => 'raw_html',
339 'html' => sprintf( '<button data-nonce="%s" data-id="elementor-tools-general-button-clear-files-data" class="button elementor-button-spinner" id="elementor-clear-cache-button">%s</button>', wp_create_nonce( 'elementor_clear_cache' ), esc_html__( 'Clear Files & Data', 'elementor' ) ),
340 'desc' => esc_html__( "Clear outdated CSS files and cached data in the database (rendered HTML, JS/CSS assets, etc.). We'll regenerate those files the next time someone visits any page on your website.", 'elementor' ),
341 ],
342 ],
343 'reset_api_data' => [
344 'label' => esc_html__( 'Sync Library', 'elementor' ),
345 'field_args' => [
346 'type' => 'raw_html',
347 'html' => sprintf( '<button data-nonce="%s" data-id="elementor-tools-general-button-sync-library" class="button elementor-button-spinner" id="elementor-library-sync-button">%s</button>', wp_create_nonce( 'elementor_reset_library' ), esc_html__( 'Sync Library', 'elementor' ) ),
348 'desc' => esc_html__( 'Elementor Library automatically updates on a daily basis. You can also manually update it by clicking on the sync button.', 'elementor' ),
349 ],
350 ],
351 ],
352 ],
353 ],
354 ],
355 'replace_url' => [
356 'label' => esc_html__( 'Replace URL', 'elementor' ),
357 'sections' => [
358 'replace_url' => [
359 'callback' => function() {
360 echo '<h2>' . esc_html__( 'Replace URL', 'elementor' ) . '</h2>';
361 printf(
362 '<p><strong>%1$s</strong> %2$s</p>',
363 esc_html__( 'Important:', 'elementor' ),
364 sprintf(
365 /* translators: 1: Link open tag, 2: Link close tag. */
366 esc_html__( 'It is strongly recommended to %1$sbackup the database%2$s before using replacing URLs.', 'elementor' ),
367 '<a href="https://go.elementor.com/wordpress-backups/" target="_blank">',
368 '</a>'
369 )
370 );
371 },
372 'fields' => [
373 'replace_url' => [
374 'label' => esc_html__( 'Update Site Address (URL)', 'elementor' ),
375 'field_args' => [
376 'type' => 'raw_html',
377 'html' => sprintf( '<input type="text" name="from" placeholder="https://old.example.com" class="large-text"><input type="text" name="to" placeholder="https://new.example.com" class="large-text"><button data-nonce="%s" data-id="elementor-tools-replace_url-button-replace-url" class="button elementor-button-spinner" id="elementor-replace-url-button">%s</button>', wp_create_nonce( 'elementor_replace_url' ), esc_html__( 'Replace URL', 'elementor' ) ),
378 'desc' => esc_html__( 'Enter your old and new URLs for your WordPress installation, to update all Elementor data (Relevant for domain transfers or move to \'HTTPS\').', 'elementor' ),
379 ],
380 ],
381 ],
382 ],
383 ],
384 ],
385 'versions' => [
386 'show_if' => static::can_user_rollback_versions(),
387 'label' => esc_html__( 'Version Control', 'elementor' ),
388 'sections' => [
389 'rollback' => [
390 'label' => esc_html__( 'Rollback to Previous Version', 'elementor' ),
391 'callback' => function() {
392 $intro_text = sprintf(
393 /* translators: %s: Elementor version. */
394 esc_html__( 'Experiencing an issue with Elementor version %s? Rollback to a previous version before the issue appeared.', 'elementor' ),
395 ELEMENTOR_VERSION
396 );
397 $intro_text = '<p>' . $intro_text . '</p>';
398
399 Utils::print_unescaped_internal_string( $intro_text );
400 },
401 'fields' => [
402 'rollback' => [
403 'label' => esc_html__( 'Rollback Version', 'elementor' ),
404 'field_args' => [
405 'type' => 'raw_html',
406 'html' => sprintf(
407 $rollback_html . '<a data-placeholder-text="%1$s v{VERSION}" href="#" data-placeholder-url="%2$s" class="button elementor-button-spinner elementor-rollback-button">%1$s</a>',
408 esc_html__( 'Reinstall', 'elementor' ),
409 wp_nonce_url( admin_url( 'admin-post.php?action=elementor_rollback&version=VERSION' ), 'elementor_rollback' )
410 ),
411 'desc' => $this->get_warning_span( esc_html__( 'Warning: Please backup your database before making the rollback.', 'elementor' ) ),
412 ],
413 ],
414 ],
415 ],
416 'beta' => [
417 'show_if' => $this->display_beta_tester(),
418 'label' => esc_html__( 'Become a Beta Tester', 'elementor' ),
419 'callback' => function() {
420 echo '<p>' .
421 esc_html__( 'Turn-on Beta Tester, to get notified when a new beta version of Elementor or Elementor Pro is available. The Beta version will not install automatically. You always have the option to ignore it.', 'elementor' ) .
422 '</p>';
423 echo '<p>' . sprintf(
424 /* translators: 1: Link open tag, 2: Link close tag. */
425 esc_html__( '%1$sClick here%2$s %3$sto join our first-to-know email updates.%4$s', 'elementor' ),
426 '<a id="beta-tester-first-to-know" class="elementor-become-a-beta-tester" href="#">',
427 '</a>',
428 '<span class="elementor-become-a-beta-tester">',
429 '</span>',
430 ) . '</p>';
431 },
432 'fields' => [
433 'beta' => [
434 'label' => esc_html__( 'Beta Tester', 'elementor' ),
435 'field_args' => [
436 'type' => 'select',
437 'std' => 'no',
438 'options' => [
439 'no' => esc_html__( 'Disable', 'elementor' ),
440 'yes' => esc_html__( 'Enable', 'elementor' ),
441 ],
442 'desc' => $this->get_warning_span( esc_html__( 'Please Note: We do not recommend updating to a beta version on production sites.', 'elementor' ) ),
443 ],
444 ],
445 ],
446 ],
447 ],
448 ],
449 ];
450
451 if ( ! Plugin::$instance->kits_manager->get_active_kit()->get_id() ) {
452 $tabs['general']['sections']['tools']['fields']['recreate_kit'] = [
453 'label' => esc_html__( 'Recreate Kit', 'elementor' ),
454 'field_args' => [
455 'type' => 'raw_html',
456 'html' => sprintf( '<button data-nonce="%s" class="button elementor-button-spinner" id="elementor-recreate-kit-button">%s</button>', wp_create_nonce( 'elementor_recreate_kit' ), esc_html__( 'Recreate Kit', 'elementor' ) ),
457 'desc' => esc_html__( 'It seems like your site doesn\'t have any active Kit. The active Kit includes all of your Site Settings. By recreating your Kit you will able to start edit your Site Settings again.', 'elementor' ),
458 ],
459 ];
460 }
461 return $tabs;
462 }
463
464 /**
465 * Get tools page title.
466 *
467 * Retrieve the title for the tools page.
468 *
469 * @since 1.5.0
470 * @access protected
471 *
472 * @return string Tools page title.
473 */
474 protected function get_page_title() {
475 return esc_html__( 'Tools', 'elementor' );
476 }
477
478 /**
479 * Check if the current user can access the version control tab and rollback versions.
480 *
481 * @return bool
482 */
483 public static function can_user_rollback_versions() {
484 return current_user_can( 'activate_plugins' ) && current_user_can( 'update_plugins' );
485 }
486
487 /**
488 * Check if the beta tester should be displayed.
489 *
490 * @since 3.19.0
491 *
492 * @return bool
493 */
494 public function display_beta_tester(): bool {
495 $display_beta_tester = true;
496 /**
497 * Filter to allow override the display of the beta tester.
498 *
499 * @param bool $display_beta_tester Whether to display the beta tester.
500 *
501 * @since 3.19.0
502 *
503 * return bool
504 */
505 return apply_filters( 'elementor/admin/show_beta_tester', $display_beta_tester );
506 }
507 }
508