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

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