PluginProbe
Sharing Image / 3.7
Sharing Image v3.7
3.10 trunk 2.0 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.17 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 3.0 3.1 3.2 3.3 All 29 releases
← All changes | classes/class-settings.php +137 -1120 2.0.33.7 View file →
@@ -12,9 +12,9 @@
12 12 die;
13 13 }
14 14
15 15 /**
16 - * Settings page class
16 + * Settings class.
17 17 *
18 18 * @class Settings
19 19 */
20 20 class Settings {
@@ -25,29 +25,8 @@
25 25 */
26 26 const SCREEN_ID = 'settings_page_sharing-image';
27 27
28 28 /**
29 - * Sharing Image templates options name.
30 - *
31 - * @var string
32 - */
33 - const OPTION_TEMPLATES = 'sharing_image_templates';
34 -
35 - /**
36 - * Sharing Image config options name.
37 - *
38 - * @var string
39 - */
40 - const OPTION_CONFIG = 'sharing_image_config';
41 -
42 - /**
43 - * Sharing Image license options name.
44 - *
45 - * @var string
46 - */
47 - const OPTION_LICENSE = 'sharing_image_license';
48 -
49 - /**
50 29 * Plugin admin menu slug.
51 30 *
52 31 * @var string
53 32 */
@@ -53,64 +32,35 @@
53 32 */
54 33 const SETTINGS_SLUG = 'sharing-image';
55 34
56 35 /**
57 - * Remote licenses API url.
58 - *
59 - * @var string
36 + * Common nonce for settings tabs.
60 37 */
61 - const REMOTE_LICENSES = 'https://wpget.org/sharing-image/verify/';
38 + const SETTINGS_NONCE = 'sharing-image-nonce';
62 39
63 40 /**
64 - * Premium verification event name.
65 - *
66 - * @var string
67 - */
68 - const EVENT_PREMIUM = 'sharing_image_event_premium';
69 -
70 - /**
71 41 * List of settings tabs.
72 42 *
73 43 * @var array
74 44 */
75 - private $tabs = array();
45 + private static $tabs = array();
76 46
77 47 /**
78 - * Settings constructor.
79 - */
80 - public function __construct() {
81 - $this->init_tabs();
82 - }
83 -
84 - /**
85 48 * Init class actions and filters.
86 49 */
87 - public function init() {
88 - add_action( 'admin_menu', array( $this, 'add_menu' ) );
50 + public static function init() {
51 + add_action( 'admin_init', array( __CLASS__, 'init_tabs' ) );
52 + add_action( 'admin_menu', array( __CLASS__, 'add_menu' ) );
53 + add_action( 'admin_title', array( __CLASS__, 'update_settings_title' ) );
54 + add_action( 'admin_init', array( __CLASS__, 'allow_custom_fonts' ) );
89 55
90 - // Handle settings POST requests.
91 - add_action( 'admin_init', array( $this, 'handle_post_requests' ) );
92 -
93 - // Handle settings AJAX requests.
94 - add_action( 'admin_init', array( $this, 'handle_ajax_requests' ) );
95 -
96 - // Allow uploading custom fonts for templates editor.
97 - add_action( 'admin_init', array( $this, 'allow_custom_fonts' ) );
98 -
99 - // Add settings link to plugins list.
100 - add_filter( 'plugin_action_links', array( $this, 'add_settings_link' ), 10, 2 );
101 -
102 - // Update admin title for different tabs.
103 - add_action( 'admin_title', array( $this, 'update_settings_title' ) );
104 -
105 - // Schedule Premium license verification.
106 - add_action( self::EVENT_PREMIUM, array( $this, 'launch_verification_event' ), 10, 1 );
56 + add_filter( 'plugin_action_links', array( __CLASS__, 'add_settings_link' ), 10, 2 );
107 57 }
108 58
109 59 /**
110 60 * Add plugin settings page in WordPress menu.
111 61 */
112 - public function add_menu() {
62 + public static function add_menu() {
113 63 /**
114 64 * Easy way to hide settings page.
115 65 *
116 66 * @param bool $hide_settings Set true to hide settings page.
@@ -125,61 +75,22 @@
125 75 esc_html__( 'Sharing Image settings', 'sharing-image' ),
126 76 esc_html__( 'Sharing Image', 'sharing-image' ),
127 77 'manage_options',
128 78 self::SETTINGS_SLUG,
129 - array( $this, 'display_settings' )
79 + array( __CLASS__, 'display_settings' )
130 80 );
131 81
132 82 // Add required assets and objects.
133 - add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles' ) );
134 - add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
83 + add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_styles' ) );
84 + add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_scripts' ) );
135 85 }
136 86
137 87 /**
138 - * Handle settings POST requests.
139 - */
140 - public function handle_post_requests() {
141 - $actions = array(
142 - 'config' => 'save_settings_config',
143 - 'editor' => 'save_settings_template',
144 - 'delete' => 'delete_settings_template',
145 - );
146 -
147 - foreach ( $actions as $key => $method ) {
148 - $action = 'sharing_image_' . $key;
149 -
150 - if ( method_exists( $this, $method ) ) {
151 - add_action( 'admin_post_' . $action, array( $this, $method ) );
152 - }
153 - }
154 - }
155 -
156 - /**
157 - * Handle settings AJAX requests.
158 - */
159 - public function handle_ajax_requests() {
160 - $actions = array(
161 - 'show' => 'show_template_preview',
162 - 'save' => 'save_template_preview',
163 - 'verify' => 'verify_premium_key',
164 - 'revoke' => 'revoke_premium_access',
165 - );
166 -
167 - foreach ( $actions as $key => $method ) {
168 - $action = 'sharing_image_' . $key;
169 -
170 - if ( method_exists( $this, $method ) ) {
171 - add_action( 'wp_ajax_' . $action, array( $this, $method ) );
172 - }
173 - }
174 - }
175 -
176 - /**
177 88 * Allow uploading custom fonts for templates editor.
178 89 * This function may affect the security of the site.
179 90 * Disable font uploading if you are not going to use it.
180 91 */
181 - public function allow_custom_fonts() {
92 + public static function allow_custom_fonts() {
182 93 /**
183 94 * Easy way to disable custom font uploading.
184 95 *
185 96 * @param bool $disable_fonts Set true to disable fonts uploading.
@@ -189,13 +100,13 @@
189 100 if ( $disable_fonts ) {
190 101 return;
191 102 }
192 103
193 - // Allow True Type fonts uploading.
194 - add_filter( 'wp_check_filetype_and_ext', array( $this, 'fix_ttf_mime_type' ), 10, 3 );
104 + // Allow fonts uploading.
105 + add_filter( 'wp_check_filetype_and_ext', array( __CLASS__, 'fix_fonts_mime_type' ), 10, 3 );
195 106
196 - // Add new .ttf font mime type.
197 - add_filter( 'upload_mimes', array( $this, 'add_ttf_mime_type' ) );
107 + // Add new .ttf and .otf font mime types.
108 + add_filter( 'upload_mimes', array( __CLASS__, 'add_fonts_mime_type' ) );
198 109 }
199 110
200 111 /**
201 112 * Add settings link to plugins list.
@@ -204,9 +115,9 @@
204 115 * @param string $plugin_file Path to the plugin file relative to the plugins directory.
205 116
206 117 * @return array Array of settings actions.
207 118 */
208 - public function add_settings_link( $actions, $plugin_file ) {
119 + public static function add_settings_link( $actions, $plugin_file ) {
209 120 $actions = (array) $actions;
210 121
211 122 if ( plugin_basename( SHARING_IMAGE_FILE ) === $plugin_file ) {
212 123 $actions[] = sprintf(
@@ -219,249 +130,12 @@
219 130 return $actions;
220 131 }
221 132
222 133 /**
223 - * Save settings config fields.
224 - */
225 - public function save_settings_config() {
226 - check_admin_referer( basename( __FILE__ ), 'sharing_image_nonce' );
227 -
228 - if ( ! current_user_can( 'manage_options' ) ) {
229 - wp_die( esc_html__( 'Sorry, you are not allowed to manage options for this site.', 'sharing-image' ) );
230 - }
231 -
232 - $return = $this->get_tab_link( 'config' );
233 -
234 - if ( null === $return ) {
235 - $return = admin_url( 'options-general.php?page=' . self::SETTINGS_SLUG );
236 - }
237 -
238 - if ( ! isset( $_POST['sharing_image_config'] ) ) {
239 - $this->redirect_with_message( $return, 5 );
240 - }
241 -
242 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
243 - $config = $this->sanitize_config( wp_unslash( $_POST['sharing_image_config'] ) );
244 -
245 - $this->update_config( $config );
246 -
247 - // Redirect with success message.
248 - $this->redirect_with_message( $return, 1 );
249 - }
250 -
251 - /**
252 - * Save template editor fields.
253 - */
254 - public function save_settings_template() {
255 - check_admin_referer( basename( __FILE__ ), 'sharing_image_nonce' );
256 -
257 - if ( ! current_user_can( 'manage_options' ) ) {
258 - wp_die( esc_html__( 'Sorry, you are not allowed to manage options for this site.', 'sharing-image' ) );
259 - }
260 -
261 - $return = admin_url( 'options-general.php?page=' . self::SETTINGS_SLUG );
262 -
263 - if ( ! isset( $_POST['sharing_image_index'] ) ) {
264 - $this->redirect_with_message( $return, 2 );
265 - }
266 -
267 - $index = absint( wp_unslash( $_POST['sharing_image_index'] ) );
268 -
269 - if ( ! isset( $_POST['sharing_image_editor'] ) ) {
270 - $this->redirect_with_message( $return, 2 );
271 - }
272 -
273 - // Skip 2nd+ templates if the Premium is not active.
274 - if ( $index > 0 && ! $this->is_premium_features() ) {
275 - $this->redirect_with_message( $return, 2 );
276 - }
277 -
278 - $return = add_query_arg( array( 'template' => $index + 1 ), $return );
279 -
280 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
281 - $editor = $this->sanitize_editor( wp_unslash( $_POST['sharing_image_editor'] ) );
282 -
283 - $this->update_templates( $index, $editor );
284 -
285 - // Redirect with success message.
286 - $this->redirect_with_message( $return, 1 );
287 - }
288 -
289 - /**
290 - * Action to delete template from editor page.
291 - */
292 - public function delete_settings_template() {
293 - check_admin_referer( basename( __FILE__ ), 'nonce' );
294 -
295 - if ( ! current_user_can( 'manage_options' ) ) {
296 - return;
297 - }
298 -
299 - $return = admin_url( 'options-general.php?page=' . self::SETTINGS_SLUG );
300 -
301 - if ( ! isset( $_REQUEST['template'] ) ) {
302 - $this->redirect_with_message( $return, 4 );
303 - }
304 -
305 - // Get index from template ID.
306 - $index = absint( $_REQUEST['template'] ) - 1;
307 -
308 - if ( ! $this->update_templates( $index ) ) {
309 - $this->redirect_with_message( $return, 4 );
310 - }
311 -
312 - $this->redirect_with_message( $return, 3 );
313 - }
314 -
315 - /**
316 - * Show generated template from AJAX request.
317 - */
318 - public function show_template_preview() {
319 - $check = check_ajax_referer( basename( __FILE__ ), 'sharing_image_nonce', false );
320 -
321 - if ( false === $check ) {
322 - wp_send_json_error( __( 'Invalid security token. Reload the page and retry.', 'sharing-image' ), 403 );
323 - }
324 -
325 - if ( ! isset( $_POST['sharing_image_index'] ) ) {
326 - wp_send_json_error( __( 'Poster index undefined.', 'sharing-image' ), 400 );
327 - }
328 -
329 - $index = absint( wp_unslash( $_POST['sharing_image_index'] ) );
330 -
331 - if ( ! isset( $_POST['sharing_image_editor'] ) ) {
332 - wp_send_json_error( __( 'Editor settings are not set.', 'sharing-image' ), 400 );
333 - }
334 -
335 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
336 - $editor = $this->sanitize_editor( wp_unslash( $_POST['sharing_image_editor'] ) );
337 -
338 - // Show poster using generator class.
339 - $poster = ( new Generator() )->show( $editor, $index );
340 -
341 - if ( is_wp_error( $poster ) ) {
342 - wp_send_json_error( $poster->get_error_message(), 400 );
343 - }
344 - }
345 -
346 - /**
347 - * Show generated template from AJAX request.
348 - */
349 - public function save_template_preview() {
350 - $check = check_ajax_referer( basename( __FILE__ ), 'sharing_image_nonce', false );
351 -
352 - if ( false === $check ) {
353 - wp_send_json_error( __( 'Invalid security token. Reload the page and retry.', 'sharing-image' ), 403 );
354 - }
355 -
356 - if ( ! isset( $_POST['sharing_image_index'] ) ) {
357 - wp_send_json_error( __( 'Poster index undefined.', 'sharing-image' ), 400 );
358 - }
359 -
360 - $index = absint( wp_unslash( $_POST['sharing_image_index'] ) );
361 -
362 - if ( ! isset( $_POST['sharing_image_editor'] ) ) {
363 - wp_send_json_error( __( 'Editor settings are not set.', 'sharing-image' ), 400 );
364 - }
365 -
366 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
367 - $editor = $this->sanitize_editor( wp_unslash( $_POST['sharing_image_editor'] ) );
368 -
369 - // Save poster using generator class.
370 - $poster = ( new Generator() )->save( $editor, $index );
371 -
372 - if ( is_wp_error( $poster ) ) {
373 - wp_send_json_error( $poster->get_error_message(), 400 );
374 - }
375 -
376 - wp_send_json_success( $poster );
377 - }
378 -
379 - /**
380 - * Verify Premium key from AJAX request.
381 - */
382 - public function verify_premium_key() {
383 - $check = check_ajax_referer( basename( __FILE__ ), 'sharing_image_nonce', false );
384 -
385 - if ( false === $check ) {
386 - wp_send_json_error( __( 'Invalid security token. Reload the page and retry.', 'sharing-image' ), 403 );
387 - }
388 -
389 - if ( empty( $_POST['sharing_image_key'] ) ) {
390 - wp_send_json_error( __( 'Premium key undefined.', 'sharing-image' ), 400 );
391 - }
392 -
393 - $key = sanitize_text_field( wp_unslash( $_POST['sharing_image_key'] ) );
394 -
395 - $args = array(
396 - 'body' => array(
397 - 'key' => $key,
398 - 'domain' => wp_parse_url( site_url(), PHP_URL_HOST ),
399 - ),
400 - );
401 -
402 - $response = wp_remote_post( self::REMOTE_LICENSES, $args );
403 -
404 - if ( is_wp_error( $response ) ) {
405 - wp_send_json_error( __( 'Unable to get a response from the verification server.', 'sharing-image' ), 400 );
406 - }
407 -
408 - $answer = json_decode( $response['body'], true );
409 -
410 - if ( ! isset( $answer['success'] ) ) {
411 - wp_send_json_error( __( 'Unable to get a response from the verification server.', 'sharing-image' ), 400 );
412 - }
413 -
414 - // Remove license verification event.
415 - wp_unschedule_hook( self::EVENT_PREMIUM );
416 -
417 - if ( true === $answer['success'] ) {
418 - $license = $this->update_license( true, $key );
419 -
420 - // Schedule license verification twice daily.
421 - $this->schedule_verification( array( $key ) );
422 -
423 - wp_send_json_success( $license );
424 - }
425 -
426 - $error = array(
427 - 'success' => false,
428 - 'data' => __( 'Verification failed.', 'sharing-image' ),
429 - );
430 -
431 - if ( isset( $answer['result'] ) ) {
432 - $error['code'] = $answer['result'];
433 - }
434 -
435 - $this->update_license( false, $key );
436 -
437 - wp_send_json( $error, 403 );
438 - }
439 -
440 - /**
441 - * Revoke Premium access from AJAX request.
442 - */
443 - public function revoke_premium_access() {
444 - $check = check_ajax_referer( basename( __FILE__ ), 'sharing_image_nonce', false );
445 -
446 - if ( false === $check ) {
447 - wp_send_json_error( __( 'Invalid security token. Reload the page and retry.', 'sharing-image' ), 403 );
448 - }
449 -
450 - // Remove license verification event.
451 - wp_unschedule_hook( self::EVENT_PREMIUM );
452 -
453 - // Disable Premium license.
454 - $license = $this->update_license( false );
455 -
456 - wp_send_json_success( $license );
457 - }
458 -
459 - /**
460 134 * Show plugin settings.
461 135 */
462 - public function display_settings() {
463 - if ( ! $this->is_settings_screen() ) {
136 + public static function display_settings() {
137 + if ( ! self::is_settings_screen() ) {
464 138 return;
465 139 }
466 140
467 141 include_once SHARING_IMAGE_DIR . 'templates/settings.php';
@@ -472,9 +146,9 @@
472 146 do_action( 'sharing_image_settings' );
473 147 }
474 148
475 149 /**
476 - * Fix .ttf files mime.
150 + * Fix .ttf and .otf files mime.
477 151 *
478 152 * @param array $types Values for the extension, mime type, and corrected filename.
479 153 * @param string $file Full path to the file.
480 154 * @param string $filename The name of the file (may differ from $file due to.
@@ -480,9 +154,9 @@
480 154 * @param string $filename The name of the file (may differ from $file due to.
481 155 *
482 156 * @return array List of file types.
483 157 */
484 - public function fix_ttf_mime_type( $types, $file, $filename ) {
158 + public static function fix_fonts_mime_type( $types, $file, $filename ) {
485 159 $extension = pathinfo( $filename, PATHINFO_EXTENSION );
486 160
487 161 if ( 'ttf' === $extension ) {
488 162 $types['ext'] = false;
@@ -488,24 +162,34 @@
488 162 $types['ext'] = false;
489 163
490 164 if ( current_user_can( 'manage_options' ) ) {
491 165 $types['ext'] = 'ttf';
492 - $types['type'] = 'application/x-font-ttf';
166 + $types['type'] = 'font/ttf';
493 167 }
494 168 }
495 169
170 + if ( 'otf' === $extension ) {
171 + $types['ext'] = false;
172 +
173 + if ( current_user_can( 'manage_options' ) ) {
174 + $types['ext'] = 'otf';
175 + $types['type'] = 'font/otf';
176 + }
177 + }
178 +
496 179 return $types;
497 180 }
498 181
499 182 /**
500 - * Add new .ttf font mime type.
183 + * Add new .ttf and .otf font mime types.
501 184 *
502 185 * @param array $types Allowed file types to upload.
503 186 *
504 187 * @return array Allowed file types to upload.
505 188 */
506 - public function add_ttf_mime_type( $types ) {
507 - $types['ttf'] = 'application/x-font-ttf';
189 + public static function add_fonts_mime_type( $types ) {
190 + $types['ttf'] = 'font/ttf';
191 + $types['otf'] = 'font/otf';
508 192
509 193 return $types;
510 194 }
511 195
@@ -511,16 +195,20 @@
511 195
512 196 /**
513 197 * Enqueue settings styles.
514 198 */
515 - public function enqueue_styles() {
516 - if ( ! $this->is_settings_screen() ) {
199 + public static function enqueue_styles() {
200 + if ( ! self::is_settings_screen() ) {
517 201 return;
518 202 }
519 203
204 + $asset = require SHARING_IMAGE_DIR . 'assets/settings/index.asset.php';
205 +
206 + wp_enqueue_media();
207 +
520 208 wp_enqueue_style(
521 209 'sharing-image-settings',
522 - SHARING_IMAGE_URL . 'assets/styles/settings.css',
210 + plugins_url( 'assets/settings/index.css', SHARING_IMAGE_FILE ),
523 211 array(),
524 212 SHARING_IMAGE_VERSION,
525 213 'all'
526 214 );
@@ -528,18 +216,20 @@
528 216
529 217 /**
530 218 * Enqueue settings scripts.
531 219 */
532 - public function enqueue_scripts() {
533 - if ( ! $this->is_settings_screen() ) {
220 + public static function enqueue_scripts() {
221 + if ( ! self::is_settings_screen() ) {
534 222 return;
535 223 }
536 224
225 + $asset = require SHARING_IMAGE_DIR . 'assets/widget/index.asset.php';
226 +
537 227 wp_enqueue_script(
538 228 'sharing-image-settings',
539 - SHARING_IMAGE_URL . 'assets/scripts/settings.js',
540 - array( 'wp-i18n', 'wp-polyfill-url', 'wp-polyfill-formdata' ),
541 - SHARING_IMAGE_VERSION,
229 + plugins_url( 'assets/settings/index.js', SHARING_IMAGE_FILE ),
230 + $asset['dependencies'],
231 + $asset['version'],
542 232 true
543 233 );
544 234
545 235 wp_enqueue_media();
@@ -546,9 +236,9 @@
546 236
547 237 // Translations availible only for WP 5.0+.
548 238 wp_set_script_translations( 'sharing-image-settings', 'sharing-image' );
549 239
550 - $object = $this->create_script_object();
240 + $object = self::create_script_object();
551 241
552 242 // Add settings script object.
553 243 wp_localize_script( 'sharing-image-settings', 'sharingImageSettings', $object );
554 244 }
@@ -553,243 +243,8 @@
553 243 wp_localize_script( 'sharing-image-settings', 'sharingImageSettings', $object );
554 244 }
555 245
556 246 /**
557 - * Get templates list from options.
558 - *
559 - * @return array List of templates.
560 - */
561 - public function get_templates() {
562 - $templates = get_option( self::OPTION_TEMPLATES, array() );
563 -
564 - if ( ! $this->is_premium_features() ) {
565 - $templates = array_slice( $templates, 0, 1 );
566 - }
567 -
568 - /**
569 - * Filters list of templates.
570 - *
571 - * @param array $templates List of templates.
572 - */
573 - return apply_filters( 'sharing_image_get_templates', $templates );
574 - }
575 -
576 - /**
577 - * Update templates using index.
578 - *
579 - * @param int $index Template index to update.
580 - * @param array $editor New template data.
581 - */
582 - public function update_templates( $index, $editor = null ) {
583 - // Method get_templates() is not used to save old templates during Premium switching.
584 - $templates = get_option( self::OPTION_TEMPLATES, array() );
585 -
586 - $templates[ $index ] = $editor;
587 -
588 - if ( null === $editor ) {
589 - unset( $templates[ $index ] );
590 - }
591 -
592 - /**
593 - * Filters list of templates before update in database.
594 - *
595 - * @param array $templates List of reindexed templates.
596 - */
597 - $templates = apply_filters( 'sharing_image_update_templates', array_values( $templates ) );
598 -
599 - return update_option( self::OPTION_TEMPLATES, $templates );
600 - }
601 -
602 - /**
603 - * Get plugin config settings.
604 - *
605 - * @return array List of plugin config settings.
606 - */
607 - public function get_config() {
608 - $config = get_option( self::OPTION_CONFIG, array() );
609 -
610 - /**
611 - * Filters settigns config.
612 - *
613 - * @param array List of plugin config settings.
614 - */
615 - return apply_filters( 'sharing_image_get_config', $config );
616 - }
617 -
618 - /**
619 - * Update config settings.
620 - *
621 - * @param array $config License settings config data.
622 - */
623 - public function update_config( $config ) {
624 - /**
625 - * Filters config options before their update in database.
626 - *
627 - * @param array $config Settings config data.
628 - */
629 - $config = apply_filters( 'sharing_image_update_config', $config );
630 -
631 - update_option( self::OPTION_CONFIG, $config );
632 - }
633 -
634 - /**
635 - * Get plugin license settings.
636 - *
637 - * @return array List of plugin license settings.
638 - */
639 - public function get_license() {
640 - $license = get_option( self::OPTION_LICENSE, array() );
641 -
642 - /**
643 - * Check if the plugin in development mode.
644 - *
645 - * @param bool Current development state. Disabled by default.
646 - */
647 - $develop = apply_filters( 'sharing_image_develop', false );
648 -
649 - if ( $develop ) {
650 - $license['develop'] = true;
651 - }
652 -
653 - /**
654 - * Filters license settings.
655 - *
656 - * @param array List of plugin license settings.
657 - */
658 - return apply_filters( 'sharing_image_get_license', $license );
659 - }
660 -
661 - /**
662 - * Set license options.
663 - *
664 - * @param bool $premium Premium status.
665 - * @param string $key License key.
666 - * @param string $error Verification error code.
667 -
668 - * @return array License options.
669 - */
670 - public function update_license( $premium, $key = '', $error = '' ) {
671 - $license = get_option( self::OPTION_LICENSE, array() );
672 -
673 - $license['premium'] = $premium;
674 -
675 - if ( ! empty( $key ) ) {
676 - $license['key'] = $key;
677 - }
678 -
679 - unset( $license['error'] );
680 -
681 - if ( ! empty( $error ) ) {
682 - $license['error'] = $error;
683 - }
684 -
685 - // Save updated license settings in database.
686 - update_option( self::OPTION_LICENSE, $license );
687 -
688 - return $license;
689 - }
690 -
691 - /**
692 - * Get directory to uploaded posters.
693 - *
694 - * @return array Path and url to upload directory.
695 - */
696 - public function get_upload_dir() {
697 - $config = $this->get_config();
698 -
699 - if ( ! isset( $config['uploads'] ) ) {
700 - $config['uploads'] = 'default';
701 - }
702 -
703 - // Create custom upload directory.
704 - if ( isset( $config['storage'] ) && 'custom' === $config['uploads'] ) {
705 - return $this->create_upload_dir( $config['storage'] );
706 - }
707 -
708 - $uploads = wp_upload_dir();
709 -
710 - /**
711 - * Filters upload directory.
712 - *
713 - * @param array $dir Path and url to upload directory.
714 - */
715 - return apply_filters( 'sharing_image_upload_dir', array( $uploads['path'], $uploads['url'] ) );
716 - }
717 -
718 - /**
719 - * Get generated image file format.
720 - *
721 - * @param string $format Optional. Default image format.
722 -
723 - * @return string Image file format.
724 - */
725 - public function get_file_format( $format = 'jpg' ) {
726 - $config = $this->get_config();
727 -
728 - if ( isset( $config['format'] ) ) {
729 - $format = $config['format'];
730 - }
731 -
732 - /**
733 - * Filters Image file format.
734 - *
735 - * @param string $format Image file format.
736 - */
737 - return apply_filters( 'sharing_image_file_format', $format );
738 - }
739 -
740 - /**
741 - * Get quality of generated poster.
742 - *
743 - * @param int $quality Optional. Default image quality.
744 - *
745 - * @return int Image quality.
746 - */
747 - public function get_quality( $quality = 90 ) {
748 - $config = $this->get_config();
749 -
750 - if ( isset( $config['quality'] ) ) {
751 - $quality = $config['quality'];
752 - }
753 -
754 - /**
755 - * Filters poster image quality.
756 - *
757 - * @param string $quality Image quality.
758 - */
759 - return apply_filters( 'sharing_image_poster_quality', $quality );
760 - }
761 -
762 - /**
763 - * Try to get default poster image data.
764 - * Returns array with image url, width and height.
765 - *
766 - * @see https://developer.wordpress.org/reference/functions/wp_get_attachment_image_src/
767 - *
768 - * @return array|false Array of image data, or boolean false if no image is available.
769 - */
770 - public function get_default_poster_src() {
771 - $config = $this->get_config();
772 -
773 - if ( empty( $config['default'] ) ) {
774 - return false;
775 - }
776 -
777 - $poster = wp_get_attachment_image_src( $config['default'], 'full' );
778 -
779 - if ( is_array( $poster ) ) {
780 - $poster = array_slice( $poster, 0, 3 );
781 - }
782 -
783 - /**
784 - * Filters default poster data.
785 - *
786 - * @param array|false Array of image data, or boolean false if no image is available.
787 - */
788 - return apply_filters( 'sharing_image_default_poster_src', $poster );
789 - }
790 -
791 - /**
792 247 * Update settings page title.
793 248 *
794 249 * @param string $title Plugin settings page title.
795 250 *
@@ -794,99 +249,34 @@
794 249 * @param string $title Plugin settings page title.
795 250 *
796 251 * @return string Plugin settings title
797 252 */
798 - public function update_settings_title( $title ) {
799 - if ( ! $this->is_settings_screen() ) {
253 + public static function update_settings_title( $title ) {
254 + if ( ! self::is_settings_screen() ) {
800 255 return $title;
801 256 }
802 257
803 - $tab = $this->get_current_tab();
258 + $tab = self::get_current_tab();
804 259
805 - if ( null === $tab ) {
260 + if ( is_null( $tab ) ) {
806 261 return $title;
807 262 }
808 263
809 - if ( empty( $this->tabs[ $tab ]['label'] ) ) {
264 + if ( empty( self::$tabs[ $tab ]['label'] ) ) {
810 265 return $title;
811 266 }
812 267
813 - $label = esc_html( $this->tabs[ $tab ]['label'] );
268 + $label = esc_html( self::$tabs[ $tab ]['label'] );
814 269
815 270 return sprintf( '%s – %s', $label, $title );
816 271 }
817 272
818 273 /**
819 - * Launch scheduled license verification event.
820 - * Do not disable Premium if the verification server does not respond.
821 - *
822 - * @param string $key License key.
823 - */
824 - public function launch_verification_event( $key ) {
825 - $args = array(
826 - 'body' => array(
827 - 'key' => $key,
828 - 'domain' => wp_parse_url( site_url(), PHP_URL_HOST ),
829 - ),
830 - );
831 -
832 - $response = wp_remote_post( self::REMOTE_LICENSES, $args );
833 -
834 - if ( is_wp_error( $response ) ) {
835 - return;
836 - }
837 -
838 - $answer = json_decode( $response['body'], true );
839 -
840 - if ( ! isset( $answer['success'] ) ) {
841 - return;
842 - }
843 -
844 - if ( true === $answer['success'] ) {
845 - return $this->update_license( true, $key );
846 - }
847 -
848 - if ( ! isset( $answer['result'] ) ) {
849 - return $this->update_license( false, $key );
850 - }
851 -
852 - $this->update_license( false, $key, $answer['result'] );
853 - }
854 -
855 - /**
856 - * Check if Premium features availible.
857 - *
858 - * @return bool Whether premium featured enabled.
859 - */
860 - public function is_premium_features() {
861 - $license = $this->get_license();
862 -
863 - if ( ! empty( $license['premium'] ) || ! empty( $license['develop'] ) ) {
864 - return true;
865 - }
866 -
867 - return false;
868 - }
869 -
870 - /**
871 - * Schedule license verification.
872 - *
873 - * @param array $args List of event arguments. License key by default.
874 - */
875 - public function schedule_verification( $args = array() ) {
876 - if ( wp_next_scheduled( self::EVENT_PREMIUM, $args ) ) {
877 - return;
878 - }
879 -
880 - wp_schedule_event( time() + DAY_IN_SECONDS / 2, 'twicedaily', self::EVENT_PREMIUM, $args );
881 - }
882 -
883 - /**
884 274 * Create script object to inject with settings.
885 275 *
886 276 * @return array Filtered script settings object.
887 277 */
888 - private function create_script_object() {
278 + private static function create_script_object() {
889 279 $uploads = wp_get_upload_dir();
890 280
891 281 // Get uploads directory path from WordPress root.
892 282 $basedir = str_replace( ABSPATH, '', $uploads['basedir'] );
@@ -891,19 +281,21 @@
891 281 // Get uploads directory path from WordPress root.
892 282 $basedir = str_replace( ABSPATH, '', $uploads['basedir'] );
893 283
894 284 $object = array(
895 - 'nonce' => wp_create_nonce( basename( __FILE__ ) ),
285 + 'nonce' => wp_create_nonce( self::SETTINGS_NONCE ),
896 286 'links' => array(
897 287 'uploads' => esc_url( admin_url( 'upload.php' ) ),
898 288 'action' => esc_url( admin_url( 'admin-post.php' ) ),
899 - 'premium' => esc_url_raw( $this->get_tab_link( 'premium' ) ),
289 + 'premium' => esc_url_raw( self::get_tab_link( 'premium' ) ),
900 290 'storage' => path_join( $basedir, 'sharing-image' ),
901 291 ),
902 - 'templates' => $this->get_templates(),
903 - 'config' => $this->get_config(),
904 - 'license' => $this->get_license(),
905 - 'fonts' => $this->get_fonts(),
292 + 'fonts' => self::get_fonts(),
293 + 'templates' => Templates::get_templates(),
294 + 'index' => Templates::create_unique_index(),
295 + 'snippets' => Snippets::get_snippets(),
296 + 'config' => Config::get_config(),
297 + 'license' => Premium::get_license(),
906 298 );
907 299
908 300 /**
909 301 * Filters settings script object.
@@ -913,401 +305,14 @@
913 305 return apply_filters( 'sharing_image_settings_object', $object );
914 306 }
915 307
916 308 /**
917 - * Sanitize editor template settings.
918 - *
919 - * @param array $editor Template editor settings.
920 - *
921 - * @return array
922 - */
923 - private function sanitize_editor( $editor ) {
924 - $sanitized = array();
925 -
926 - if ( ! empty( $editor['preview'] ) ) {
927 - $sanitized['preview'] = sanitize_text_field( $editor['preview'] );
928 - }
929 -
930 - if ( ! empty( $editor['title'] ) ) {
931 - $sanitized['title'] = sanitize_text_field( $editor['title'] );
932 - }
933 -
934 - if ( ! empty( $editor['attachment'] ) ) {
935 - $sanitized['attachment'] = absint( $editor['attachment'] );
936 - }
937 -
938 - if ( ! empty( $editor['suspend'] ) ) {
939 - $sanitized['suspend'] = 'suspend';
940 - }
941 -
942 - $sanitized['fill'] = '#000000';
943 -
944 - if ( ! empty( $editor['fill'] ) ) {
945 - $sanitized['fill'] = sanitize_hex_color( $editor['fill'] );
946 - }
947 -
948 - $sanitized['background'] = 'blank';
949 -
950 - if ( isset( $editor['background'] ) ) {
951 - $background = array( 'dynamic', 'blank', 'permanent' );
952 -
953 - // Set default background for permanent option without attachment.
954 - if ( empty( $sanitized['attachment'] ) ) {
955 - $background = array_diff( $background, array( 'permanent' ) );
956 - }
957 -
958 - if ( in_array( $editor['background'], $background, true ) ) {
959 - $sanitized['background'] = $editor['background'];
960 - }
961 - }
962 -
963 - $sanitized['width'] = 1200;
964 -
965 - if ( ! empty( $editor['width'] ) ) {
966 - $sanitized['width'] = absint( $editor['width'] );
967 - }
968 -
969 - $sanitized['height'] = 630;
970 -
971 - if ( ! empty( $editor['height'] ) ) {
972 - $sanitized['height'] = absint( $editor['height'] );
973 - }
974 -
975 - if ( isset( $editor['layers'] ) && is_array( $editor['layers'] ) ) {
976 - $layers = array();
977 -
978 - foreach ( $editor['layers'] as $layer ) {
979 - if ( empty( $layer['type'] ) ) {
980 - continue;
981 - }
982 -
983 - switch ( $layer['type'] ) {
984 - case 'text':
985 - $layers[] = $this->sanitize_text_layer( $layer );
986 - break;
987 -
988 - case 'image':
989 - $layers[] = $this->sanitize_image_layer( $layer );
990 - break;
991 -
992 - case 'filter':
993 - $layers[] = $this->sanitize_filter_layer( $layer );
994 - break;
995 -
996 - case 'rectangle':
997 - $layers[] = $this->sanitize_rectangle_layer( $layer );
998 - break;
999 - }
1000 - }
1001 -
1002 - $sanitized['layers'] = $layers;
1003 - }
1004 -
1005 - /**
1006 - * Filters template editor sanitized fields.
1007 - *
1008 - * @param array $sanitized List of sanitized editor fields.
1009 - * @param array $editor List of editor fields before sanitization.
1010 - */
1011 - return apply_filters( 'sharing_image_sanitize_editor', $sanitized, $editor );
1012 - }
1013 -
1014 - /**
1015 - * Sanitize template editor text layer.
1016 - *
1017 - * @param array $layer Layer settings.
1018 - *
1019 - * @return array Sanitized layer settings.
1020 - */
1021 - private function sanitize_text_layer( $layer ) {
1022 - $sanitized = array();
1023 -
1024 - // No need to sanitize after switch.
1025 - $sanitized['type'] = $layer['type'];
1026 -
1027 - if ( ! empty( $layer['dynamic'] ) ) {
1028 - $sanitized['dynamic'] = 'dynamic';
1029 - }
1030 -
1031 - if ( isset( $layer['title'] ) ) {
1032 - $sanitized['title'] = sanitize_text_field( $layer['title'] );
1033 - }
1034 -
1035 - if ( isset( $layer['content'] ) ) {
1036 - $sanitized['content'] = sanitize_textarea_field( $layer['content'] );
1037 - }
1038 -
1039 - if ( isset( $layer['sample'] ) ) {
1040 - $sanitized['sample'] = sanitize_textarea_field( $layer['sample'] );
1041 - }
1042 -
1043 - $sanitized['preset'] = 'none';
1044 -
1045 - if ( isset( $layer['preset'] ) ) {
1046 - $preset = array( 'title', 'excerpt' );
1047 -
1048 - if ( in_array( $layer['preset'], $preset, true ) ) {
1049 - $sanitized['preset'] = $layer['preset'];
1050 - }
1051 - }
1052 -
1053 - $sanitized['color'] = '#ffffff';
1054 -
1055 - if ( ! empty( $layer['color'] ) ) {
1056 - $sanitized['color'] = sanitize_hex_color( $layer['color'] );
1057 - }
1058 -
1059 - $sanitized['horizontal'] = 'left';
1060 -
1061 - if ( isset( $layer['horizontal'] ) ) {
1062 - $horizontal = array( 'center', 'right' );
1063 -
1064 - if ( in_array( $layer['horizontal'], $horizontal, true ) ) {
1065 - $sanitized['horizontal'] = $layer['horizontal'];
1066 - }
1067 - }
1068 -
1069 - $sanitized['vertical'] = 'top';
1070 -
1071 - if ( isset( $layer['vertical'] ) ) {
1072 - $vertical = array( 'center', 'bottom' );
1073 -
1074 - if ( in_array( $layer['vertical'], $vertical, true ) ) {
1075 - $sanitized['vertical'] = $layer['vertical'];
1076 - }
1077 - }
1078 -
1079 - if ( isset( $layer['fontsize'] ) ) {
1080 - $sanitized['fontsize'] = absint( $layer['fontsize'] );
1081 - }
1082 -
1083 - if ( isset( $layer['lineheight'] ) ) {
1084 - $sanitized['lineheight'] = (float) $layer['lineheight'];
1085 - }
1086 -
1087 - if ( isset( $layer['fontname'] ) ) {
1088 - $sanitized['fontname'] = sanitize_text_field( $layer['fontname'] );
1089 - }
1090 -
1091 - if ( ! empty( $layer['fontfile'] ) ) {
1092 - $sanitized['fontfile'] = absint( $layer['fontfile'] );
1093 - }
1094 -
1095 - $sizes = array( 'x', 'y', 'width', 'height' );
1096 -
1097 - foreach ( $sizes as $size ) {
1098 - if ( ! isset( $layer[ $size ] ) || '' === $layer[ $size ] ) {
1099 - continue;
1100 - }
1101 -
1102 - $sanitized[ $size ] = absint( $layer[ $size ] );
1103 - }
1104 -
1105 - return $sanitized;
1106 - }
1107 -
1108 - /**
1109 - * Sanitize template editor image layer.
1110 - *
1111 - * @param array $layer Layer settings.
1112 - *
1113 - * @return array Sanitized image layer settings.
1114 - */
1115 - private function sanitize_image_layer( $layer ) {
1116 - $sanitized = array();
1117 -
1118 - // No need to sanitize after switch.
1119 - $sanitized['type'] = $layer['type'];
1120 -
1121 - if ( ! empty( $layer['attachment'] ) ) {
1122 - $sanitized['attachment'] = absint( $layer['attachment'] );
1123 - }
1124 -
1125 - $sizes = array( 'x', 'y', 'width', 'height' );
1126 -
1127 - foreach ( $sizes as $size ) {
1128 - if ( ! isset( $layer[ $size ] ) || '' === $layer[ $size ] ) {
1129 - continue;
1130 - }
1131 -
1132 - $sanitized[ $size ] = absint( $layer[ $size ] );
1133 - }
1134 -
1135 - return $sanitized;
1136 - }
1137 -
1138 - /**
1139 - * Sanitize template editor filter layer.
1140 - *
1141 - * @param array $layer Layer settings.
1142 - *
1143 - * @return array Sanitized filter layer settings.
1144 - */
1145 - private function sanitize_filter_layer( $layer ) {
1146 - $sanitized = array();
1147 -
1148 - // No need to sanitize after switch.
1149 - $sanitized['type'] = $layer['type'];
1150 -
1151 - if ( ! empty( $layer['grayscale'] ) ) {
1152 - $sanitized['grayscale'] = 'grayscale';
1153 - }
1154 -
1155 - if ( ! empty( $layer['blur'] ) ) {
1156 - $sanitized['blur'] = 'blur';
1157 - }
1158 -
1159 - $sanitized['brightness'] = 0;
1160 -
1161 - if ( isset( $layer['brightness'] ) ) {
1162 - $brightness = (int) $layer['brightness'];
1163 -
1164 - if ( $brightness >= -100 && $brightness <= 100 ) {
1165 - $sanitized['brightness'] = $brightness;
1166 - }
1167 - }
1168 -
1169 - $sanitized['contrast'] = 0;
1170 -
1171 - if ( isset( $layer['contrast'] ) ) {
1172 - $contrast = (int) $layer['contrast'];
1173 -
1174 - if ( $contrast >= -100 && $contrast <= 100 ) {
1175 - $sanitized['contrast'] = $contrast;
1176 - }
1177 - }
1178 -
1179 - $sanitized['blackout'] = 0;
1180 -
1181 - if ( isset( $layer['blackout'] ) ) {
1182 - $blackout = (int) $layer['blackout'];
1183 -
1184 - if ( $blackout >= 0 && $blackout <= 100 ) {
1185 - $sanitized['blackout'] = $blackout;
1186 - }
1187 - }
1188 -
1189 - return $sanitized;
1190 - }
1191 -
1192 - /**
1193 - * Sanitize template editor rectagle layer.
1194 - *
1195 - * @param array $layer Layer settings.
1196 - *
1197 - * @return array Sanitized rectangle layer settings.
1198 - */
1199 - private function sanitize_rectangle_layer( $layer ) {
1200 - $sanitized = array();
1201 -
1202 - // No need to sanitize after switch.
1203 - $sanitized['type'] = $layer['type'];
1204 -
1205 - if ( ! empty( $layer['outline'] ) ) {
1206 - $sanitized['outline'] = 'outline';
1207 - }
1208 -
1209 - $sanitized['color'] = '#ffffff';
1210 -
1211 - if ( ! empty( $layer['color'] ) ) {
1212 - $sanitized['color'] = sanitize_hex_color( $layer['color'] );
1213 - }
1214 -
1215 - $sanitized['opacity'] = 0;
1216 -
1217 - if ( isset( $layer['opacity'] ) ) {
1218 - $opacity = (float) $layer['opacity'];
1219 -
1220 - if ( $opacity >= 0 && $opacity <= 100 ) {
1221 - $sanitized['opacity'] = $opacity;
1222 - }
1223 - }
1224 -
1225 - $sanitized['thickness'] = 0;
1226 -
1227 - if ( isset( $layer['thickness'] ) ) {
1228 - $thickness = (int) $layer['thickness'];
1229 -
1230 - if ( $thickness >= 0 && $thickness <= 50 ) {
1231 - $sanitized['thickness'] = $thickness;
1232 - }
1233 - }
1234 -
1235 - $sizes = array( 'x', 'y', 'width', 'height' );
1236 -
1237 - foreach ( $sizes as $size ) {
1238 - if ( ! isset( $layer[ $size ] ) || '' === $layer[ $size ] ) {
1239 - continue;
1240 - }
1241 -
1242 - $sanitized[ $size ] = absint( $layer[ $size ] );
1243 - }
1244 -
1245 - return $sanitized;
1246 - }
1247 -
1248 - /**
1249 - * Sanitize config settings.
1250 - *
1251 - * @param array $config Config settings.
1252 - *
1253 - * @return array Sanitized config settings.
1254 - */
1255 - private function sanitize_config( $config ) {
1256 - $sanitized = array();
1257 -
1258 - if ( ! empty( $config['default'] ) ) {
1259 - $sanitized['default'] = absint( $config['default'] );
1260 - }
1261 -
1262 - $sanitized['format'] = 'jpg';
1263 -
1264 - if ( isset( $config['format'] ) ) {
1265 - $format = $config['format'];
1266 -
1267 - if ( in_array( $format, array( 'jpg', 'png' ), true ) ) {
1268 - $sanitized['format'] = $config['format'];
1269 - }
1270 - }
1271 -
1272 - if ( isset( $config['quality'] ) ) {
1273 - $quality = (int) $config['quality'];
1274 -
1275 - if ( $quality >= 1 && $quality <= 100 ) {
1276 - $sanitized['quality'] = $quality;
1277 - }
1278 - }
1279 -
1280 - $sanitized['uploads'] = 'default';
1281 -
1282 - if ( isset( $config['uploads'] ) ) {
1283 - $uploads = $config['uploads'];
1284 -
1285 - if ( in_array( $uploads, array( 'custom', 'default' ), true ) ) {
1286 - $sanitized['uploads'] = $config['uploads'];
1287 - }
1288 - }
1289 -
1290 - if ( isset( $config['storage'] ) ) {
1291 - $sanitized['storage'] = sanitize_text_field( $config['storage'] );
1292 - }
1293 -
1294 - /**
1295 - * Filters template editor sanitized fields.
1296 - *
1297 - * @param array $sanitized List of sanitized config fields.
1298 - * @param array $config List of config fields before sanitization.
1299 - */
1300 - return apply_filters( 'sharing_image_sanitize_config', $sanitized, $config );
1301 - }
1302 -
1303 - /**
1304 309 * Show settings tab template.
1305 310 */
1306 - private function show_settings_section() {
1307 - $tab = $this->get_current_tab();
311 + private static function show_settings_section() {
312 + $tab = self::get_current_tab();
1308 313
1309 - if ( null === $tab ) {
314 + if ( is_null( $tab ) ) {
1310 315 return;
1311 316 }
1312 317
1313 318 include_once SHARING_IMAGE_DIR . "templates/{$tab}.php";
@@ -1315,32 +320,60 @@
1315 320
1316 321 /**
1317 322 * Show settings messages and errors after post actions.
1318 323 */
1319 - private function show_settings_message() {
324 + private static function show_settings_message() {
1320 325 // phpcs:ignore WordPress.Security.NonceVerification
1321 326 $message = isset( $_GET['message'] ) ? absint( $_GET['message'] ) : 0;
1322 327
1323 328 switch ( $message ) {
1324 329 case 1:
1325 - add_settings_error( 'sharing-image', 'sharing-image', __( 'Settings successfully updated.', 'sharing-image' ), 'updated' );
330 + add_settings_error( 'sharing-image', 'sharing-image', __( 'Settings updated successfully.', 'sharing-image' ), 'updated' );
1326 331 break;
1327 332
1328 333 case 2:
1329 - add_settings_error( 'sharing-image', 'sharing-image', __( 'Failed to save template settings.', 'sharing-image' ) );
334 + add_settings_error( 'sharing-image', 'sharing-image', __( 'Unable to save template settings.', 'sharing-image' ) );
1330 335 break;
1331 336
1332 337 case 3:
1333 - add_settings_error( 'sharing-image', 'sharing-image', __( 'Template successfully deleted.', 'sharing-image' ), 'updated' );
338 + add_settings_error( 'sharing-image', 'sharing-image', __( 'Template deleted successfully.', 'sharing-image' ), 'updated' );
1334 339 break;
1335 340
1336 341 case 4:
1337 - add_settings_error( 'sharing-image', 'sharing-image', __( 'Failed to delete template.', 'sharing-image' ) );
342 + add_settings_error( 'sharing-image', 'sharing-image', __( 'Unable to delete template.', 'sharing-image' ) );
1338 343 break;
1339 344
1340 345 case 5:
1341 - add_settings_error( 'sharing-image', 'sharing-image', __( 'Failed to save configuration settings.', 'sharing-image' ) );
346 + add_settings_error( 'sharing-image', 'sharing-image', __( 'Unable to save configuration settings.', 'sharing-image' ) );
1342 347 break;
348 +
349 + case 6:
350 + add_settings_error( 'sharing-image', 'sharing-image', __( 'Error uploading file. Please try again.', 'sharing-image' ) );
351 + break;
352 +
353 + case 7:
354 + add_settings_error( 'sharing-image', 'sharing-image', __( 'The imported file is empty.', 'sharing-image' ) );
355 + break;
356 +
357 + case 8:
358 + add_settings_error( 'sharing-image', 'sharing-image', __( 'The maximum allowed number of templates has been reached. Please upgrade to Premium.', 'sharing-image' ) );
359 + break;
360 +
361 + case 9:
362 + add_settings_error( 'sharing-image', 'sharing-image', __( 'Templates imported successfully.', 'sharing-image' ), 'updated' );
363 + break;
364 +
365 + case 10:
366 + add_settings_error( 'sharing-image', 'sharing-image', __( 'Unable to clone template.', 'sharing-image' ) );
367 + break;
368 +
369 + case 11:
370 + add_settings_error( 'sharing-image', 'sharing-image', __( 'Template cloned successfully.', 'sharing-image' ), 'updated' );
371 + break;
372 +
373 + case 12:
374 + add_settings_error( 'sharing-image', 'sharing-image', __( 'Posters removed successfully.', 'sharing-image' ), 'updated' );
375 + break;
1343 376 }
1344 377
1345 378 settings_errors( 'sharing-image' );
1346 379 }
@@ -1347,9 +380,9 @@
1347 380
1348 381 /**
1349 382 * Set list of settings page tabs.
1350 383 */
1351 - private function init_tabs() {
384 + public static function init_tabs() {
1352 385 $tabs = array(
1353 386 'templates' => array(
1354 387 'label' => __( 'Templates', 'sharing-image' ),
1355 388 'link' => admin_url( 'options-general.php?page=' . self::SETTINGS_SLUG ),
@@ -1358,8 +391,12 @@
1358 391 'config' => array(
1359 392 'label' => __( 'Configuration', 'sharing-image' ),
1360 393 'link' => admin_url( 'options-general.php?page=' . self::SETTINGS_SLUG . '&tab=config' ),
1361 394 ),
395 + 'tools' => array(
396 + 'label' => __( 'Tools', 'sharing-image' ),
397 + 'link' => admin_url( 'options-general.php?page=' . self::SETTINGS_SLUG . '&tab=tools' ),
398 + ),
1362 399 'premium' => array(
1363 400 'label' => __( 'Premium', 'sharing-image' ),
1364 401 'link' => admin_url( 'options-general.php?page=' . self::SETTINGS_SLUG . '&tab=premium' ),
1365 402 ),
@@ -1369,18 +406,18 @@
1369 406 * Filters tabs in settings page.
1370 407 *
1371 408 * @param array $tabs List of settings tabs.
1372 409 */
1373 - $this->tabs = apply_filters( 'sharing_image_settings_tabs', $tabs );
410 + self::$tabs = apply_filters( 'sharing_image_settings_tabs', $tabs );
1374 411 }
1375 412
1376 413 /**
1377 414 * Print menu on settings page.
1378 415 */
1379 - private function show_settings_menu() {
1380 - $current = $this->get_current_tab();
416 + private static function show_settings_menu() {
417 + $current = self::get_current_tab();
1381 418
1382 - foreach ( $this->tabs as $tab => $args ) {
419 + foreach ( self::$tabs as $tab => $args ) {
1383 420 $classes = array(
1384 421 'sharing-image-tab',
1385 422 );
1386 423
@@ -1387,9 +424,9 @@
1387 424 if ( $current === $tab ) {
1388 425 $classes[] = 'active';
1389 426 }
1390 427
1391 - if ( null === $current && ! empty( $args['default'] ) ) {
428 + if ( is_null( $current ) && ! empty( $args['default'] ) ) {
1392 429 $classes[] = 'active';
1393 430 }
1394 431
1395 432 printf(
@@ -1405,16 +442,19 @@
1405 442 * Get availible fonts.
1406 443 *
1407 444 * @return array List of availible poster fonts.
1408 445 */
1409 - private function get_fonts() {
446 + private static function get_fonts() {
1410 447 $fonts = array(
1411 - 'open-sans' => 'Open Sans',
1412 - 'merriweather' => 'Merriweather',
1413 - 'roboto-slab' => 'Roboto Slab',
1414 - 'ubuntu' => 'Ubuntu',
1415 - 'rubik-bold' => 'Rubik Bold',
1416 - 'montserrat' => 'Montserrat',
448 + 'open-sans' => 'Open Sans',
449 + 'open-sans-light' => 'Open Sans Light',
450 + 'open-sans-bold' => 'Open Sans Bold',
451 + 'merriweather' => 'Merriweather',
452 + 'roboto-slab' => 'Roboto Slab',
453 + 'ubuntu' => 'Ubuntu',
454 + 'rubik-bold' => 'Rubik Bold',
455 + 'alice' => 'Alice',
456 + 'lobster' => 'Lobster',
1417 457 );
1418 458
1419 459 /**
1420 460 * Filters poster fonts.
@@ -1430,14 +470,14 @@
1430 470 * @param string $tab Tab name.
1431 471 *
1432 472 * @return string|null Tab link.
1433 473 */
1434 - private function get_tab_link( $tab ) {
1435 - if ( empty( $this->tabs[ $tab ]['link'] ) ) {
1436 - return null;
474 + public static function get_tab_link( $tab ) {
475 + if ( empty( self::$tabs[ $tab ]['link'] ) ) {
476 + return admin_url( 'options-general.php?page=' . self::SETTINGS_SLUG );
1437 477 }
1438 478
1439 - return $this->tabs[ $tab ]['link'];
479 + return self::$tabs[ $tab ]['link'];
1440 480 }
1441 481
1442 482 /**
1443 483 * Get current tab.
@@ -1443,14 +483,14 @@
1443 483 * Get current tab.
1444 484 *
1445 485 * @return string|null Current tab name.
1446 486 */
1447 - private function get_current_tab() {
487 + public static function get_current_tab() {
1448 488 // phpcs:disable WordPress.Security.NonceVerification
1449 489 if ( ! empty( $_GET['tab'] ) ) {
1450 490 $tab = sanitize_file_name( wp_unslash( $_GET['tab'] ) );
1451 491
1452 - if ( array_key_exists( $tab, $this->tabs ) ) {
492 + if ( array_key_exists( $tab, self::$tabs ) ) {
1453 493 return $tab;
1454 494 }
1455 495 }
1456 496 // phpcs:enable WordPress.Security.NonceVerification
@@ -1458,40 +498,17 @@
1458 498 return null;
1459 499 }
1460 500
1461 501 /**
1462 - * Create upload directory and return its path and url
1463 - *
1464 - * @param string $storage Relative directory path.
1465 - *
1466 - * @return array Path and url to upload directory.
1467 - */
1468 - private function create_upload_dir( $storage ) {
1469 - $storage = trim( $storage, '/' );
1470 -
1471 - /**
1472 - * Change permissions when creating new folders.
1473 - *
1474 - * @param int $permissions New directory access permissions. By default 0755.
1475 - */
1476 - $permissions = apply_filters( 'sharing_image_directory_permissions', 0755 );
1477 -
1478 - // We do not pay attention to the possible error.
1479 - mkdir( ABSPATH . $storage, $permissions, true );
1480 -
1481 - return array( ABSPATH . $storage, site_url( $storage ) );
1482 - }
1483 -
1484 - /**
1485 502 * Add message id to the back link and redirect
1486 503 *
1487 - * @param string $return Redirect link.
1488 - * @param int $message Settings error message id.
504 + * @param string $redirect Redirect link.
505 + * @param int $message Settings error message id.
1489 506 */
1490 - private function redirect_with_message( $return, $message ) {
1491 - $return = add_query_arg( array( 'message' => $message ), $return );
507 + public static function redirect_with_message( $redirect, $message ) {
508 + $redirect = add_query_arg( array( 'message' => $message ), $redirect );
1492 509
1493 - wp_safe_redirect( $return );
510 + wp_safe_redirect( $redirect );
1494 511 exit;
1495 512 }
1496 513
1497 514 /**
@@ -1498,9 +515,9 @@
1498 515 * Is current admin screen the plugin options screen.
1499 516 *
1500 517 * @return bool Whether the settings screen of this plugin is displayed or not.
1501 518 */
1502 - private function is_settings_screen() {
519 + private static function is_settings_screen() {
1503 520 $current_screen = get_current_screen();
1504 521
1505 522 if ( $current_screen && self::SCREEN_ID === $current_screen->id ) {
1506 523 return true;