uawdijnntqw1x1x1
IP : 3.138.37.184
Hostname : premium160.web-hosting.com
Kernel : Linux premium160.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64
Disable Function : None :)
OS : Linux
PATH:
/
home
/
batcwwjx
/
www
/
wp-content
/
plugins
/
ml-slider
/
admin
/
.
/
slideshows
/
Themes.php
/
/
<?php if (!defined('ABSPATH')) { die('No direct access.'); } /** * Class to handle themes */ class MetaSlider_Themes { /** * Theme instance * * @var object * @see get_instance() */ protected static $instance = null; /** * Theme name * * @var string */ public $theme_id; /** * List of supported slide types * * @var array */ public $supported_slideshow_libraries = array('flex', 'responsive', 'nivo', 'coin'); /** * Constructor */ public function __construct() { } /** * Used to access the instance */ public static function get_instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } /** * Method to get all the free themes from the theme directory * * @return array|WP_Error whether the file was included, or error class */ public function get_all_free_themes() { if (!file_exists(METASLIDER_THEMES_PATH . 'manifest.php') || !file_exists(METASLIDER_THEMES_PATH . 'manifest-legacy.php')) { return new WP_Error('manifest_not_found', __('No themes found.', 'ml-slider'), array('status' => 404)); } if (is_multisite() && $settings = get_site_option('metaslider_global_settings')) { $global_settings = $settings; } if ($settings = get_option('metaslider_global_settings')) { $global_settings = $settings; } $new_install = get_option('metaslider_new_user'); if ( (isset($global_settings['legacy']) && true == $global_settings['legacy']) || (isset($new_install) && 'new' == $new_install) ) { $themes = (include METASLIDER_THEMES_PATH . 'manifest.php'); } else { $themes = (include METASLIDER_THEMES_PATH . 'manifest-legacy.php'); } // If is not Pro, let's include some Premium themes with upgrade link if (! metaslider_pro_is_active()) { $premium_themes = (include METASLIDER_THEMES_PATH . 'manifest-premium.php'); $themes = array_merge($themes, $premium_themes); } /** * Check if we have extra themes/ folders added from external sources, * including MetaSlider Pro * * e.g. * array( * '/path/to/wp-content/plugins/ml-slider-pro/themes/', * '/path/to/wp-content/themes/my-theme/ms-themes/' * ) */ $extra_themes = apply_filters('metaslider_extra_themes', array()); foreach ($extra_themes as $location) { // Make sure there is a manifest if (file_exists(trailingslashit($location) . 'manifest.php')) { $manifest = include(trailingslashit($location) . 'manifest.php'); // Make sure each theme has an existing folder, title, description foreach ($manifest as $data) { if (isset($data['folder']) && file_exists($folder = trailingslashit($location) . $data['folder']) && isset($data['title']) && isset($data['description']) && isset($data['screenshot_dir']) ) { // Adjust type $data['type'] = isset($data['type']) ? $data['type'] : 'external'; // Set a temporary array key to pass the customize.php file location if (file_exists($customize = trailingslashit($folder) . 'customize.php')) { $data['theme_customize_temp_'] = $customize; } // Add a key to the theme array $data = array( $data['folder'] => $data ); // Merge and set new theme to the top $themes = array_merge($themes, $data); } } } } // Add theme customization settings $themes = $this->add_base_customize_settings($themes); return $themes; } /** * Add customize array key to each theme that have its own customize.php file * * @since 3.91.0 * * @param array $themes Themes array from manifest file * * @return array */ public function add_base_customize_settings($themes) { foreach ( $themes as $item ) { $folder = $item['folder']; // Check if we use a different customize.php file (e.g. is an external theme) for this theme or default $customize_file = isset($item['theme_customize_temp_']) ? $item['theme_customize_temp_'] : METASLIDER_THEMES_PATH . $folder . '/customize.php'; if (in_array($item['type'], array('free', 'premium', 'external')) && file_exists($customize_file) ) { $customize_settings = (include $customize_file); $themes[$folder]['customize'] = $this->merge_theme_customizations($customize_settings); } // Remove temporary array keys if (isset($themes[$folder]['theme_customize_temp_'])) { unset($themes[$folder]['theme_customize_temp_']); } } return $themes; } /** * Get customize settings from a specific theme * * @since 3.91.0 * @since 3.93 - Added $alt_customize_file param * * @param string $theme Theme slug in lowercase. Use the theme's folder name actually. * @param bool|string $alt_customize_file Alternative customize.php location * Use cases: if is a Pro theme or a custom theme. * e.g. 'path/to/another/themes/my-theme/customize.php' * * return array */ public function add_base_customize_settings_single($theme, $alt_customize_file = false) { $customize_file = $alt_customize_file ? $alt_customize_file : METASLIDER_THEMES_PATH . $theme . '/customize.php'; if (file_exists($customize_file)) { $customize_settings = (include $customize_file); $data = $this->merge_theme_customizations($customize_settings); } else { $data = array(); } return $data; } /** * Get single theme data from manifest file * * @since 3.93.0 * * @param string $theme Theme slug in lowercase. Use the theme's folder name actually. * * return array */ public function get_single_theme($theme) { $all_themes = $this->get_all_free_themes(); return $all_themes[$theme]; } /** * Method to get all custom themes from the database. * * @return array Returns an array of custom themes or an empty array if none found */ public function get_custom_themes() { $custom_themes = array(); if ((bool) $themes = get_option('metaslider-themes')) { foreach ($themes as $id => $theme) { $custom_themes[$id] = array( 'folder' => $id, 'title' => $theme['title'], 'type' => 'custom', 'version' => (isset($theme['version']) ? $theme['version'] : 'v1') ); // Data exclusive to v2 themes if (isset($theme['base'])) { $custom_themes[$id]['base'] = $theme['base']; } if (isset($theme['base_title'])) { $custom_themes[$id]['base_title'] = $theme['base_title']; } } } return $custom_themes; } /** * Method to get details about a theme * * @param string $id - Id of the slideshow * @return void */ public function details($id) { } /** * Method to get the object by theme name/id * * @param string $slideshow_id - Id of the slideshow * @param string $theme_id - Id of the theme * * @return bool|array - The theme object or false if no theme */ public function get_theme_object($slideshow_id, $theme_id) { if (is_wp_error($free_themes = $this->get_all_free_themes())) { $free_themes = array(); } $themes = array_merge($free_themes, $this->get_custom_themes()); foreach ($themes as $one_theme) { if ($one_theme['folder'] === $theme_id) { $theme = $one_theme; } } // If the folder isn't set then something went wrong or no theme is set. if (!isset($theme['folder']) || '' == $theme['folder']) { return false; } // If the version isn't set, grab the latest if (!isset($theme['version']) || '' == $theme['version']) { $theme['version'] = $this->get_latest_version($theme['folder']); } return $theme; } /** * Method to get a random theme * * @param bool $all - Whether to include themes that arent fully supported * * @return bool|array - The theme object or false if no theme */ public function random($all = false) { if (is_wp_error($free_themes = $this->get_all_free_themes())) { return false; } if ($all) { return array_rand($free_themes); } $themes = array(); foreach ($free_themes as $id => $theme) { // Be sure the theme supports all slider libraries if (count($this->supported_slideshow_libraries) === count($theme['supports'])) { $themes[$id] = $theme; } } return array_rand($themes); } /** * Method to get the current set theme for a slideshow * * @param string $slideshow_id - Id of the slideshow * * @return bool|array - The theme object or false if no theme */ public function get_current_theme($slideshow_id) { $theme = get_post_meta($slideshow_id, 'metaslider_slideshow_theme', true); // If the theme is none, it means no theme is set (happens if they remove a theme) // $theme may be WP_Error due to a bug in 3.9.1 if ('none' === $theme || is_wp_error($theme)) { return false; } $is_a_custom_theme = (isset($theme['folder']) && ('_theme' === substr($theme['folder'], 0, 6))); // Check here for a legacy theme OR a custom theme if (!isset($theme['folder']) || $is_a_custom_theme) { $settings = get_post_meta($slideshow_id, 'ml-slider_settings', true); // * This might be a nivo theme or a custom theme (pro) if (isset($settings['theme'])) { $settings['theme'] = in_array($settings['theme'], array('light', 'dark', 'bar')) ? 'nivo-' . $settings['theme'] : $settings['theme']; $theme = $this->get_theme_object($slideshow_id, $settings['theme']); // Update the theme to the new system update_post_meta($slideshow_id, 'metaslider_slideshow_theme', $theme); } } // If the folder isn't set then something went wrong or no theme is set. if (!isset($theme['folder']) || '' == $theme['folder']) { return false; } // If the version isn't set, grab the latest if (!isset($theme['version']) || '' == $theme['version']) { $theme['version'] = $this->get_latest_version($theme['folder']); } // At this point, if it's a custom theme we are okay if ($is_a_custom_theme) { return $theme; } /** * Check if we have extra themes/ folders added from external sources, * including MetaSlider Pro * * e.g. * array( * '/path/to/wp-content/plugins/ml-slider-pro/themes/', * '/path/to/wp-content/themes/my-theme/ms-themes/' * ) */ $extra_themes = apply_filters('metaslider_extra_themes', array()); foreach ($extra_themes as $location) { if (file_exists(trailingslashit($location) . trailingslashit($theme['folder']) . trailingslashit($theme['version']) . 'theme.php')) { return $theme; } } // If the folder is in in our theme selection if (file_exists(METASLIDER_THEMES_PATH . trailingslashit($theme['folder']) . $theme['version'])) { return $theme; } // Remove the broken/not found theme $this->set($slideshow_id, array()); // The theme wasnt found anywhere return new WP_Error('theme_not_found', __('We removed your selected theme as it could not be found. Was the folder deleted?', 'ml-slider')); } /** * Method to get the version of the latest theme * * @param string $folder - Folder name in /themes/ * @return string the version number */ public function get_latest_version($folder) { // If the changelog isn't there for some reason just assume it's v1.0.0 if (!file_exists(METASLIDER_THEMES_PATH . trailingslashit($folder) . 'changelog.php')) { return 'v1.0.0'; } $changelog = (include METASLIDER_THEMES_PATH . trailingslashit($folder) . 'changelog.php'); return current(array_keys($changelog)); } /** * Method to set the theme * * @param int|string $slideshow_id The id of the current slideshow * @param array $theme The selected theme object * @return bool true on successful update, false on failure. */ public function set($slideshow_id, $theme) { // For legacy reasons we have to query the settings $settings = get_post_meta($slideshow_id, 'ml-slider_settings', true); // If the theme isn't set, then they attempted to remove the theme if (!isset($theme['folder']) || is_wp_error($theme)) { $settings['theme'] = 'none'; $settings['theme_customize'] = array(); update_post_meta($slideshow_id, 'ml-slider_settings', $settings); return update_post_meta($slideshow_id, 'metaslider_slideshow_theme', 'none'); } // For custom themes, it's easier to use the legacy setting because the pro plugin // already hooks into it. if ('_theme' === substr($theme['folder'], 0, 6)) { /* @since 3.94 - Make sure we keep theme_customize empty for custom themes based on core themes (v2 theme editor), * let's empty 'theme_customize' to make sure we don't keep previous customize settings saved * in case the new assigned theme doesn't have 'customize' to override it */ if(isset($theme['type']) && ! in_array($theme['type'], array('free', 'premium'))) { if ('_theme_v2' === substr($theme['folder'], 0, 9)) { // Is a theme created with v2 Theme editor $settings['theme_customize'] = array(); } elseif (isset($settings['theme_customize'])) { // Is a theme created with v1 Theme editor (legacy) unset($settings['theme_customize']); } } $settings['theme'] = $theme['folder']; update_post_meta($slideshow_id, 'ml-slider_settings', $settings); } else if (isset($settings['theme'])) { /* @since 3.94 - If theme doesn't have 'customize' array key, let's empty 'theme_customize' * Important: even if is empty, 'theme_customize' is required in 'ml-slider_settings' postmeta db * for themes created with v2 theme editor */ if (! isset($theme['customize']) && isset($settings['theme_customize'])) { $settings['theme_customize'] = array(); } // If the theme isn't a custom theme, we should unset the legacy setting // unset($settings['theme']); // ! Pro requires this to be set $settings['theme'] = ''; update_post_meta($slideshow_id, 'ml-slider_settings', $settings); // Save the customizations defaults $this->save_theme_customizations( $slideshow_id, $theme ); } // We don't want to store customization manifest in metaslider_slideshow_theme postmeta if (isset($theme['customize'])) { unset($theme['customize']); } // This will return false if the data is the same, unfortunately return (bool) update_post_meta($slideshow_id, 'metaslider_slideshow_theme', $theme); } /** * Merge base theme customizations with specific theme customizations * * @since 3.91.0 * * @param array $customizations Theme customizations * * @return array */ public function merge_theme_customizations( $customizations ) { $base_customizations = ( include METASLIDER_THEMES_PATH . 'customize.php' ); $all_customizations = array_merge( $customizations, $base_customizations ); // Merge Pro customize.php if ( defined( 'METASLIDERPRO_THEMES_PATH' ) && metaslider_pro_is_active() && file_exists( $pro = METASLIDERPRO_THEMES_PATH . '/customize.php' ) ) { $all_customizations = $this->merge_settings_by_name( $all_customizations, include $pro ); } return $all_customizations; } /** * Merge $a customize.php 'settings' into $b customize.php 'settings' by matching 'section' * * @since 3.96 * * @param array $a Customize file A * @param array $b Customize file B * * @return array $a modified version */ public function merge_settings_by_name( &$a, $b ) { foreach ($b as $b_section) { foreach ( $a as &$a_section ) { // Check if sections match by 'name' if (isset( $a_section['name'], $b_section['name'] ) && $a_section['name'] === $b_section['name'] ) { // Merge 'settings' arrays if ( isset( $a_section['settings'], $b_section['settings'] ) ) { $a_section['settings'] = array_merge( $a_section['settings'], $b_section['settings'] ); } } } unset( $a_section ); // Break reference to prevent side effects } return $a; } /** * Save theme customizations * * @since 3.91.0 * * @param int $slideshow_id Slideshow ID * @param array $theme Theme with all the props including folder and customize * * @return void */ public function save_theme_customizations( $slideshow_id, $theme ) { $customizations = $theme['customize']; // To fix incoming warning: foreach() argument must be of type array|object, null given if (! is_array($customizations)) { return false; } $theme_settings = $this->get_customize_defaults($customizations, array('color')); // Only get 'color' settings $slideshow_settings = get_post_meta( $slideshow_id, 'ml-slider_settings', true ); $slideshow_settings['theme_customize'] = $theme_settings; update_post_meta( $slideshow_id, 'ml-slider_settings', $slideshow_settings ); } /** * Just save name => default/value of each array inside 'fields' from customize.php manifest * * In customize.php as: * array( * array( * 'label' => 'Arrows', * 'fields' => array( * array( * 'label' => 'Normal', * 'name' => 'arrows_color', * 'type' => 'color', * 'default' => '#336699', * 'css' => '%s .lorem { color: %s }' * ), * // More arrays ... * ) * ) * ) * * Stored in db as: * array( * 'arrows_color' => '#336699', * 'another_setting' => '#feb123', * ) * * @since 3.94 * * @param array $customizations All the data from 'customize' from theme's manifest file * @param bool|array $filter Include only these setting types only. e.g. array('color') = only include color settings * * @return array */ public function get_customize_defaults($customizations, $filter = false) { $res = array(); if (! is_array($customizations)) { return $res; } // Loop each section that has 'status' key foreach ($customizations as $section) { if (!$filter || in_array($section['type'], $filter)) { // Extract 'name' and 'default' for 'section' type $res[$section['name']] = $section['default']; } // Loop each section 'settings' key foreach ($section['settings'] as $row_item) { // If type is 'fields', let's look for the list of fields. // Usually for multiple color fields grouped together if ($row_item['type'] === 'fields') { foreach ($row_item['fields'] as $field_item) { if (!$filter || in_array($field_item['type'], $filter)) { $res[$field_item['name']] = $field_item['default']; } } } else { if (!$filter || in_array($row_item['type'], $filter)) { // Get individual fields $res[$row_item['name']] = $row_item['default']; } } } } return $res; } /** * Load in the selected theme assets. * * @param int|string $slideshow_id The id of the current slideshow * @param string $theme_id The folder name of a theme * * @return bool|WP_Error whether the file was included, or error class */ public function load_theme($slideshow_id, $theme_id = null) { $is_theme_editor_screen = is_admin() && function_exists('get_current_screen') && ($screen = get_current_screen()) && 'metaslider-pro_page_metaslider-theme-editor' === $screen->id; // Don't load a theme on the editor page. if ($is_theme_editor_screen && (! isset($_GET['version']) || $_GET['version'] == 'v1')) { return false; } // @since 3.94 - Adjust $theme_id load for v2 editor if ($is_theme_editor_screen && (isset($_GET['version']) && $_GET['version'] == 'v2')) { if (! empty($_GET['theme_slug'] ?? null)) { // e.g. /wp-admin/admin.php?page=metaslider-theme-editor&theme_slug=_theme_1733247735&version=v2 $custom_theme_slug = sanitize_key($_GET['theme_slug']); $custom_themes = get_option('metaslider-themes'); if ($custom_themes && isset($custom_themes[$custom_theme_slug]) && isset($custom_themes[$custom_theme_slug]['base']) ) { $theme_id = $custom_themes[$custom_theme_slug]['base']; } } elseif (! empty($_GET['base'] ?? null)) { // e.g. /wp-admin/admin.php?page=metaslider-theme-editor&add=true&version=v2&base=outline $theme_id = sanitize_key($_GET['base']); } } $theme = (is_null($theme_id)) ? $this->get_current_theme($slideshow_id) : $this->get_theme_object($slideshow_id, $theme_id); // No theme for this slideshow? Set a default class if ( false === $theme ) { add_filter( 'metaslider_css_classes', array( $this, 'add_no_theme_class' ), 10, 3 ); remove_filter( 'metaslider_css_classes', array( $this, 'add_theme_class' ), 10, 3 ); } // 'none' is the default theme to load no theme. // @TODO - Why we don't seem to get 'none' for slideshows with no theme? if ('none' == $theme_id) { return false; } if (is_wp_error($theme) || false === $theme) { return $theme; } // We have a theme, so lets add the class to the body $this->theme_id = $theme['folder']; // Add the theme class name to the slideshow add_filter('metaslider_css_classes', array($this, 'add_theme_class'), 10, 3); remove_filter( 'metaslider_css_classes', array( $this, 'add_no_theme_class' ), 10, 3 ); // Check our themes for a match if (file_exists(METASLIDER_THEMES_PATH . $theme['folder'])) { $theme_dir = METASLIDER_THEMES_PATH . $theme['folder']; } /** * Check if we have extra themes/ folders added from external sources, * including MetaSlider Pro * * e.g. * array( * '/path/to/wp-content/plugins/ml-slider-pro/themes/', * '/path/to/wp-content/themes/my-theme/ms-themes/' * ) */ $extra_themes = apply_filters('metaslider_extra_themes', array()); foreach ($extra_themes as $location) { if (file_exists(trailingslashit($location) . $theme['folder'])) { $theme_dir = trailingslashit($location) . $theme['folder']; } } // Load in the base theme class if (isset($theme_dir) && isset($theme['version'])) { require_once(METASLIDER_THEMES_PATH . 'ms-theme-base.php'); return include_once trailingslashit($theme_dir) . trailingslashit($theme['version']) . 'theme.php'; } // This should be a custom theme (pro) return $theme; } /** * Filter the manifest data by field 'dependencies' and return final CSS * * @since 3.96 * * @param array $data The manifest data with all the customzie settings * * @return string */ public function filter_customize_css( $data ) { foreach ( $data as $key => $item ) { if ( isset( $item['dependencies'] ) && $item['dependencies'] !== false ) { foreach ( $data[$key]['dependencies'] as $dep ) { // If dependecy 'when' value is different to $data[$key]['value] (aka $item['value']) value, // let's exclude from $data if ( $dep['when'] !== $item['value'] ) { if ( isset( $data[$dep['show']] ) ) { unset($data[$dep['show']]); } } } } } // Let's extract only the CSS and merge as a single string $css = ""; foreach ( $data as $item ) { if ( ! empty( $item['css'] ) ) { $css .= $item['css']; } } return $css; } /** * When match get the value of a css_field * from another field based on css_field value * * @since 3.96 * * @return bool|string|integer|float false if no match found (not a css_field) */ public function value_linked_to_field( $manifest, $stored, $name ) { foreach ( $manifest as $section ) { // Loop each section 'settings' key foreach ( $section['settings'] as $row_item ) { // Skip fields and its childs. Perhaps in future support it? if ( $row_item['type'] !== 'fields' ) { if ( isset( $row_item['css_field'] ) && $row_item['css_field'] === $name && isset( $stored[$row_item['name']] ) ) { // Exit early and return the matching data return $stored[$row_item['name']]; } } } } return false; } /** * Loop each theme customize setting from customize.php and build final working CSS * * * @since 3.94 * * @param $array $manifest The manifest customize data. e.g. $manifest['customize'] * @param $array $stored The stored data. e.g. 'theme_customize' data at ml-slider_settings postmeta * @param int $slideshow_id Sldieshow ID * * @return string */ public function build_customize_css($manifest, $stored, $slideshow_id) { /** * We'll store some data linked to the setting name * * @since 3.96 * * e.g. * array( * array( * 'arrows_color' => array( * 'value' => '#fff' * 'css' => '[ms_id] .lorem { color: [ms_value] }' * 'dependencies' => array() * ) * ), * // More elements ... * ) **/ $pre_output = array(); foreach ($manifest as $section) { // Loop each section 'settings' key foreach ($section['settings'] as $row_item) { // If type is 'fields', let's look for the list of fields. // Usually for multiple color fields grouped together if ($row_item['type'] === 'fields') { foreach ($row_item['fields'] as $field_item) { // Check if setting from manifest exists in db if (isset($stored[$field_item['name']]) && isset($field_item['css'])) { if ($field_item['css'] == 'css_rules' && isset($field_item['css_rules'])) { // CSS code is actually on css_rules key (aka css = 'css_rules') BUT based on value parameter // @TODO Maybe allow array of CSS too as in regular css key? // Store final CSS an dependencies if any linked to its name $pre_output[$field_item['name']] = array( 'value' => $field_item['css_rules'][$stored[$field_item['name']]], 'css' => $this->adjust_css_placeholders( $field_item['css_rules'][$stored[$field_item['name']]], "#metaslider-id-{$slideshow_id}", $stored[$field_item['name']] ) . "\n", 'dependencies' => $field_item['dependencies'] ?? false ); } elseif (is_array($field_item['css'])) { $css_merge = ""; // CSS is an array of strings foreach ($field_item['css'] as $css_item) { $css_merge .= $this->adjust_css_placeholders( $css_item, "#metaslider-id-{$slideshow_id}", $stored[$field_item['name']] ) . "\n"; } // Store final CSS an dependencies if any linked to its name $pre_output[$field_item['name']] = array( 'value' => $stored[$field_item['name']], 'css' => $css_merge, 'dependencies' => $field_item['dependencies'] ?? false ); } else { // CSS is a single string // Store final CSS an dependencies if any linked to its name $pre_output[$field_item['name']] = array( 'value' => $stored[$field_item['name']], 'css' => $this->adjust_css_placeholders( $field_item['css'], "#metaslider-id-{$slideshow_id}", $stored[$field_item['name']] ) . "\n", 'dependencies' => $field_item['dependencies'] ?? false ); } } } } else { // Check if setting from manifest exists in db if (isset($stored[$row_item['name']]) && isset($row_item['css'])) { if ($row_item['css'] == 'css_rules' && isset($row_item['css_rules'])) { // CSS code is actually on css_rules key (aka css = 'css_rules') BUT based on value parameter // @TODO Maybe allow array of CSS too as in regular css key? // Is this field linked to another field through their css_field key? // We're using only value_linked_to_field() on settings // in row (not inside fields) with css_rules only. Perhaps support more in future? $linked_field = $this->value_linked_to_field( $manifest, $stored, $row_item['name'] ); if ( $linked_field === false ) { // Store final CSS an dependencies if any linked to its name $pre_output[$row_item['name']] = array( 'value' => $stored[$row_item['name']], 'css' => $this->adjust_css_placeholders( $row_item['css_rules'][$stored[$row_item['name']]], "#metaslider-id-{$slideshow_id}", $stored[$row_item['name']] ) . "\n", 'dependencies' => $row_item['dependencies'] ?? false ); } else { // Is a css_field linked; take css from linked css_field $pre_output[$row_item['name']] = array( 'value' => $stored[$row_item['name']], 'css' => $this->adjust_css_placeholders( $row_item['css_rules'][$stored[$row_item['name']]], "#metaslider-id-{$slideshow_id}", $linked_field ) . "\n", 'dependencies' => $row_item['dependencies'] ?? false ); } } elseif ( $row_item['css'] == 'css_field' ) { // Is a css_field. We're skipping it... } elseif (is_array($row_item['css'])) { $css_merge = ""; // CSS is an array of strings foreach ($row_item['css'] as $css_item) { $css_merge .= $this->adjust_css_placeholders( $css_item, "#metaslider-id-{$slideshow_id}", $stored[$row_item['name']] ) . "\n"; } // Store final CSS an dependencies if any linked to its name $pre_output[$row_item['name']] = array( 'value' => $stored[$row_item['name']], 'css' => $css_merge, 'dependencies' => $row_item['dependencies'] ?? false ); } else { // CSS is a single string // Store final CSS an dependencies if any linked to its name $pre_output[$row_item['name']] = array( 'value' => $stored[$row_item['name']], 'css' => $this->adjust_css_placeholders( $row_item['css'], "#metaslider-id-{$slideshow_id}", $stored[$row_item['name']] ) . "\n", 'dependencies' => $row_item['dependencies'] ?? false ); } } } } } return $this->filter_customize_css( $pre_output ); } /** * Add the theme to the class so styles will apply. The theme can be * overridden, for example from the preview functionality * * @param string $class The slideshow classlist * @param string $slideshow_id The id of the slideshow * @param string $settings The settings for the slideshow */ public function add_theme_class($class, $slideshow_id, $settings) { $class .= ' ms-theme-' . $this->theme_id; return $class; } /** * Add the default class when no theme is selected * * @since 3.31 * * @param string $class The slideshow classlist * @param string $slideshow_id The id of the slideshow * @param string $settings The settings for the slideshow */ public function add_no_theme_class( $class, $slideshow_id, $settings ) { $class .= ' ms-theme-default'; return $class; } /** * Adjust CSS from customize.php to replace [ms_id] and [value] placeholders * * @since 3.94 * * @param string $css e.g. '[ms_id] .flexslider .caption-wrap a { color: [ms_value] }' * @param string $id e.g. "#metaslider-id-{$slideshow_id}" * @param string|int|float $value e.g. 'rgba(255,255,255,0.8)' or 18 * * @return string */ public function adjust_css_placeholders($css, $id, $value) { $search = array( '[ms_id]', '[ms_value]', '[ms_field_value]' ); $replace = array( $id, strip_tags( $value ), strip_tags( $value ) ); return str_replace($search, $replace, $css); } /** * Sanitize and validate color formats (hex, rgb, rgba) * * @since 3.95 * * @param string $color * * @return string|bool Return color or false if invalid */ public function sanitize_color( $color ) { $hexRegex = '/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/'; $rgbRegex = '/^rgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)$/'; $rgbaRegex = '/^rgba\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*(0|1|0?\.\d+)\s*\)$/'; return preg_match( $hexRegex, $color ) || preg_match( $rgbRegex, $color ) || preg_match( $rgbaRegex, $color ) ? $color : false; } /** * Validate and sanitize range * * @since 3.96 * * @param string $number * * @return string|bool Return number as string or false if invalid */ public function sanitize_range( $number, $min, $max ) { // Clean up the input to remove unwanted characters $number = sanitize_text_field( $number ); // Match valid numbers: -123, 45, 1.8, -0.5, or 0 if ( preg_match( '/^-?\d+(\.\d)?$/', $number ) ) { // If valid, cast to float or integer based on the input $number = strpos( $number, '.') !== false ? (float) $number : (int) $number; //$min = strpos( (String) $min, '.') !== false ? (float) $min : (int) $min; //$max = strpos( (String) $max, '.') !== false ? (float) $max : (int) $max; // Check $number is between $min and $max return $number >= $min && $number <= $max ? (String) $number : false; } // Invalid $number return false; } /** * Validate and sanitize select * @TODO - Check if $value is one of the available options in $item['options']? * * @since 3.96 * * @param string $number * * @return string */ public function sanitize_select( $value ) { return sanitize_text_field( $value ); } /** * Get theme manifest (customize.php) * * @since 3.96 * * @param string $theme Theme name in lowercase (slug). e.g. 'bitono' * @param string $type 'free' or 'premium' * * @return array */ public function get_theme_manifest( $theme, $type ) { $manifest = array(); // Is a premium, external or custom theme (v2), override $manifest path if ($type !== 'free') { // Check if is a custom v2 based on a free theme $manifest = $this->add_base_customize_settings_single($theme); /** * Check if is a premium or custom theme (v2) based on a premium theme * by looping extra themes/ folders added from external sources, * including MetaSlider Pro. * We may also support external themes (custom coded themes added by users). * * e.g. * array( * '/path/to/wp-content/plugins/ml-slider-pro/themes/', * '/path/to/wp-content/themes/my-theme/ms-themes/' * ) */ if (! count($manifest)) { $extra_themes = apply_filters('metaslider_extra_themes', array()); foreach ($extra_themes as $location) { // Check if customize.php file that belongs to $theme as theme name (lowercase) exists if (file_exists($customize_file = trailingslashit($location) . trailingslashit($theme) . 'customize.php')) { // Get the data from customize.php files $manifest = $this->add_base_customize_settings_single( $theme, $customize_file ); break; } } } } else { // Is a free theme - Get data from themes/$theme/customize.php $manifest = $this->add_base_customize_settings_single($theme); } return $manifest; } /** * Theme is free, premium... ? * * @since 3.96 * * @param string $theme Theme name in lowercase (slug). e.g. 'bitono' * * return string|bool */ public function get_theme_type( $theme ) { $data = $this->get_single_theme( $theme ); if ( isset( $data['type'] ) ) { return $data['type']; } return false; } /** * Validate and sanitize manifest vs stored or submitted theme customize * * @since 3.96 * * @param $array $manifest The manifest customize data. e.g. $manifest['customize'] * @param $array $stored The stored data. e.g. 'theme_customize' data at ml-slider_settings postmeta * * return array */ public function validate_theme_stored( $manifest, $stored ) { // Valid and sanitized $stored $stored_valid = array(); if ( ! is_array( $manifest ) ) { return $stored_valid; } foreach ( $manifest as $section ) { // Loop each section 'settings' key foreach ( $section['settings'] as $row_item ) { // If type is 'fields', let's look for the list of fields. // Usually for multiple color fields grouped together if ( $row_item['type'] === 'fields' ) { foreach ( $row_item['fields'] as $field_item ) { // Check if setting from manifest exists in $stored and sanitized value is not false if ( isset( $stored[$field_item['name']] ) && ( $value_ = $this->sanitize_theme_setting( $field_item, $stored[$field_item['name']] ) ) !== false ) { $stored_valid[$field_item['name']] = $value_; } } } else { // Check if setting from manifest exists in $stored and sanitized value is not false if ( isset( $stored[$row_item['name']] ) && ( $value_ = $this->sanitize_theme_setting( $row_item, $stored[$row_item['name']] ) ) !== false ) { $stored_valid[$row_item['name']] = $value_; } } } } return $stored_valid; } /** * Sanitize individual custom theme setting * * @since 3.96 * * @param array $item e.g. array( * 'label' => esc_html__('Default', 'ml-slider'), * 'name' => 'arrows_color', * 'type' => 'color', * 'default' => '#333333', * 'css' => '[ms_id] .flexslider .flex-direction-nav li a { background: [ms_value] }' * ) * @param string|float $value The db stored or submitted value * * @return bool|string If false, stored value is invalid */ public function sanitize_theme_setting( $item, $value ) { switch ( $item['type'] ) { case 'color': return $this->sanitize_color( $value ); break; case 'select': return $this->sanitize_select( $value ); break; case 'range': return $this->sanitize_range( $value, $item['min'], $item['max'] ); break; } return false; } }
/home/batcwwjx/www/wp-content/plugins/ml-slider/admin/./slideshows/Themes.php