', 'rocket' ), 'type' => 'fields_container', 'description' => __( 'Reduces overhead of database tables', 'rocket' ), 'page' => 'database', ], 'schedule_cleanup_section' => [ 'title' => __( 'Automatic Cleanup', 'rocket' ), 'type' => 'fields_container', 'page' => 'database', ], ] ); $this->settings->add_settings_fields( [ 'database_revisions' => [ 'type' => 'checkbox', 'label' => __( 'Revisions', 'rocket' ), // translators: %s is the number of revisions found in the database. It's a formatted number, don't use %d. 'description' => sprintf( _n( '%s revision in your database.', '%s revisions in your database.', $total['database_revisions'], 'rocket' ), number_format_i18n( $total['database_revisions'] ) ), 'section' => 'post_cleanup_section', 'page' => 'database', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], 'database_auto_drafts' => [ 'type' => 'checkbox', 'label' => __( 'Auto Drafts', 'rocket' ), // translators: %s is the number of revisions found in the database. It's a formatted number, don't use %d. 'description' => sprintf( _n( '%s draft in your database.', '%s drafts in your database.', $total['database_auto_drafts'], 'rocket' ), number_format_i18n( $total['database_auto_drafts'] ) ), 'section' => 'post_cleanup_section', 'page' => 'database', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], 'database_trashed_posts' => [ 'type' => 'checkbox', 'label' => __( 'Trashed Posts', 'rocket' ), // translators: %s is the number of revisions found in the database. It's a formatted number, don't use %d. 'description' => sprintf( _n( '%s trashed post in your database.', '%s trashed posts in your database.', $total['database_trashed_posts'], 'rocket' ), $total['database_trashed_posts'] ), 'section' => 'post_cleanup_section', 'page' => 'database', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], 'database_spam_comments' => [ 'type' => 'checkbox', 'label' => __( 'Spam Comments', 'rocket' ), // translators: %s is the number of revisions found in the database. It's a formatted number, don't use %d. 'description' => sprintf( _n( '%s spam comment in your database.', '%s spam comments in your database.', $total['database_spam_comments'], 'rocket' ), number_format_i18n( $total['database_spam_comments'] ) ), 'section' => 'comments_cleanup_section', 'page' => 'database', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], 'database_trashed_comments' => [ 'type' => 'checkbox', 'label' => __( 'Trashed Comments', 'rocket' ), // translators: %s is the number of revisions found in the database. It's a formatted number, don't use %d. 'description' => sprintf( _n( '%s trashed comment in your database.', '%s trashed comments in your database.', $total['database_trashed_comments'], 'rocket' ), number_format_i18n( $total['database_trashed_comments'] ) ), 'section' => 'comments_cleanup_section', 'page' => 'database', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], 'database_all_transients' => [ 'type' => 'checkbox', 'label' => __( 'All transients', 'rocket' ), // translators: %s is the number of revisions found in the database. It's a formatted number, don't use %d. 'description' => sprintf( _n( '%s transient in your database.', '%s transients in your database.', $total['database_all_transients'], 'rocket' ), number_format_i18n( $total['database_all_transients'] ) ), 'section' => 'transients_cleanup_section', 'page' => 'database', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], 'database_optimize_tables' => [ 'type' => 'checkbox', 'label' => __( 'Optimize Tables', 'rocket' ), // translators: %s is the number of revisions found in the database. It's a formatted number, don't use %d. 'description' => sprintf( _n( '%s table to optimize in your database.', '%s tables to optimize in your database.', $total['database_optimize_tables'], 'rocket' ), number_format_i18n( $total['database_optimize_tables'] ) ), 'section' => 'database_cleanup_section', 'page' => 'database', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], 'schedule_automatic_cleanup' => [ 'container_class' => [ 'wpr-isParent', ], 'type' => 'checkbox', 'label' => __( 'Schedule Automatic Cleanup', 'rocket' ), 'description' => '', 'section' => 'schedule_cleanup_section', 'page' => 'database', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], 'automatic_cleanup_frequency' => [ 'container_class' => [ 'wpr-field--children', ], 'type' => 'select', 'label' => __( 'Frequency', 'rocket' ), 'description' => '', 'parent' => 'schedule_automatic_cleanup', 'section' => 'schedule_cleanup_section', 'page' => 'database', 'default' => 'daily', 'sanitize_callback' => 'sanitize_text_field', 'choices' => [ 'daily' => __( 'Daily', 'rocket' ), 'weekly' => __( 'Weekly', 'rocket' ), 'monthly' => __( 'Monthly', 'rocket' ), ], ], ] ); } /** * Registers CDN section * * @since 3.0 */ private function cdn_section() { $this->settings->add_page_section( 'page_cdn', [ 'title' => __( 'CDN', 'rocket' ), 'menu_description' => __( 'Integrate your CDN', 'rocket' ), ] ); $cdn_beacon = $this->beacon->get_suggest( 'cdn' ); $cdn_exclude_beacon = $this->beacon->get_suggest( 'exclude_cdn' ); $this->settings->add_settings_sections( [ 'cdn_section' => [ 'title' => __( 'CDN', 'rocket' ), 'type' => 'fields_container', 'description' => __( 'All URLs of static files (CSS, JS, images) will be rewritten to the CNAME(s) you provide.', 'rocket' ) . '
' . sprintf( // translators: %1$s = opening link tag, %2$s = closing link tag. __( 'Not required for services like Cloudflare and Sucuri. Please see our available %1$sAdd-ons%2$s.', 'rocket' ), '', '' ) . '', 'help' => [ 'id' => $this->beacon->get_suggest( 'cdn_section' ), 'url' => $cdn_beacon['url'], ], 'page' => 'page_cdn', ], 'cnames_section' => [ 'type' => 'nocontainer', 'page' => 'page_cdn', ], 'exclude_cdn_section' => [ 'title' => __( 'Exclude files from CDN', 'rocket' ), 'type' => 'fields_container', 'help' => [ 'id' => $cdn_exclude_beacon['id'], 'url' => $cdn_exclude_beacon['url'], ], 'page' => 'page_cdn', ], ] ); $maybe_display_cdn_helper = ''; /** * Filters the addons names requiring the helper message. * * @param array $addons Array of addons. */ $addons = apply_filters( 'rocket_cdn_helper_addons', [] ); if ( ! is_array( $addons ) ) { $addons = []; } $addons = array_unique( $addons ); if ( ! empty( $addons ) ) { $maybe_display_cdn_helper = wp_sprintf( // translators: %1$s = opening em tag, %2$l = list of add-on name(s), %3$s = closing em tag. _n( '%1$s%2$l Add-on%3$s is currently enabled. Configuration of the CDN settings is not required for %2$l to work on your site.', '%1$s%2$l Add-ons%3$s are currently enabled. Configuration of the CDN settings is not required for %2$l to work on your site.', count( $addons ), 'rocket' ), '', $addons, '' ) . '
'; } $this->settings->add_settings_fields( /** * Filters the fields for the CDN section. * * @since 3.5 * @author Remy Perona * * @param array $cdn_settings_fields Data to be added to the CDN section. */ apply_filters( 'rocket_cdn_settings_fields', [ 'cdn' => [ 'type' => 'checkbox', 'label' => __( 'Enable Content Delivery Network', 'rocket' ), 'helper' => $maybe_display_cdn_helper, 'section' => 'cdn_section', 'page' => 'page_cdn', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], 'cdn_cnames' => [ 'type' => 'cnames', 'label' => __( 'CDN CNAME(s)', 'rocket' ), 'description' => __( 'Specify the CNAME(s) below', 'rocket' ), 'default' => [], 'section' => 'cnames_section', 'page' => 'page_cdn', ], 'cdn_reject_files' => [ 'type' => 'textarea', 'description' => __( 'Specify URL(s) of files that should not get served via CDN (one per line).', 'rocket' ), 'helper' => __( 'The domain part of the URL will be stripped automatically.
Use (.*) wildcards to exclude all files of a given file type located at a specific path.', 'rocket' ), 'placeholder' => '/wp-content/plugins/some-plugins/(.*).css', 'section' => 'exclude_cdn_section', 'page' => 'page_cdn', 'default' => [], 'sanitize_callback' => 'sanitize_textarea', ], ] ) ); } /** * Registers Heartbeat section. * * @since 3.2 */ private function heartbeat_section() { $heartbeat_beacon = $this->beacon->get_suggest( 'heartbeat_settings' ); $this->settings->add_page_section( 'heartbeat', [ 'title' => __( 'Heartbeat', 'rocket' ), 'menu_description' => __( 'Control WordPress Heartbeat API', 'rocket' ), ] ); $this->settings->add_settings_sections( [ 'heartbeat_section' => [ 'title' => __( 'Heartbeat', 'rocket' ), 'description' => __( 'Reducing or disabling the Heartbeat API’s activity can help save some of your server’s resources.', 'rocket' ), 'type' => 'fields_container', 'page' => 'heartbeat', 'help' => $heartbeat_beacon, ], 'heartbeat_settings' => [ 'title' => __( 'Reduce or disable Heartbeat activity', 'rocket' ), 'description' => __( 'Reducing activity will change Heartbeat frequency from one hit each minute to one hit every 2 minutes.', 'rocket' ) . '
' . __( 'Disabling Heartbeat entirely may break plugins and themes using this API.', 'rocket' ), 'type' => 'fields_container', 'page' => 'heartbeat', ], ] ); $fields_default = [ 'type' => 'select', 'page' => 'heartbeat', 'section' => 'heartbeat_settings', 'sanitize_callback' => 'sanitize_text_field', 'default' => 'reduce_periodicity', 'choices' => [ '' => __( 'Do not limit', 'rocket' ), 'reduce_periodicity' => __( 'Reduce activity', 'rocket' ), 'disable' => __( 'Disable', 'rocket' ), ], ]; $this->settings->add_settings_fields( [ 'control_heartbeat' => [ 'type' => 'checkbox', 'label' => __( 'Control Heartbeat', 'rocket' ), 'page' => 'heartbeat', 'section' => 'heartbeat_section', 'sanitize_callback' => 'sanitize_checkbox', 'default' => 0, ], 'heartbeat_admin_behavior' => array_merge( $fields_default, [ 'label' => __( 'Behavior in backend', 'rocket' ), 'description' => '', ] ), 'heartbeat_editor_behavior' => array_merge( $fields_default, [ 'label' => __( 'Behavior in post editor', 'rocket' ), ] ), 'heartbeat_site_behavior' => array_merge( $fields_default, [ 'label' => __( 'Behavior in frontend', 'rocket' ), ] ), ] ); } /** * Registers Add-ons section. * * @since 3.0 */ private function addons_section() { $webp_beacon = $this->beacon->get_suggest( 'webp' ); $user_cache_beacon = $this->beacon->get_suggest( 'user_cache' ); $this->settings->add_page_section( 'addons', [ 'title' => __( 'Add-ons', 'rocket' ), 'menu_description' => __( 'Add more features', 'rocket' ), ] ); $this->settings->add_settings_sections( [ 'one_click' => [ 'title' => __( 'One-click Rocket Add-ons', 'rocket' ), 'description' => __( 'One-Click Add-ons are features extending available options without configuration needed. Switch the option "on" to enable from this screen.', 'rocket' ), 'type' => 'addons_container', 'page' => 'addons', ], ] ); $this->settings->add_settings_sections( [ 'addons' => [ 'title' => __( 'Rocket Add-ons', 'rocket' ), 'description' => __( 'Rocket Add-ons are complementary features extending available options.', 'rocket' ), 'type' => 'addons_container', 'page' => 'addons', ], ] ); $this->settings->add_settings_fields( [ 'cache_logged_user' => [ 'type' => 'one_click_addon', 'label' => __( 'User Cache', 'rocket' ), 'logo' => [ 'url' => WP_ROCKET_ASSETS_IMG_URL . 'icon-user-cache.svg', 'width' => 152, 'height' => 135, ], 'title' => __( 'If you need to create a dedicated set of cache files for each logged-in WordPress user, you must activate this add-on.', 'rocket' ), // translators: %1$s = opening tag, %2$s = closing tag. 'description' => sprintf( __( 'User cache is great when you have user-specific or restricted content on your website.
%1$sLearn more%2$s', 'rocket' ), '', '' ), 'section' => 'one_click', 'page' => 'addons', 'settings_page' => 'user_cache', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], ] ); $default_cf_settings = [ 'do_cloudflare' => [ 'type' => 'rocket_addon', 'label' => __( 'Cloudflare', 'rocket' ), 'logo' => [ 'url' => rocket_get_constant( 'WP_ROCKET_ASSETS_IMG_URL', '' ) . 'logo-cloudflare2.svg', 'width' => 153, 'height' => 51, ], 'title' => __( 'Integrate your Cloudflare account with this add-on.', 'rocket' ), 'description' => __( 'Provide your account email, global API key, and domain to use options such as clearing the Cloudflare cache and enabling optimal settings with WP Rocket.', 'rocket' ), 'helper' => sprintf( // translators: %1$s = opening span tag, %2$s = closing span tag. __( '%1$sPlanning on using Automatic Platform Optimization (APO)?%2$s Just activate the official Cloudflare plugin and configure it. WP Rocket will automatically enable compatibility.', 'rocket' ), '', '' ), 'section' => 'addons', 'page' => 'addons', 'settings_page' => 'cloudflare', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], ]; /** * Filters the Cloudflare Addon field values * * @since 3.14 * * @param array $cf_settings Array of values to populate the field. */ $cf_settings = (array) apply_filters( 'rocket_cloudflare_field_settings', $default_cf_settings ); $cf_settings = wp_parse_args( $cf_settings, $default_cf_settings ); $this->settings->add_settings_fields( $cf_settings ); /** * Allow to display the "Varnish" tab in the settings page * * @since 2.7 * * @param bool $display true will display the "Varnish" tab. */ if ( apply_filters( 'rocket_display_varnish_options_tab', true ) ) { $varnish_beacon = $this->beacon->get_suggest( 'varnish' ); $this->settings->add_settings_fields( /** * Filters the Varnish field settings data * * @since 3.0 * @author Remy Perona * * @param array $settings Field settings data. */ apply_filters( 'rocket_varnish_field_settings', [ 'varnish_auto_purge' => [ 'type' => 'one_click_addon', 'label' => __( 'Varnish', 'rocket' ), 'logo' => [ 'url' => WP_ROCKET_ASSETS_IMG_URL . 'logo-varnish.svg', 'width' => 152, 'height' => 135, ], 'title' => __( 'If Varnish runs on your server, you must activate this add-on.', 'rocket' ), // translators: %1$s = opening tag, %2$s = closing tag. 'description' => sprintf( __( 'Varnish cache will be purged each time WP Rocket clears its cache to ensure content is always up-to-date.
%1$sLearn more%2$s', 'rocket' ), '', '' ), 'section' => 'one_click', 'page' => 'addons', 'settings_page' => 'varnish', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], ] ) ); } $webp_beacon = $this->beacon->get_suggest( 'webp' ); if ( rocket_valid_key() && ! \Imagify_Partner::has_imagify_api_key() ) { $imagify_link = ''; } else { $imagify_link = ''; } $this->settings->add_settings_fields( [ 'cache_webp' => /** * Add more content to the 'cache_webp' setting field. * * @since 3.10 moved to add-on section * @since 3.4 * * @param array $cache_webp_field Data to be added to the setting field. */ apply_filters( 'rocket_cache_webp_setting_field', [ 'type' => 'one_click_addon', 'label' => __( 'WebP Compatibility', 'rocket' ), 'logo' => [ 'url' => WP_ROCKET_ASSETS_IMG_URL . 'logo-webp.svg', 'width' => 152, 'height' => 135, ], 'title' => __( 'Improve browser compatibility for WebP images.', 'rocket' ), // translators: %1$s = opening tag, %2$s = closing tag. 'description' => sprintf( // translators: %1$s and %3$s = opening tag, %2$s = closing tag. __( 'Enable this option if you would like WP Rocket to serve WebP images to compatible browsers. Please note that WP Rocket cannot create WebP images for you. To create WebP images we recommend %1$sImagify%2$s. %3$sMore info%2$s', 'rocket' ), $imagify_link, '', '' ), 'section' => 'one_click', 'page' => 'addons', 'settings_page' => 'webp', 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', 'container_class' => [ 'wpr-webp-addon', ], ] ), ] ); if ( defined( 'WP_ROCKET_SUCURI_API_KEY_HIDDEN' ) && WP_ROCKET_SUCURI_API_KEY_HIDDEN ) { // No need to display the dedicated tab if there is nothing to display on it. $description = __( 'Clear the Sucuri cache when WP Rocket’s cache is cleared.', 'rocket' ); $settings_page = false; } else { $description = __( 'Provide your API key to clear the Sucuri cache when WP Rocket’s cache is cleared.', 'rocket' ); $settings_page = 'sucuri'; } $this->settings->add_settings_fields( [ 'sucury_waf_cache_sync' => [ 'type' => 'rocket_addon', 'label' => __( 'Sucuri', 'rocket' ), 'logo' => [ 'url' => WP_ROCKET_ASSETS_IMG_URL . 'logo-sucuri.png', 'width' => 152, 'height' => 56, ], 'title' => __( 'Synchronize Sucuri cache with this add-on.', 'rocket' ), 'description' => $description, 'section' => 'addons', 'page' => 'addons', 'settings_page' => $settings_page, 'default' => 0, 'sanitize_callback' => 'sanitize_checkbox', ], ] ); } /** * Registers Cloudflare section. * * @since 3.0 */ private function cloudflare_section() { $this->settings->add_page_section( 'cloudflare', [ 'title' => __( 'Cloudflare', 'rocket' ), 'menu_description' => '', 'class' => [ 'wpr-subMenuItem', 'wpr-addonSubMenuItem', ], ] ); $beacon_cf_credentials = $this->beacon->get_suggest( 'cloudflare_credentials' ); $beacon_cf_settings = $this->beacon->get_suggest( 'cloudflare_settings' ); $beacon_cf_credentials_api = $this->beacon->get_suggest( 'cloudflare_credentials_api' ); $this->settings->add_settings_sections( [ 'cloudflare_credentials' => [ 'type' => 'fields_container', 'title' => __( 'Cloudflare credentials', 'rocket' ), 'help' => [ 'id' => $beacon_cf_credentials['id'], 'url' => $beacon_cf_credentials['url'], ], 'page' => 'cloudflare', ], 'cloudflare_settings' => [ 'type' => 'fields_container', 'title' => __( 'Cloudflare settings', 'rocket' ), 'help' => [ 'id' => $beacon_cf_settings['id'], 'url' => $beacon_cf_settings['url'], ], 'page' => 'cloudflare', ], ] ); if ( ! defined( 'WP_ROCKET_CF_API_KEY_HIDDEN' ) || ! WP_ROCKET_CF_API_KEY_HIDDEN ) { $this->settings->add_settings_fields( [ 'cloudflare_api_key_mask' => [ 'label' => _x( 'Global API key:', 'Cloudflare', 'rocket' ), 'description' => sprintf( '%2$s', esc_url( $beacon_cf_credentials_api['url'] ), _x( 'Find your API key', 'Cloudflare', 'rocket' ) ), 'default' => '', 'section' => 'cloudflare_credentials', 'page' => 'cloudflare', ], ] ); } $this->settings->add_settings_fields( [ 'cloudflare_email' => [ 'label' => _x( 'Account email', 'Cloudflare', 'rocket' ), 'default' => '', 'container_class' => [ 'wpr-field--split', ], 'section' => 'cloudflare_credentials', 'page' => 'cloudflare', ], 'cloudflare_zone_id_mask' => [ 'label' => _x( 'Zone ID', 'Cloudflare', 'rocket' ), 'default' => '', 'container_class' => [ 'wpr-field--split', ], 'section' => 'cloudflare_credentials', 'page' => 'cloudflare', ], 'cloudflare_devmode' => [ 'type' => 'sliding_checkbox', 'label' => __( 'Development mode', 'rocket' ), // translators: %1$s = link opening tag, %2$s = link closing tag. 'description' => sprintf( __( 'Temporarily activate development mode on your website. This setting will automatically turn off after 3 hours. %1$sLearn more%2$s', 'rocket' ), '', '' ), 'default' => 0, 'section' => 'cloudflare_settings', 'page' => 'cloudflare', 'sanitize_callback' => 'sanitize_checkbox', ], 'cloudflare_auto_settings' => [ 'type' => 'sliding_checkbox', 'label' => __( 'Optimal settings', 'rocket' ), 'description' => __( 'Automatically enhances your Cloudflare configuration for speed, performance grade and compatibility.', 'rocket' ), 'default' => 0, 'section' => 'cloudflare_settings', 'page' => 'cloudflare', 'sanitize_callback' => 'sanitize_checkbox', ], 'cloudflare_protocol_rewrite' => [ 'type' => 'sliding_checkbox', 'label' => __( 'Relative protocol', 'rocket' ), 'description' => __( 'Should only be used with Cloudflare\'s flexible SSL feature. URLs of static files (CSS, JS, images) will be rewritten to use // instead of http:// or https://.', 'rocket' ), 'default' => 0, 'section' => 'cloudflare_settings', 'page' => 'cloudflare', 'sanitize_callback' => 'sanitize_checkbox', ], ] ); } /** * Registers Sucuri cache section. * * @since 3.2 */ private function sucuri_section() { if ( defined( 'WP_ROCKET_SUCURI_API_KEY_HIDDEN' ) && WP_ROCKET_SUCURI_API_KEY_HIDDEN ) { return; } $sucuri_beacon = $this->beacon->get_suggest( 'sucuri_credentials' ); $this->settings->add_page_section( 'sucuri', [ 'title' => __( 'Sucuri', 'rocket' ), 'menu_description' => '', 'class' => [ 'wpr-subMenuItem', 'wpr-addonSubMenuItem', ], ] ); $this->settings->add_settings_sections( [ 'sucuri_credentials' => [ 'type' => 'fields_container', 'title' => __( 'Sucuri credentials', 'rocket' ), 'page' => 'sucuri', 'help' => [ 'id' => $sucuri_beacon['id'], 'url' => $sucuri_beacon['url'], ], ], ] ); $this->settings->add_settings_fields( [ 'sucury_waf_api_key' => [ 'label' => _x( 'Firewall API key (for plugin), must be in format {32 characters}/{32 characters}:', 'Sucuri', 'rocket' ), 'description' => sprintf( '%2$s', 'https://kb.sucuri.net/firewall/Performance/clearing-cache', _x( 'Find your API key', 'Sucuri', 'rocket' ) ), 'default' => '', 'section' => 'sucuri_credentials', 'page' => 'sucuri', ], ] ); } /** * Sets hidden fields. * * @since 3.0 */ private function hidden_fields() { $hidden_fields = [ 'consumer_key', 'consumer_email', 'secret_key', 'license', 'secret_cache_key', 'minify_css_key', 'minify_js_key', 'version', 'previous_version', 'cloudflare_old_settings', 'cache_ssl', 'minify_google_fonts', 'emoji', 'remove_unused_css', 'async_css', 'cache_mobile', 'do_caching_mobile_files', 'minify_concatenate_css', 'cloudflare_api_key', 'cloudflare_zone_id', ]; $this->settings->add_hidden_settings_fields( /** * Filters the hidden settings fields * * @since 3.5 * @author Remy Perona * * @param array $hidden_settings_fields An array of hidden settings fields ID */ apply_filters( 'rocket_hidden_settings_fields', $hidden_fields ) ); } /** * Sanitize and format a list. * * @since 3.5.5 * * @param array $list A list of strings. * @param string $tag_name Name of the HTML tag that will wrap each element of the list. * @return array */ private function sanitize_and_format_list( $list, $tag_name = 'strong' ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.listFound if ( ! is_array( $list ) || empty( $list ) ) { return []; } $list = array_filter( $list ); if ( empty( $list ) ) { return []; } $list = array_unique( $list ); if ( empty( $tag_name ) ) { return $list; } $format = "<$tag_name>%s"; return array_map( 'sprintf', array_fill( 0, count( $list ), $format ), $list ); } /** * Checks if combine JS option should be disabled * * @since 3.9 * * @return bool */ private function disable_combine_js(): bool { if ( (bool) get_rocket_option( 'delay_js', 0 ) ) { return true; } return ! (bool) get_rocket_option( 'minify_js', 0 ); } /** * Checks if combine CSS option should be disabled * * @since 3.11 * * @return bool */ private function disable_combine_css(): bool { if ( (bool) get_rocket_option( 'remove_unused_css', 0 ) ) { return true; } return ! (bool) get_rocket_option( 'minify_css', 0 ); } /** * Render radio options sub fields. * * @since 3.10 * * @param array $sub_fields Array of fields to display. */ public function display_radio_options_sub_fields( $sub_fields ) { $sub_fields = $this->settings->set_radio_buttons_sub_fields_value( $sub_fields ); $this->render->render_fields( $sub_fields ); } /** * Render mobile cache option. * * @return void */ public function display_mobile_cache_option(): void { if ( (bool) $this->options->get( 'cache_mobile', 0 ) ) { return; } $data = $this->beacon->get_suggest( 'mobile_cache' ); echo $this->generate( 'settings/mobile-cache', $data ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Dynamic content is properly escaped in the view. } /** * Callback method for the AJAX request to mobile cache. * * @return void */ public function enable_mobile_cache(): void { check_ajax_referer( 'rocket-ajax', 'nonce', true ); if ( ! current_user_can( 'rocket_manage_options' ) ) { wp_send_json_error(); return; } $this->options->set( 'cache_mobile', 1 ); $this->options->set( 'do_caching_mobile_files', 1 ); update_option( rocket_get_constant( 'WP_ROCKET_SLUG', 'wp_rocket_settings' ), $this->options->get_options() ); wp_send_json_success(); } /** * Enable Separate cache files option on upgrade. * * @return void */ public function enable_separate_cache_files_mobile(): void { if ( ! (bool) $this->options->get( 'cache_mobile', 0 ) ) { return; } if ( (bool) $this->options->get( 'do_caching_mobile_files', 0 ) ) { return; } $this->options->set( 'do_caching_mobile_files', 1 ); update_option( rocket_get_constant( 'WP_ROCKET_SLUG', 'wp_rocket_settings' ), $this->options->get_options() ); } /** * Display an update notice when the plugin is updated. * * @return void */ public function display_update_notice() { if ( ! current_user_can( 'rocket_manage_options' ) ) { return; } if ( 'settings_page_wprocket' !== get_current_screen()->id ) { return false; } $boxes = get_user_meta( get_current_user_id(), 'rocket_boxes', true ); if ( in_array( 'rocket_update_notice', (array) $boxes, true ) ) { return; } $previous_version = $this->options->get( 'previous_version' ); // Bail-out for fresh install. if ( empty( $previous_version ) ) { return; } // Bail-out if previous version is greater than 3.16. if ( $previous_version > '3.16' ) { return; } $critical_images_beacon = $this->beacon->get_suggest( 'optimize_critical_images' ); $remove_cache_tab = $this->beacon->get_suggest( 'remove_cache_tab' ); rocket_notice_html( [ 'status' => 'info', 'dismissible' => '', 'message' => sprintf( // translators: %1$s: opening strong tag, %2$s: closing strong tag, %3$s: opening a tag, %4$s: option a tag, %5$s: opening a tag. __( '%1$sWP Rocket:%2$s the plugin has been updated to the 3.16 version. Our brand new feature %3$sOptimize critical images%5$s is automatically activated now! Also, the Cache tab was removed but the existing features will remain working, %4$ssee more here%5$s.', 'rocket' ), '', '', '', '', '' ), 'dismiss_button' => 'rocket_update_notice', ] ); } } کیتلین دیور – معرفی فیلم و سریال روز | آرشیو فیلم و سریال ایرانی و خارجی | اخبار روز فیلم ، سریال و بازیگران https://cabinmovie.ir کابین مووی Sat, 24 Feb 2024 08:47:50 +0000 fa-IR hourly 1 https://wordpress.org/?v=6.8.3 https://cabinmovie.ir/wp-content/uploads/2023/05/cropped-cabin-movie-favicon-32x32.png کیتلین دیور – معرفی فیلم و سریال روز | آرشیو فیلم و سریال ایرانی و خارجی | اخبار روز فیلم ، سریال و بازیگران https://cabinmovie.ir 32 32 سریال unbelievable https://cabinmovie.ir/series/%d8%b3%d8%b1%db%8c%d8%a7%d9%84-unbelievable/ https://cabinmovie.ir/series/%d8%b3%d8%b1%db%8c%d8%a7%d9%84-unbelievable/#respond Sat, 24 Feb 2024 08:43:26 +0000 https://cabinmovie.ir/?post_type=series&p=2404 معرفی سریال Unbelievable

سریال Unbelievable یک درام جنایی است که بر اساس داستان واقعی و گزارشی از مجله ProPublica و The Marshall Project ساخته شده است. این سریال، که در سال 2019 منتشر شد، به داستان دو کارآگاه زن می پردازد که در تعقیب یک تجاوزکار سریالی در سراسر ایالات متحده هستند. داستان با تمرکز بر یک قربانی جوان به نام ماری، که پس از گزارش دادن تجاوز، توسط پلیس و اطرافیانش باور نمی شود، آغاز می شود. این سریال با نمایش روند تحقیقات و چالش هایی که قربانیان جنایات جنسی با آن روبرو هستند، به موضوعات مهمی همچون اعتبار قربانیان و اهمیت تحقیقات دقیق و همدلانه می پردازد.
سریال Unbelievable با بازی قدرتمند تونی کولت، مریت ویور، و کایتلین دیور، نه تنها توانست نظر منتقدین را به خود جلب کند، بلکه توجه عموم مخاطبین را نیز به مسائل مهم اجتماعی جلب کرد. این سریال تماشاگران را با پیچیدگی های سیستم عدالت کیفری و تأثیر آن بر قربانیان جنایت آشنا می کند. با به تصویر کشیدن داستان های واقعی و تلاش های خستگی ناپذیر کارآگاهان برای به دست آوردن عدالت، سریال Unbelievable به یک اثر ماندگار و تأثیرگذار در ژانر درام جنایی تبدیل شده است.تماشای فیلم Maestro را به شما پیشنهاد می کنیم.

داستان سریال Unbelievable

سریال Unbelievable درامی قدرتمند و برانگیزاننده است که بر اساس رویدادهای واقعی شکل گرفته و به بررسی پرونده ای از تجاوزات سریالی در ایالات متحده می پردازد. داستان از زندگی ماری، نوجوانی که پس از گزارش دادن یک حمله جنسی، با تردید و بی اعتمادی از سوی پلیس و افراد نزدیک به خود مواجه می شود، آغاز می شود. این امر منجر به بازگشت ماری بر روی اظهارات خود و ایجاد یک حس انزوا و درماندگی در او می شود. در همین حال، در نقاط دیگری از کشور، دو کارآگاه زن، کارن دوارت و گریس راسموسن، به طور مستقل از هم شروع به کشف الگوهایی می کنند که نشان دهنده فعالیت یک تجاوزکار سریالی است.
با پیشرفت تحقیقات، راه های کارن و گریس به یکدیگر می رسد و آن ها تصمیم می گیرند با همکاری یکدیگر مظنون را شناسایی و دستگیر کنند. این سریال با استفاده از روایت های موازی، نه تنها به داستان مبارزه ماری برای بازیابی هویت و اعتماد به نفس خود پرداخته، بلکه به دقت روند کارآگاهی و چالش هایی که در راه کشف حقیقت وجود دارد را به تصویر می کشد. سریال Unbelievable نه تنها یک داستان تکان دهنده از بقا و جستجو برای عدالت است، بلکه به یک بررسی عمیق و انتقادی از سیستم عدالت کیفری و نحوه برخورد آن با قربانیان جنایات جنسی تبدیل می شود، بازتاب دهنده ضرورت تغییرات اساسی در نگرش و رویه ها.

نقد و بررسی سریال Unbelievable

سریال Unbelievable با داستانی که از وقایع واقعی الهام گرفته، به یکی از محبوب ترین و تاثیرگذارترین سریال های درام جنایی تبدیل شده است. این سریال که در سال 2019 منتشر شد، با دقت و حساسیت بالایی به موضوع تجاوز و کاستی های سیستم عدالت کیفری در برخورد با چنین پرونده هایی می پردازد. توجه به جزئیات داستانی، بازسازی واقع گرایانه رویدادها، و نحوه برخورد با موضوعات حساس، سریال Unbelievable را به یک اثر ممتاز در ژانر خود تبدیل کرده است. عملکرد بازیگران، به ویژه کایتلین دیور در نقش ماری، و همچنین تونی کولت و مریت ویور در نقش کارآگاهان، استثنایی بوده و به روایت قوی و همدلانه ای از تجربیات قربانیان و تلاش های محققان برای کشف حقیقت کمک کرده است.
نقد و بررسی ها به طور گسترده ای بر این نکته تاکید دارند که سریال Unbelievable نه تنها یک سریال جنایی هیجان انگیز است، بلکه یک تحلیل اجتماعی قدرتمند نیز به شمار می رود که به چالش هایی که قربانیان جنایات جنسی با آن مواجه هستند، می پردازد. این سریال به مخاطبان اجازه می دهد تا از طریق داستان های شخصیت ها، با آسیب ها و موانعی که قربانیان در مسیر دستیابی به عدالت تجربه می کنند، ارتباط برقرار کنند. از طریق نگاهی دقیق به نقایص سیستم قضایی و اجتماعی، سریال Unbelievable مخاطبان را به تفکر در مورد نیاز به اصلاحات و همدلی بیشتر با قربانیان ترغیب می کند. در نهایت، این سریال به عنوان یک اثر مهم و ضروری در دنیای امروز شناخته شده و توانسته است گفتمان مهمی در مورد مسائل عدالت جنسیتی و قضایی ایجاد کند.

Rate this series
]]>
https://cabinmovie.ir/series/%d8%b3%d8%b1%db%8c%d8%a7%d9%84-unbelievable/feed/ 0