File manager - Edit - /home/nandedex/public_html/s.nandedexpress.com/ml-slider.tar
Back
admin/Notices.php 0000644 00000050337 15121325451 0007760 0 ustar 00 <?php if (!defined('ABSPATH')) { die('No direct access.'); } if (!class_exists('Updraft_Notices_1_0')) { require_once(METASLIDER_PATH . 'admin/lib/Updraft_Notices.php'); } /** * Meta Slider Notices */ class MetaSlider_Notices extends Updraft_Notices_1_0 { /** * All Ads * * @var object $ads */ protected $ads; /** * Notices content * * @var object $notices_content */ protected $notices_content; /** * Populates ad content and loads assets */ public function __construct() { /* * There are three options you can use to force ads to show. * The second two require the first to be set to true * * define('METASLIDER_FORCE_NOTICES', true); * * Be sure not to set both of these at the same time * define('METASLIDER_FORCE_LITE_NOTICES', true); * define('METASLIDER_FORCE_PRO_NOTICES', true); * */ $this->ads = $this->lite_notices(); // To avoid showing the user ads off the start, lets wait $this->notices_content = ($this->ad_delay_has_finished()) ? $this->ads : array(); add_action('admin_enqueue_scripts', array($this, 'add_notice_assets')); add_action('wp_ajax_notice_handler', array($this, 'ajax_notice_handler')); // Notices in admin pages except in MetaSlider admin pages - See MetaSliderPlugin->filter_admin_notices() add_action('admin_notices', array($this, 'show_dashboard_notices')); // @since 3.90.1 - Notices in MetaSlider admin pages add_action('metaslider_admin_notices', array($this, 'show_dashboard_notices')); } /** * Handles assets for the notices */ public function add_notice_assets() { wp_enqueue_style('ml-slider-notices-css', METASLIDER_ADMIN_URL . 'assets/css/notices.css', false, METASLIDER_ASSETS_VERSION); wp_register_script('metaslider-notices-extra-js', ''); wp_enqueue_script('metaslider-notices-extra-js'); $nonce = wp_create_nonce('metaslider_handle_notices_nonce'); $this->wp_add_inline_script( 'metaslider-notices-extra-js', "window.metaslider_notices_handle_notices_nonce = '{$nonce}'" ); } /** * Deprecated for MetaSlider for now */ public function notices_init() { return; } /** * Returns notices that free/lite users should see. dismiss_time should match the key * hide_time is in weeks. Use a string to hide for 9999 weeks. * * @return array returns an array of notices */ protected function lite_notices() { if (defined('METASLIDER_FORCE_PRO_NOTICES') && METASLIDER_FORCE_PRO_NOTICES) { // Override to force pro, but make sure both overrides arent set return (!defined('METASLIDER_FORCE_LITE_NOTICES')) ? $this->pro_notices() : array(); } return [ 'rate_plugin' => [ 'title' => _x('Like MetaSlider? Please help us by giving a positive review at WordPress.org', 'Keep the plugin name "MetaSlider" when possible', 'ml-slider'), 'text' => '', 'image' => 'notices/metaslider_logo.png', 'button_link' => 'metaslider_rate', 'button_meta' => 'review', 'dismiss_time' => 'rate_plugin', 'hide_time' => 12, 'supported_positions' => ['header'], ], 'pro_layers' => [ 'title' => __('Spice up your site with animated layers and video slides with MetaSlider Pro', 'ml-slider'), 'text' => '', 'image' => 'notices/metaslider_logo.png', 'button_link' => 'metaslider', 'button_meta' => 'buy-w-discount', 'dismiss_time' => 'pro_layers', 'hide_time' => 12, 'supported_positions' => ['header'], 'validity_function' => 'metaslider_pro_is_not_installed', ], 'pro_features' => [ 'title' => __('Increase your revenue and conversion with video slides and many more MetaSlider Pro features', 'ml-slider'), 'text' => '', 'image' => 'notices/metaslider_logo.png', 'button_link' => 'metaslider', 'button_meta' => 'buy-w-discount', 'dismiss_time' => 'pro_features', 'hide_time' => 12, 'supported_positions' => ['header'], 'validity_function' => 'metaslider_pro_is_not_installed', ], 'translation' => [ 'title' => __('Can you translate? Want to improve MetaSlider for speakers of your language?', 'ml-slider'), 'text' => '', 'image' => 'notices/metaslider_logo.png', 'button_link' => 'metaslider_translate', 'button_meta' => 'lets_start', 'dismiss_time' => 'translation', 'hide_time' => 12, 'supported_positions' => ['header'], 'validity_function' => 'translation_needed', ], ]; } /** * Premium user notices, if any. * * @return array */ protected function pro_notices() { if (defined('METASLIDER_FORCE_LITE_NOTICES') && METASLIDER_FORCE_LITE_NOTICES) { // Override to force pro, but make sure both overrides arent set return (!defined('METASLIDER_FORCE_PRO_NOTICES')) ? $this->lite_notices() : []; } return []; } /** * Add fields needed for an notice to show * * @param string $notice - the name of the notice * @return array */ public function prepare_notice_fields($notice) { if (!isset($notice['dismiss_time']) && isset($notice['discount_code'])) { $notice['dismiss_time'] = $notice['discount_code']; } return $notice; } /** * Checks if MetaSlider Pro is NOT installed * * @return bool */ protected function metaslider_pro_is_not_installed() { return ! metaslider_pro_is_installed(); } /** * Checks if the user agent isn't set as en_GB or en_US, and if the language file doesn't exist * * @param string $plugin_base_dir The plguin base directory * @param string $product_name Product name * @return bool */ protected function translation_needed($plugin_base_dir = '', $product_name = '') { return parent::translation_needed(METASLIDER_PATH, 'ml-slider'); } /** * This method checks to see if the ad has been dismissed * * @param string $ad_identifier - identifier for the ad * @return bool returns true when we dont want to show the ad */ protected function check_notice_dismissed($ad_identifier) { if ($this->force_ads()) { return false; } return (time() < get_option("ms_hide_{$ad_identifier}_ads_until")); } /** * Checks whether this is an ad page - hard-coded * * @return bool */ protected function is_page_with_ads() { global $pagenow; $page = isset($_GET['page']) ? sanitize_key($_GET['page']) : ''; // I'm thinking to limit the check to the actual settings page for now // This way, if they activate the plugin but don't start using it until // a few weeks after, it won't bother them with ads. // return ('index.php' === $pagenow) || ($page === 'metaslider'); return ($page === 'metaslider'); } /** * This method checks to see if the ad waiting period is over (2 weeks) * If not, it will set a two week time * * @return bool returns true when we dont want to show the ad */ protected function ad_delay_has_finished() { // The delay could be empty, ~2 weeks (initial delay) or ~12 weeks $delay = get_option("ms_hide_all_ads_until"); if ($this->force_ads()) { // If there's an override, return true return true; } if (!$this->is_page_with_ads() && !$delay) { // Only start the timer if they see a page that can serve ads return false; } if (!$delay) { // Set the delay for when they will first see an ad, 2 weeks; returns false return !update_option("ms_hide_all_ads_until", time() + 2 * 7 * 86400); } elseif ((time() > $delay) && !get_option("ms_ads_first_seen_on")) { // Serve ads now, and note the time they first saw ads update_option("ms_ads_first_seen_on", time()); // Now that they can see ads, make sure the rate_plugin is shown first. // Since this shows after 2 weeks, it's better timing. $notices = $this->lite_notices(); $this->ads = array('rate_plugin' => $notices['rate_plugin']); return true; } elseif (time() < $delay) { // This means an ad was dismissed and there's a delay return false; } elseif (get_option("ms_ads_first_seen_on")) { // This means the initial delay has elapsed, // and the dismissed period expired return true; } if (metaslider_pro_is_installed()) { // If they are pro don't check anything but show the pro ad. return true; } // Default to not show an ad, in case there's some error return false; } /** * Method to handle dashboard notices */ public function show_dashboard_notices() { $current_page = get_current_screen(); if ('dashboard' === $current_page->base && metaslider_user_is_ready_for_notices()) { // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $this->do_notice(false, 'dashboard', true); } } /** * Selects the template and returns or displays the notice * * @param array $notice_information - variable names/values to pass through to the template * @param bool $return_instead_of_echo - whether to * @param string $position - where the notice is being displayed * @return null|string - depending on the value of $return_instead_of_echo */ protected function render_specified_notice($notice_information, $return_instead_of_echo = false, $position = 'header') { $views = array( 'header' => 'header-notice.php', ); $view = isset($views[$position]) ? $views[$position] : 'header-notice.php'; return $this->include_template($view, $return_instead_of_echo, $notice_information); } /** * Displays or returns the template * * @param string $path file name of the template * @param bool $return_instead_of_echo Return the template instead of printing * @param array $args template arguments * @return null|string */ public function include_template($path, $return_instead_of_echo = false, $args = array()) { if ( $return_instead_of_echo ) { ob_start(); } if ( ! empty( $args['hide_time']) && is_int($args['hide_time'])) { $hide_time = $args['hide_time'] . ' ' . __('weeks', 'ml-slider'); } include METASLIDER_PATH . 'admin/views/notices/' . $path; if ($return_instead_of_echo) { return ob_get_clean(); } } /** * Builds a link based on the type of notice being requested * * @param string $link - the URL to link to * @param string $type - which notice is being displayed * @return string - the resulting HTML */ public function get_button_link($link, $type) { $messages = array( 'lets_start' => __('Let\'s Start →', 'ml-slider'), 'review' => _x('Review MetaSlider →', 'Keep the plugin name "MetaSlider" when possible', 'ml-slider'), 'ml-slider' => __('Find out more →', 'ml-slider'), 'buy-w-discount' => __('Get MetaSlider Pro →', 'ml-slider'), 'signup' => __('Sign up →', 'ml-slider'), 'go_there' => __('Go there →', 'ml-slider') ); $message = isset($messages[$type]) ? $messages[$type] : __('Read more', 'ml-slider'); return '<a class="updraft_notice_link ml-discount-ad-button" target="_blank" href="' . esc_url($this->get_notice_url($link)) . '">' . esc_html($message) . '</a>'; } /** * Handles any notice related ajax calls * * @return void */ public function ajax_notice_handler() { if (! isset($_REQUEST['_wpnonce']) || ! wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'metaslider_handle_notices_nonce')) { wp_send_json_error(array( 'message' => __('The security check failed. Please refresh the page and try again.', 'ml-slider') ), 401); } $capability = apply_filters('metaslider_capability', MetaSliderPlugin::DEFAULT_CAPABILITY_EDIT_SLIDES); if (! current_user_can($capability)) { wp_send_json_error( [ 'message' => __('Access denied. Sorry, you do not have permission to complete this task.', 'ml-slider') ], 403 ); } if (! isset($_POST['ad_identifier'])) { wp_send_json_error(array( 'message' => __('Bad request', 'ml-slider') ), 400); } $ad_data = $this->ad_exists(sanitize_key($_POST['ad_identifier'])); if (is_wp_error($ad_data)) { wp_send_json_error(array( 'message' => __('This item does not exist. Please refresh the page and try again.', 'ml-slider') ), 401); } $result = $this->dismiss_ad($ad_data['dismiss_time'], $ad_data['hide_time']); if (is_wp_error($result)) { wp_send_json_error(array( 'message' => $result->get_error_message() ), 409); } wp_send_json_success(array( 'message' => __('The option was successfully updated', 'ml-slider'), ), 200); } /** * Returns the available ads that havent been dismissed by the user * * @param string|array $location the location for the ad * @param boolean $bypass_delay Bypass the ad delay * @return array the identifier for the ad */ public function active_ads($location = 'header', $bypass_delay = false) { $dismissed_ads = array(); $ads = ($bypass_delay) ? $this->ads : $this->notices_content; // Filter through all site options (cached) foreach (wp_load_alloptions() as $key => $value) { if (strpos($key, 'ms_hide_') && strpos($key, '_ads_until')) { $key = str_replace(array('ms_hide_', '_ads_until'), '', $key); $dismissed_ads[$key] = $value; } } // Filter out if the dismiss time has expired, then compare to the database $valid_ads = array(); foreach ($ads as $ad_identifier => $values) { $is_valid = isset($values['validity_function']) ? (bool)call_user_func([$this, $values['validity_function']]) : true; $not_dismissed = !$this->check_notice_dismissed($ad_identifier); $is_supported = in_array($location, $values['supported_positions']); if ($is_valid && $not_dismissed && $is_supported) { $valid_ads[$ad_identifier] = $values; } } return array_diff_key($valid_ads, $dismissed_ads); } /** * Returns all possible ads or the specified identifier * * @param string|null $ad_identifier Ad Identifier * @return string|null the data of the ad */ public function get_ad($ad_identifier = null) { $all_notices = array_merge($this->pro_notices(), $this->lite_notices()); return is_null($ad_identifier) ? $all_notices : $all_notices['ad_identifier']; } /** * Checks if the ad identifier exists in any of the ads above * * @param string $ad_identifier Ad Identifier * @return bool the data of the ad */ public function ad_exists($ad_identifier) { $all_notices = array_merge($this->pro_notices(), $this->lite_notices()); if (isset($all_notices[$ad_identifier])) { return $all_notices[$ad_identifier]; } return new WP_Error('bad_call', __('The requested data does not exist.', 'ml-slider'), array('status' => 401)); } /** * Updates the stored value for how long to hide the ads * * @param string $ad_identifier Ad Identifier * @param int|string $weeks time in weeks or a string to show * @return bool|WP_Error whether the update was a success */ public function dismiss_ad($ad_identifier, $weeks) { // If the time isn't specified it will hide "forever" (9999 weeks) // Update 12/18/2017 - will set this an extra week, so that this individual ad will hide, for example, 13 weeks, while ALL ads will hide for 12 weeks. This ensures that the user doesn't see the same ad twice. Minor detail. $weeks = is_int($weeks) ? $weeks + 1 : 9999; $result = update_option("ms_hide_{$ad_identifier}_ads_until", time() + $weeks * 7 * 86400); // Update 12/18/2017 - Hide all ads for 12 weeks (this used to be 24 hours) // This skips over the scenario when a user has seen a seasonal ad within the 2 week grace period. That way we can still show them the "rate plugin" ad after 2 weeks. if (get_option("ms_ads_first_seen_on")) { update_option("ms_hide_all_ads_until", time() + 12 * 7 * 86400); } return $result ? $result : new WP_Error('update_failed', __('The attempt to update the option failed.', 'ml-slider'), array('status' => 409)); } /** * Returns the url for a notice link * * @param string $link_id the link to get the url * @return string the url for the link id */ public function get_notice_url($link_id) { $urls = array( 'metaslider' => apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade'), 'metaslider_rate' => 'https://wordpress.org/support/plugin/ml-slider/reviews?rate=5#new-post', 'metaslider_survey' => 'https://www.metaslider.com/survey', 'metaslider_survey_pro' => 'https://www.metaslider.com/survey-pro', 'metaslider_translate' => 'https://translate.wordpress.org/projects/wp-plugins/ml-slider', ); // Return the website url if the ID was not set if (!isset($urls[$link_id])) { return 'https://www.metaslider.com'; } // Return if analytics code is already set if (strpos($urls[$link_id], 'utm_source')) { return esc_url($urls[$link_id]); } // Add our analytics code return esc_url(add_query_arg(array( 'utm_source' => 'metaslider-plugin-page', 'utm_medium' => 'banner' ), $urls[$link_id])); } /** * Forces ads to show when any override is set */ private function force_ads() { return (defined('METASLIDER_FORCE_NOTICES') && METASLIDER_FORCE_NOTICES) || (defined('METASLIDER_FORCE_PRO_NOTICES') && METASLIDER_FORCE_PRO_NOTICES) || (defined('METASLIDER_FORCE_LITE_NOTICES') && METASLIDER_FORCE_LITE_NOTICES); } /** * Polyfill to handle the wp_add_inline_script() function. * * @param string $handle The script identifier * @param string $data The script to add, without <script> tags * @param string $position Whether to output before or after * * @return object|bool */ public function wp_add_inline_script($handle, $data, $position = 'after') { if (function_exists('wp_add_inline_script')) { return wp_add_inline_script($handle, $data, $position); } global $wp_scripts; if (!$data) { return false; } // First fetch any existing scripts $script = $wp_scripts->get_data($handle, 'data'); // Append to the end $script .= $data; return $wp_scripts->add_data($handle, 'data', $script); } } admin/support/Analytics.php 0000644 00000023440 15121325451 0012012 0 ustar 00 <?php if (!defined('ABSPATH')) { die('No direct access.'); } /** * Class to handle analytics for MetaSlider. Will act more like a controller */ class MetaSlider_Analytics { /** * @var Appsero\Insights $appsero */ public $appsero; /** * @var array $whereToShow */ public $whereToShow = array('plugins', 'dashboard'); /** * Start various analytics systems * * @return void */ public function __construct() { // Since only one service for now, keep it simple and just load it directly $this->boot( apply_filters('metaslider_appsero_app_key', 'c3c10cf6-1a8f-4d7f-adf3-6bbbc5fe2885'), apply_filters('metaslider_appsero_app_name', 'MetaSlider'), apply_filters('metaslider_appsero_app_path', METASLIDER_PATH . 'ml-slider.php') ); // Show notice only if they are not already opt in (pro will override this to show the opt-out notice once) add_action('wp_ajax_handle_optin_action', array($this, 'handleOptinDismiss')); add_action('admin_enqueue_scripts', array($this, 'addAdminNonce')); } /** * Show the dang thing * * @return void */ public function addAdminNonce() { wp_register_script('metaslider-optin-extra-js', ''); wp_enqueue_script('metaslider-optin-extra-js'); $nonce = wp_create_nonce('metaslider_optin_notice_nonce'); $this->wp_add_inline_script( 'metaslider-optin-extra-js', "window.metaslider_optin_notice_nonce = '{$nonce}'" ); } /** * Handle the skip on the notice * * @return void */ public function handleOptinDismiss() { if (! isset($_REQUEST['_wpnonce']) || ! wp_verify_nonce(sanitize_key($_REQUEST['_wpnonce']), 'metaslider_optin_notice_nonce')) { wp_send_json_error(array( 'message' => esc_html__('The security check failed. Please refresh the page and try again.', 'ml-slider') ), 401); } // They opted in, so we can instruct Appsero to communicate with the server if (isset($_REQUEST['activate']) && filter_var($_REQUEST['activate'], FILTER_VALIDATE_BOOLEAN)) { update_option('metaslider_optin_via', 'notice', true); $this->optin(); } update_user_option(get_current_user_id(), 'metaslider_optin_notice_dismissed', time()); wp_send_json_success(); } /** * Start Appsero's insights client * * @var string $key - The app key * @var string $name - The app slug * @var string $path - The app path to main file * * @return MetaSlider_Analytics */ public function boot($key, $name, $path) { if (is_multisite()) { return $this; } if (!class_exists('Appsero\\Client')) { require_once(METASLIDER_PATH . 'lib/appsero/src/Client.php'); } add_filter('ml-slider_tracker_data', array($this, 'filterTrackingData')); $client = new Appsero\Client($key, $name, $path); $this->appsero = $client->insights(); return $this; } /** * Start Appsero's insights client * * @return void */ public function load() { if (!$this->appsero) { return; } if (self::siteIsOptin()) { // If the user has opted in to sharing data with MetaSlider, we can skip the Appsero opt in // $this->appsero->hide_notice()->init()->optinIfNotAlready(); <-- would be nice $this->appsero->hide_notice()->add_extra(array($this, 'extraDataToCollect'))->init(); if (get_option('ml-slider_allow_tracking') === 'no') { $this->appsero->optin(); } } else { // Here we are hiding the notice for users that aren't opted in, because we are serving our own notices // We will make sure they are opted out from appsero too. Note, this initializes, but that's just for // showing the notice and doesn't do any actual tracking unless the user approves. $this->appsero->hide_notice()->add_extra(array($this, 'extraDataToCollect'))->init(); if (get_option('ml-slider_allow_tracking') === 'yes') { $this->appsero->optout(); } } } /** * Filter Appsero's data * - We want the user that opts in, not the first admin user * * @var array $data - The data from Appsero * * @return array */ public function filterTrackingData($data) { if (!$extras = get_option('metaslider_optin_user_extras')) { return $data; } if ($admin_user = get_userdata($extras['id'])) { $data['admin_email'] = $admin_user->user_email; $data['first_name'] = $admin_user->first_name ? $admin_user->first_name : $admin_user->display_name; $data['last_name'] = $admin_user->last_name; } return $data; } /** * Add some extra fields - This is called async now so no need to cache it. * * @return array */ public function extraDataToCollect() { try { $sliders_count = new WP_Query(array( 'post_type' => 'ml-slider', 'post_status' => array('inherit', 'publish'), 'suppress_filters' => 1, 'posts_per_page' => -1 )); $date_activated = new DateTime(); $date_activated->setTimestamp((int) get_option('ms_hide_all_ads_until')); $date_activated->modify('-2 week'); $date_activated = $date_activated->getTimeStamp(); $data = array( 'has_pro_installed' => metaslider_pro_is_installed() ? metaslider_pro_version() : 'false', 'cancelled_tour_on' => get_option('metaslider_tour_cancelled_on'), 'optin_user_info' => get_option('metaslider_optin_user_extras'), 'optin_via' => get_option('metaslider_optin_via'), 'slider_count' => $sliders_count ? $sliders_count->found_posts : 0, 'first_activated_on' => $date_activated > 0 ? $date_activated : 0 ); return $data; } catch (\Exception $e) { return array(); } } /** * Helper method for checking whether the site has opted in * * @return boolean */ public static function siteIsOptin() { // Users of non-WP.org plugins can manage the opt in state manually here if (apply_filters('metaslider_force_optout', false)) { return self::updateOptinStatusTo(false); } if (apply_filters('metaslider_force_optin', false)) { return self::updateOptinStatusTo(true); } $settings = get_option('metaslider_global_settings'); return isset($settings['optIn']) && (int) $settings['optIn'] > 0; } /** * Helper method for setting the opt in status * * @var string $status - Whether the user is opt in ('true') or opt out ('false') * * @return boolean - The same as $status */ public static function updateOptinStatusTo($status) { $settings = get_option('metaslider_global_settings'); $settings['optIn'] = filter_var($status, FILTER_VALIDATE_BOOLEAN) ? 1 : 0; update_option('metaslider_global_settings', $settings, true); return filter_var($status, FILTER_VALIDATE_BOOLEAN); } /** * Method to optin * Note: Need to init() before optin/optout * * @return void */ public function optin() { $current_user = wp_get_current_user(); //check if there is a custom email added for optin $optin_email = get_option('metaslider_optin_email'); if (!empty($optin_email)) { $use_email = filter_var($optin_email, FILTER_SANITIZE_EMAIL); } else { $use_email = $current_user->user_email; } update_option('metaslider_optin_user_extras', array( 'id' => $current_user->ID, 'email' => $use_email, 'ip' => isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field($_SERVER['REMOTE_ADDR']) : '', // phpcs:ignore WordPressVIPMinimum.Variables.ServerVariables.UserControlledHeaders 'time' => time() )); if ($this->appsero) { $this->appsero->hide_notice()->add_extra(array($this, 'extraDataToCollect'))->init(); $this->appsero->optin(); } self::updateOptinStatusTo('true'); } /** * Method to optout * Note: Need to init() before optin/optout * * @return void */ public function optout() { // We could possibly track who opted out, but for now just clear it update_option('metaslider_optin_user_extras', array()); if ($this->appsero) { $this->appsero->hide_notice()->init(); $this->appsero->optout(); } self::updateOptinStatusTo('false'); } /** * Polyfill to handle the wp_add_inline_script() function. * * @param string $handle The script identifier * @param string $data The script to add, without <script> tags * @param string $position Whether to output before or after * * @return object|bool */ public function wp_add_inline_script($handle, $data, $position = 'after') { if (function_exists('wp_add_inline_script')) { return wp_add_inline_script($handle, $data, $position); } global $wp_scripts; if (!$data) { return false; } // First fetch any existing scripts $script = $wp_scripts->get_data($handle, 'data'); // Append to the end $script .= $data; return $wp_scripts->add_data($handle, 'data', $script); } } admin/support/Settings.php 0000644 00000002345 15121325451 0011664 0 ustar 00 <?php if (!defined('ABSPATH')) { die('No direct access.'); } if (! class_exists('MetaSlider_Settings')) { /** * Class to handle settings for MetaSlider. */ class MetaSlider_Settings { const GLOBAL_OPTIONS_OPTION_NAME = 'metaslider_global_settings'; /** * Instance object * * @var MetaSlider_Settings * @see get_instance() */ protected static $instance = null; public function __construct() { } /** * Used to access the instance * * @return MetaSlider_Settings - class instance */ public static function get_instance() { if (null === self::$instance) { self::$instance = new self(); } return self::$instance; } private function get_option($option_name, $default = null) { $settings = get_option(self::GLOBAL_OPTIONS_OPTION_NAME); if (false === $settings) { return $default; } if (! isset($settings[$option_name])) { return $default; } return $settings[$option_name]; } } } admin/Gutenberg.php 0000644 00000007016 15121325451 0010272 0 ustar 00 <?php if (!defined('ABSPATH')) { die('No direct access.'); } /** * Adds a MetaSlider block to Gutenberg */ class MetaSlider_Gutenberg { /** * Init */ public function __construct() { add_action('enqueue_block_editor_assets', array($this,'enqueue_block_scripts')); if (isset($_REQUEST['override_preview_style']) && filter_var($_REQUEST['override_preview_style'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { add_filter('metaslider_preview_styles', array($this, 'preview_styles')); } } /** * Enqueues gutenberg scripts */ public function enqueue_block_scripts() { $version = MetaSliderPlugin::get_instance()->version; // Enqueue the bundled block JS file wp_enqueue_script( 'metaslider-blocks', plugins_url('assets/dist/js/editor-block.js', __FILE__), array('wp-i18n', 'wp-element', 'wp-block-library', 'wp-components', 'wp-api'), $version ); wp_localize_script('metaslider-blocks', 'metaslider_block_config', array( 'preview_url' => add_query_arg('ms_gutenberg_preview', 1, set_url_scheme(home_url())), 'plugin_page' => admin_url('admin.php?page=metaslider') )); /* * gutenberg_get_jed_locale_data uses WP function get_translations_for_domain, * which can be usefull if we want to use wp.18n.__ in the rest of the plugin. */ $locale_data = $this->gutenberg_get_jed_locale_data('ml-slider'); wp_add_inline_script( 'metaslider-blocks', 'wp.i18n.setLocaleData(' . json_encode($locale_data) . ', \'ml-slider\');', 'before' ); // Enqueue optional editor only styles wp_enqueue_style( 'metaslider-blocks-editor-css', plugins_url('assets/dist/css/editor-block.css', __FILE__), array('wp-block-library'), $version ); } /** * Preview styles * * @param string $styles The preview styles * @return string */ public function preview_styles($styles) { ob_start(); ?> body, html { overflow: hidden; height: auto; margin:0; padding:0; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif; font-size: 14px; } .metaslider { margin: 0 auto; } <?php return ob_get_clean(); } /** * Backup function for Gutenberg's gutenberg_get_jed_locale_data * * @param string $domain - The text domain for the strings */ private function gutenberg_get_jed_locale_data($domain) { if (function_exists('gutenberg_get_jed_locale_data')) { return gutenberg_get_jed_locale_data($domain); } $translations = get_translations_for_domain($domain); $locale = array( '' => array( 'domain' => $domain, 'lang' => is_admin() && function_exists('get_user_locale') ? get_user_locale() : get_locale(), ), ); if (!empty($translations->headers['Plural-Forms'])) { $locale['']['plural_forms'] = $translations->headers['Plural-Forms']; } foreach ($translations->entries as $msgid => $entry) { $locale[$msgid] = $entry->translations; } return $locale; } } admin/Table.php 0000644 00000034560 15121325453 0007405 0 ustar 00 <?php if (!defined('ABSPATH')) { die('No direct access.'); } if (!class_exists('WP_List_table')) { require_once(ABSPATH . 'wp-admin/includes/class-wp-list-table.php'); } class MetaSlider_Admin_Table extends WP_List_table { public function prepare_items() { $this->process_action(); $columns = $this->get_columns(); $hidden = array(); $sortable = $this->get_sortable_columns(); $this->_column_headers = array($columns, $hidden, $sortable); if (isset($_REQUEST['s'])) { $table_data = $this->table_data(sanitize_text_field($_REQUEST['s'])); } else { $table_data = $this->table_data(); } //pagination $slideshows_per_page = 10; $table_page = $this->get_pagenum(); $this->items = array_slice($table_data, (($table_page - 1) * $slideshows_per_page), $slideshows_per_page); $total_slideshows = count($table_data); $this->set_pagination_args(array( 'total_items' => $total_slideshows, 'per_page' => $slideshows_per_page, 'total_pages' => ceil($total_slideshows/$slideshows_per_page) )); } public function no_items() { printf( esc_html__( 'You don\'t have any slideshows yet. Click %shere%s to create a new slideshow.', 'ml-slider' ), '<a href="' . esc_url(wp_nonce_url(admin_url("admin-post.php?action=metaslider_create_slider"), "metaslider_create_slider")) . '">','</a>' ); } protected function get_views() { global $wpdb; $views = array(); $paramaters = array('action', 'slideshows', 'post_status', '_wpnonce', 'paged'); $current = ( !empty($_REQUEST['post_status']) ? $_REQUEST['post_status'] : 'all'); $all = remove_query_arg($paramaters); $class = ($current == 'all' ? ' class="current"' :''); $views['all'] = "<a href='" . esc_url($all) . "' {$class} >" . esc_html__('Published', 'ml-slider') . " (" . $this->slideshow_count('all') . ")</a>"; if ($this->slideshow_count('trash') != 0) { $class = ($current == 'trash' ? ' class="current"' :''); $views['trash'] = "<a href='" . esc_url($all) . "&post_status=trash' {$class} >" . esc_html__('Trash', 'ml-slider') . " (" . $this->slideshow_count('trash') . ")</a>"; } return $views; } public function get_columns() { $columns = array( 'cb' => '<input type="checkbox" />', 'slides' => esc_html__('Preview', 'ml-slider'), 'post_title' => esc_html__('Title', 'ml-slider'), 'post_date' => esc_html__('Created', 'ml-slider'), 'ID' => esc_html__('Shortcode', 'ml-slider') ); return $columns; } public function get_bulk_actions() { if (isset($_REQUEST['post_status']) && $_REQUEST['post_status'] == "trash") { $actions = array( 'restore' => __('Restore', 'ml-slider'), 'permanent' => __('Delete Permanently', 'ml-slider') ); } else { $actions = array( 'delete' => __('Trash', 'ml-slider') ); } return $actions; } public function get_hidden_columns() { return array(); } public function get_sortable_columns() { $sortable_columns = array( 'post_title' => array('post_title',false), 'post_date' => array('post_date',false), 'ID' => array('ID',false) ); return $sortable_columns; } public function column_default($item, $column_name) { switch($column_name) { case 'slides': return $this->slideshow_thumb($item[ 'ID' ]); case 'post_title': return $item[ $column_name ]; case 'post_date': $date = strtotime($item[ $column_name ]); $dateFormat = get_option('date_format'); $timeFormat = get_option( 'time_format' ); return ucfirst( wp_date( $dateFormat.' \a\t '.$timeFormat, $date ) ); case 'ID': return $this->shortcodeColumn($item[$column_name]); default: return print_r($item, true); } } public function shortcodeColumn($slideshowID) { return ('<pre class="copy-shortcode tipsy-tooltip" original-title="' . __('Click to copy shortcode.', 'ml-slider') . '"><div class="text-orange cursor-pointer whitespace-normal inline">[metaslider id="'. esc_attr($slideshowID) .'"]</div></pre><span class="copy-message" style="display:none;"><div class="dashicons dashicons-yes"></div></span>'); } protected function column_cb($item) { return sprintf( '<input type="checkbox" name="slideshows[]" value="%d" />', (int)$item['ID'] ); } protected function process_action() { if (isset($_POST['_wpnonce']) && ! empty($_POST['_wpnonce'])) { $nonce = filter_input( INPUT_POST, '_wpnonce', FILTER_SANITIZE_SPECIAL_CHARS ); $action = 'bulk-' . $this->_args['plural']; if ( ! wp_verify_nonce($nonce, $action)) { wp_die( 'Cannot process action' ); } } if (isset($_POST['delete_all'])) { $slideshows = $this->table_data('', 'trash'); foreach($slideshows as $slideshow_id) { wp_delete_post($slideshow_id['ID'], true); } } if(isset($_GET['_wpnonce'])) { if ( ! wp_verify_nonce($_GET['_wpnonce'], 'metaslider-action')) { wp_die( 'Cannot process action' ); } } $action = $this->current_action(); if(isset($_REQUEST['slideshows'])) { if(is_array($_REQUEST['slideshows'])) { $slideshows = array_map('intval', $_REQUEST['slideshows']); } else { $toArray = array($_REQUEST['slideshows']); $slideshows = array_map('intval', $toArray); } } else { //single slider if(isset($_REQUEST['id'])) { $toArray = array($_REQUEST['id']); $slideshows = array_map('intval', $toArray); } } switch ( $action ) { case 'delete': foreach($slideshows as $slideshow_id) { wp_update_post(array( 'ID' => $slideshow_id, 'post_status' => 'trash' )); } break; case 'permanent': foreach($slideshows as $slideshow_id) { wp_delete_post( $slideshow_id, true); } break; case 'restore': foreach($slideshows as $slideshow_id) { wp_update_post(array( 'ID' => $slideshow_id, 'post_status' => 'publish' )); $slides = $this->get_slides($slideshow_id, 'trash'); foreach ($slides as $key => $slide) { wp_update_post(array( 'ID' => $slide->ID, 'post_status' => 'publish' )); } } break; default: return; break; } return; } private function table_data($search='', $status='all') { global $wpdb; $wpdbTable = $wpdb->prefix . 'posts'; $columns = ['slides', 'post_title', 'post_date']; $orderBy = isset($_GET['orderby']) && in_array($_GET['orderby'], $columns, true ) ? $_GET['orderby'] : 'ID'; $order = isset($_GET['order']) && 'desc' === $_GET['order'] ? 'desc' : 'asc'; $orderBySql = sanitize_sql_orderby( "{$orderBy} {$order}" ); $status = isset($_GET['post_status']) && 'trash' === $_GET['post_status'] ? 'trash' : 'all'; if (!empty($search)) { $slides_query = $wpdb->prepare("SELECT ID, post_title, post_date FROM $wpdbTable WHERE post_type = %s AND post_status = %s AND post_title LIKE %s ORDER BY $orderBySql", array('ml-slider', 'publish', '%'. $wpdb->esc_like($search). '%')); // WPCS: unprepared SQL OK. } else { if( $status == 'all' ) { $slides_query = $wpdb->prepare("SELECT ID, post_title, post_date FROM $wpdbTable WHERE post_type = %s AND post_status = %s ORDER BY $orderBySql", array('ml-slider', 'publish')); // WPCS: unprepared SQL OK. } else { $slides_query = $wpdb->prepare("SELECT ID, post_title, post_date FROM $wpdbTable WHERE post_type = %s AND post_status = %s ORDER BY $orderBySql", array('ml-slider', 'trash')); // WPCS: unprepared SQL OK. } } $query_results = $wpdb->get_results($slides_query, ARRAY_A ); // WPCS: unprepared SQL OK. return $query_results; } private function slideshow_count($status = 'all') { global $wpdb; $wpdbTable = $wpdb->prefix . 'posts'; if ($status == 'trash') { $slides_query = $wpdb->prepare("SELECT ID, post_title, post_date FROM $wpdbTable WHERE post_type = %s AND post_status = %s", array('ml-slider', 'trash')); // WPCS: unprepared SQL OK. } else { $slides_query = $wpdb->prepare("SELECT ID, post_title, post_date FROM $wpdbTable WHERE post_type = %s AND post_status = %s", array('ml-slider', 'publish')); // WPCS: unprepared SQL OK. } $wpdb->get_results($slides_query, ARRAY_A ); // WPCS: unprepared SQL OK. return $wpdb->num_rows; } public function getslide_thumb($slideId) { $logo = 'data:image/svg+xml;base64,' . base64_encode(file_get_contents(dirname(__FILE__) . '/assets/metaslider.svg')); if (get_post_type($slideId) == 'attachment') { $image = wp_get_attachment_image_src($slideId, 'thumbnail'); } else { $image = wp_get_attachment_image_src(get_post_thumbnail_id($slideId), 'thumbnail'); } if (isset($image[0])) { $slidethumb = "<img src='". esc_url($image[0]) ."'>"; } else { $slidethumb = "<img src='". $logo ."' class='thumb-logo'>"; } return $slidethumb; } public function get_slides($slideshowId, $status) { $slides = get_posts(array( 'post_type' => array('ml-slide'), 'post_status' => array($status), 'orderby' => 'menu_order', 'order' => 'ASC', 'lang' => '', 'suppress_filters' => 1, 'posts_per_page' => -1, 'tax_query' => array( array( 'taxonomy' => 'ml-slider', 'field' => 'slug', 'terms' => (int) $slideshowId ) ) )); return $slides; } public function slideshow_thumb($slideshowId) { $slides = $this->get_slides($slideshowId, 'publish'); $numberOfSlides = count($slides); $logo = 'data:image/svg+xml;base64,' . base64_encode(file_get_contents(dirname(__FILE__) . '/assets/metaslider.svg')); $thumbHtml = "<div class='w-16 h-16 bg-gray-light slidethumb'>"; if ($numberOfSlides === 0) { $thumbHtml .= "<img src='". $logo ."' class='thumb-logo'>"; } else { if ($numberOfSlides === 1){ $thumbHtml .= $this->getslide_thumb($slides[0]->ID); } else { foreach ($slides as $key => $slide) { $thumbHtml .= $this->getslide_thumb($slide->ID); } } } $thumbHtml .= "</div>"; return $thumbHtml; } public function column_post_title($item) { $page = empty($_REQUEST['page']) ? 'metaslider' : sanitize_key($_REQUEST['page']); if(isset($_GET['post_status']) && $_GET['post_status'] == 'trash') { $restoreUrl = wp_nonce_url('?page=' . $page . '&post_status=trash&action=restore&slideshows=' . absint($item['ID']), 'metaslider-action' ); $deleteUrl = wp_nonce_url('?page=' . $page . '&post_status=trash&action=permanent&slideshows=' . absint($item['ID']), 'metaslider-action' ); $actions = [ 'restore' => '<a href="' . esc_url($restoreUrl) . '">' . esc_html__('Restore', 'ml-slider') . '</a>', 'permanent' => '<a class="submitdelete" href="' . esc_url($deleteUrl) . '">' . esc_html__('Delete Permanently', 'ml-slider') . '</a>', ]; return sprintf( '%1$s %2$s', '<a class="row-title">' . esc_html($item['post_title']) . '</a>', $this->row_actions($actions) ); } else { $editUrl = '?page=' . $page . '&id=' . absint($item['ID']); $deleteUrl = wp_nonce_url('?page=' . $page . '&action=delete&slideshows=' . absint($item['ID']), 'metaslider-action' ); $actions = [ 'edit' => '<a href="' . esc_url($editUrl) . '">' . esc_html__('Edit', 'ml-slider') . '</a>', 'trash' => '<a class="submitdelete" href="' . esc_url($deleteUrl) . '">' . esc_html__('Trash', 'ml-slider') . '</a>', ]; return sprintf( '%1$s %2$s', '<a class="row-title" href="' . esc_url($editUrl) . '">' . esc_html($item['post_title']) . '</a>', $this->row_actions($actions) ); } } public function extra_tablenav( $which ) { if ( $which == "top" ) { if (isset($_REQUEST['post_status']) && $_REQUEST['post_status'] == "trash") { if ( ! empty($this->table_data('', 'trash'))) { submit_button( __( 'Empty Trash' ), 'apply', 'delete_all', false ); } } } } public function check_num_rows() { $table_data = $this->table_data(); return $table_data; } } admin/views/slides/tabs/link.php 0000644 00000004331 15121325453 0012655 0 ustar 00 <?php if ( ! defined( 'ABSPATH' ) ) { die( 'No direct access.' ); } ?> <div class="row alt-link mb-2"> <div class="mb-2"> <label> <?php esc_html_e( 'Image Link URL', 'ml-slider' ) ?> <span class="dashicons dashicons-info tipsy-tooltip-top" title="<?php esc_attr_e('When visitors click on your image slide, they will be taken to this URL.', 'ml-slider') ?>" style="line-height: 1.2em;"></span> </label> </div> <div class="row has-right-checkbox mb-0"> <div> <input class="url" data-lpignore="true" type="text" name="attachment[<?php echo esc_attr($slide_id); ?>][url]" placeholder="<?php echo esc_attr("URL", "ml-slider"); ?>" value="<?php echo esc_url($url); ?>" /> </div> <div class="input-label"> <label> <?php esc_html_e( 'New window', 'ml-slider' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $this->info_tooltip( __( 'Open link in a new window', 'ml-slider' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $this->switch_button( 'attachment[' . esc_attr( $slide_id ) . '][new_window]', (bool) $target, array( 'autocomplete' => 'off', 'tabindex' => '0' ), 'mr-0 ml-2' ); ?> </label> </div> </div> </div> <div class="row alt-link"> <div class="mb-1 link-alt-label"> <label> <?php esc_html_e( 'Image Link Alt Text', 'ml-slider' ); ?> <span class="dashicons dashicons-info tipsy-tooltip-top" title="<?php esc_attr_e('This text is used by search engines and visitors using screen readers. Adding Alt text for links is highly recommended.', 'ml-slider') ?>"></span> </label> </div> <input type="text" size="50" name="attachment[<?php echo esc_attr($slide_id); ?>][link-alt]" placeholder="<?php echo esc_attr("Enter text here", "ml-slider"); ?>" value="<?php echo esc_attr($link_alt); ?>"> </div> admin/views/slides/tabs/mobile.php 0000644 00000011144 15121325453 0013167 0 ustar 00 <?php if (!defined('ABSPATH')) { die('No direct access.'); } $slideshow_defaults = array(); if (is_multisite() && $settings = get_site_option('metaslider_default_settings')) { $slideshow_defaults = $settings; } if ($settings = get_option('metaslider_default_settings')) { $slideshow_defaults = $settings; } if(!isset($slideshow_defaults['smartphone'])){ $slideshow_defaults['smartphone'] = 320; } if(!isset($slideshow_defaults['tablet'])){ $slideshow_defaults['tablet'] = 768; } if(!isset($slideshow_defaults['laptop'])){ $slideshow_defaults['laptop'] = 1024; } if(!isset($slideshow_defaults['desktop'])){ $slideshow_defaults['desktop'] = 1440; } $screen = array('smartphone', 'tablet', 'laptop', 'desktop'); $default_sizes = array($slideshow_defaults['smartphone'], $slideshow_defaults['tablet'], $slideshow_defaults['laptop'], $slideshow_defaults['desktop']); $settings = get_post_meta($this->slider->ID, 'ml-slider_settings', true); $hide_css = 'display: none'; if (isset($settings['type']) && $settings['type'] == 'flex') { $hide_css = 'display: block'; } ?> <div class="row flex-setting" style="<?php echo esc_attr($hide_css); ?>"> <label style="margin-right: 20px;"><?php esc_html_e("Hide slide on:", "ml-slider"); ?></label> <?php $checked_slide = ''; foreach ($screen as $key => $value) { $hideslide = get_post_meta($slide_id, 'ml-slider_hide_slide_' . $value, true); if (!empty($hideslide)) { $checked_slide = 'checked = "checked"'; } else { $checked_slide = ''; } if($key == 3){ $tooltip = sprintf( __( 'When enabled this setting will hide the slide on screen widths equal to or greater than %spx', 'ml-slider' ), $default_sizes[$key] ); } else { $maxkey = $key + 1; $max_width = $default_sizes[$maxkey] - 1; $tooltip = sprintf( __( 'When enabled this setting will hide the slide on screen widths of %1$spx to %2$spx', 'ml-slider' ), $default_sizes[$key], $max_width ); } ?> <span class="mobile-checkbox-wrap"> <input type="checkbox" name="attachment[<?php echo esc_attr($slide_id); ?>][hide_slide_<?php echo esc_attr($value); ?>]" class="mobile-checkbox tipsy-tooltip-top" title="<?php echo esc_attr($tooltip); ?>" <?php echo esc_attr($checked_slide); ?> /> <span class="dashicons <?php echo esc_attr( 'dashicons-' . $value ); ?>"></span> </span> <?php } ?> </div> <div class="row"> <label style="margin-right: 4px;"><?php esc_html_e("Hide caption on:", "ml-slider"); ?></label> <?php $checked_caption = ''; foreach ($screen as $key => $value) { $hidecaption = get_post_meta($slide_id, 'ml-slider_hide_caption_' . $value, true); if (!empty($hidecaption)) { $checked_caption = 'checked = "checked"'; } else { $checked_caption = ''; } if($key == 3){ $tooltip = sprintf( __( 'When enabled this setting will hide the caption on screen widths equal to or greater than %spx', 'ml-slider' ), $default_sizes[$key] ); } else { $maxkey = $key + 1; $max_width = $default_sizes[$maxkey] - 1; $tooltip = sprintf( __( 'When enabled this setting will hide the caption on screen widths of %1$spx to %2$spx', 'ml-slider' ), $default_sizes[$key], $max_width ); } ?> <span class="mobile-checkbox-wrap"> <input type="checkbox" name="attachment[<?php echo esc_attr($slide_id); ?>][hide_caption_<?php echo esc_attr($value); ?>]" class="mobile-checkbox tipsy-tooltip-top" title="<?php echo esc_attr($tooltip); ?>" <?php echo esc_attr($checked_caption); ?> /> <span class="dashicons <?php echo esc_attr( 'dashicons-' . $value ); ?> "></span> </span> <?php } ?> </div> admin/views/slides/tabs/crop.php 0000644 00000003755 15121325453 0012674 0 ustar 00 <?php if (!defined('ABSPATH')) { die('No direct access.'); } ?> <div class="row has-right-field"> <label> <?php esc_html_e("Crop Position", "ml-slider"); ?> <span class="dashicons dashicons-info tipsy-tooltip-top" title="<?php esc_attr_e('Choose how images are cropped if their size doesn\'t exactly match the size of your slideshow. This works if "Smart Crop" is selected in the "Image Crop" settings.', 'ml-slider') ?>" style="line-height: 1.2em;"></span> </label> <select class="crop_position" name="attachment[<?php echo esc_attr($slide_id); ?>][crop_position]"> <option value="left-top" <?php echo selected($crop_position, 'left-top', false); ?>> <?php esc_html_e("Top Left", "ml-slider"); ?></option> <option value="center-top" <?php echo selected($crop_position, 'center-top', false); ?>> <?php esc_html_e("Top Center", "ml-slider"); ?></option> <option value="right-top" <?php echo selected($crop_position, 'right-top', false); ?>> <?php esc_html_e("Top Right", "ml-slider"); ?></option> <option value="left-center" <?php echo selected($crop_position, 'left-center', false); ?>> <?php esc_html_e("Center Left", "ml-slider"); ?></option> <option value="center-center" <?php echo selected($crop_position, 'center-center', false); ?>> <?php esc_html_e("Center Center", "ml-slider"); ?></option> <option value="right-center" <?php echo selected($crop_position, 'right-center', false); ?>> <?php esc_html_e("Center Right", "ml-slider"); ?></option> <option value="left-bottom" <?php echo selected($crop_position, 'left-bottom', false); ?>> <?php esc_html_e("Bottom Left", "ml-slider"); ?></option> <option value="center-bottom" <?php echo selected($crop_position, 'center-bottom', false); ?>> <?php esc_html_e("Bottom Center", "ml-slider"); ?></option> <option value="right-bottom" <?php echo selected($crop_position, 'right-bottom', false); ?>> <?php esc_html_e("Bottom Right", "ml-slider"); ?></option> </select> </div> admin/views/slides/tabs/general.php 0000644 00000002554 15121325453 0013342 0 ustar 00 <?php if (!defined('ABSPATH')) die('No direct access.'); ?> <div class="thumb-col-settings"> <?php // Handle captions if( isset( $_GET['metaslider_add_sample_slides'] ) ){ $slide_caption = (esc_html( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent vitae.' )); } else { $slide_caption = $this->cleanup_content_kses( $this->slide->post_excerpt ); } $image_caption = (wp_filter_post_kses($attachment->post_excerpt)); $image_description = (wp_filter_post_kses($attachment->post_content)); // Deprecate inherit_image_caption by deleting it and setting the source as the image if (filter_var(get_post_meta($this->slide->ID, 'ml-slider_inherit_image_caption', true), FILTER_VALIDATE_BOOLEAN)) { update_post_meta($this->slide->ID, 'ml-slider_caption_source', 'image-caption'); delete_post_meta($this->slide->ID, 'ml-slider_inherit_image_caption'); } $caption_source = get_post_meta($this->slide->ID, 'ml-slider_caption_source', true); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $this->get_admin_slide_thumb(); ?> <div> <metaslider-caption image-caption="<?php echo esc_attr($image_caption); ?>" image-description="<?php echo esc_attr($image_description); ?>" override="<?php echo esc_attr($slide_caption); ?>" caption-source="<?php echo esc_attr($caption_source); ?>"></metaslider-caption> </div> </div> admin/views/slides/tabs/schedule.php 0000644 00000001545 15121325453 0013520 0 ustar 00 <?php if (!defined('ABSPATH')) { die('No direct access.'); } ?> <div class="schedule_placeholder"> <?php if (metaslider_pro_is_installed()) : ?> <p style="mb-0 text-base"><?php esc_html_e('Update or activate your MetaSlider Pro now to add a start/end date option to your slides', 'ml-slider'); ?></p> <?php else : ?> <h1><?php esc_html_e('Get MetaSlider Pro', 'ml-slider'); ?></h1> <p><?php esc_html_e('With MetaSlider Pro, you can schedule your slides. You can choose to show your slides on specific dates, days of the week, or times of day.', 'ml-slider'); ?></p> <a href="<?php echo esc_url(metaslider_get_upgrade_link()); ?>" class="probutton button button-primary button-hero" target="_blank"><?php esc_html_e('Upgrade now', 'ml-slider'); ?> <span class='dashicons dashicons-external'></span></a> <?php endif; ?> </div> admin/views/slides/tabs/seo.php 0000644 00000006233 15121325453 0012511 0 ustar 00 <?php if (!defined('ABSPATH')) { die('No direct access.'); } ?> <div class="row mb-2 can-inherit title<?php echo esc_attr($inherit_image_title_class); ?>"> <div class="mb-1 image-title-label"> <label> <?php esc_html_e("Image Title Text", "ml-slider"); ?> <span class="dashicons dashicons-info tipsy-tooltip-top" title="<?php esc_attr_e('Visitors will see this text if they hover over your image slide. Adding Title text is useful but not required.', 'ml-slider') ?>"></span> </label> <div class="input-label right"> <label class="small" title="<?php esc_attr_e("Enable this to inherit the image title", "ml-slider"); ?>"> <?php esc_html_e( 'Use the image title', 'ml-slider' ); echo $this->switch_button( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 'attachment[' . esc_attr( $slide_id ) . '][inherit_image_title]', $inherit_image_title_check, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped array( 'autocomplete' => 'off', 'class' => 'js-inherit-from-image' ), 'mr-0 ml-1' ); ?> </label> </div> </div> <div class="default"><?php echo $image_title ? esc_html($image_title) : "<span class='no-content'> </span>"; ?></div> <input tabindex="0" type="text" size="50" name="attachment[<?php echo esc_attr($slide_id); ?>][title]" value="<?php echo esc_attr($title); ?>"> </div> <div class="row can-inherit alt<?php echo esc_attr($inherit_image_alt_class); ?>"> <div class="mb-1 image-alt-label"> <label> <?php esc_html_e("Image Alt Text", "ml-slider"); ?> <span class="dashicons dashicons-info tipsy-tooltip-top" title="<?php esc_attr_e('This text is used by search engines and visitors using screen readers. Adding Alt text is highly recommended.', 'ml-slider') ?>"></span> </label> <div class="input-label right"> <label class="small" title="<?php esc_attr_e('Enable this to inherit the image alt text', 'ml-slider'); ?>"> <?php esc_html_e( 'Use the image alt text', 'ml-slider' ); ?> <?php echo $this->switch_button( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 'attachment[' . esc_attr( $slide_id ) . '][inherit_image_alt]', $inherit_image_alt_check, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped array( 'autocomplete' => 'off', 'class' => 'js-inherit-from-image' ), 'mr-0 ml-1' ); ?> </label> </div> </div> <div class="default"><?php echo $image_alt ? esc_html($image_alt) : "<span class='no-content'> </span>"; ?></div> <input tabindex="0" type="text" size="50" name="attachment[<?php echo esc_attr($slide_id); ?>][alt]" value="<?php echo esc_attr($alt); ?>"> </div> admin/views/pages/settings.php 0000644 00000020423 15121325453 0012443 0 ustar 00 <?php if (!defined('ABSPATH')) { die('No direct access.'); } ?> <div id="metaslider-ui" class="metaslider metaslider-ui block min-w-0 p-0 bg-white relative" style="min-height:calc(100vh - 32px)"> <metaslider-toolbar inline-template> <div id="ms-toolbar" class="flex-col bg-white h-16 shadow-sm sticky z-999"> <div class="h-full px-6"> <div class="flex items-center h-full -mx-4"> <a href="<?php echo esc_url(admin_url('admin.php?page=metaslider')) ?>" class="flex items-center h-full py-2 px-4"> <img style="height:46px;width:auto;" class="mr-2 rtl:mr-0 rtl:ml-2" src="<?php echo esc_url(METASLIDER_ADMIN_URL . 'images/metaslider_logo3.png'); ?>" alt="MetaSlider"> </a> </div> </div> </div> </metaslider-toolbar> <div v-if="isIE11" class="justify-center bg-gray-lighter" :class="{'flex': isIE11, 'hidden': !isIE11}" style="display:none"> <?php include METASLIDER_PATH . "admin/views/pages/parts/ie-warning.php"; ?> </div> <div v-else> <metaslider inline-template> <metaslider-settings-page inline-template> <div id="metaslider-settings-page" class="border-b border-gray-light flex h-full inset-0 min-w-0 p-0 w-full" :class="{'absolute': !hasNotice}"> <div class="flex md:flex-shrink-0"> <div class="flex flex-col md:w-48 border-r border-gray-lightest pt-5 pb-4 bg-white"> <div class="-mt-1 h-0 flex-1 flex flex-col overflow-y-auto"> <nav class="flex-1 px-2 py-1 bg-white"> <a href="#" @click.prevent="loadPage('settings')" @keydown.space.prevent="loadPage('settings')" @keyup.enter.prevent="loadPage('settings')" class="mt-1 group flex items-center justify-between px-2 py-2 text-sm leading-5 font-medium text-gray-darker rounded-md hover:text-gray-darkest hover:bg-gray-light focus:outline-none transition ease-in-out duration-150" :class="{'text-gray-darker bg-gray-light': 'settings' === component}"> <span class="hidden md:flex"><?php esc_html_e('Settings', 'ml-slider'); ?></span> <svg class='opacity-0 md:mr-2 w-5 group-hover:text-gray-darkest group-focus:text-gray-darkest transition ease-in-out duration-150' :class="{'opacity-100': true, 'text-gray-darker': 'settings' === component, 'md:text-white': 'settings' !== component}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" /> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /> </svg> </a> <a href="#" @click.prevent="loadPage('helpcenter')" @keydown.space.prevent="loadPage('helpcenter')" @keyup.enter.prevent="loadPage('helpcenter')" class="mt-1 group flex items-center justify-between px-2 py-2 text-sm leading-5 font-medium text-gray-darker rounded-md hover:text-gray-darkest hover:bg-gray-light focus:outline-none transition ease-in-out duration-150" :class="{'text-gray-darker bg-gray-light': 'helpcenter' === component}"> <span class="hidden md:flex"><?php esc_html_e('Help Center', 'ml-slider'); ?></span> <svg class='opacity-0 md:mr-2 w-5 group-hover:text-gray-darkest group-focus:text-gray-darkest transition ease-in-out duration-150' :class="{'opacity-100': true, 'text-gray-darker': 'helpcenter' === component, 'md:text-white': 'helpcenter' !== component}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z" /> </svg> </svg> </a> <a href="#" @click.prevent="loadPage('import')" @keydown.space.prevent="loadPage('import')" @keyup.enter.prevent="loadPage('import')" class="mt-1 group flex items-center justify-between px-2 py-2 text-sm leading-5 font-medium text-gray-darker rounded-md hover:text-gray-darkest hover:bg-gray-light transition ease-in-out duration-150" :class="{'text-gray-darker bg-gray-light': 'import' === component}"> <span class="hidden md:flex"><?php esc_html_e('Import', 'ml-slider'); ?></span> <svg class='opacity-0 md:mr-2 w-5 group-hover:text-gray-darkest group-focus:text-gray-darkest transition ease-in-out duration-150' :class="{'opacity-100': true, 'text-gray-darker': 'import' === component, 'md:text-white': 'import' !== component}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" /> </svg> </a> <a href="#" @click.prevent="loadPage('export')" @keydown.space.prevent="loadPage('export')" @keyup.enter.prevent="loadPage('export')" class="mt-1 group flex items-center justify-between px-2 py-2 text-sm leading-5 font-medium text-gray-darker rounded-md hover:text-gray-darkest hover:bg-gray-light transition ease-in-out duration-150" :class="{'text-gray-darker bg-gray-light': 'export' === component}"> <span class="hidden md:flex"><?php esc_html_e('Export', 'ml-slider'); ?></span> <svg class='opacity-0 md:mr-2 w-5 group-hover:text-gray-darkest group-focus:text-gray-darkest transition ease-in-out duration-150' :class="{'opacity-100': true, 'text-gray-darker': 'export' === component, 'md:text-white': 'export' !== component}" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" /> </svg> </a> <?php do_action('metaslider_settings_page_nav_items'); ?> </nav> </div> </div> </div> <div class="flex flex-col w-0 flex-1 overflow-hidden"> <main class="flex-1 relative z-0 overflow-y-auto py-6 focus:outline-none" tabindex="0"> <div class="max-w-7xl w-full px-4 md:px-6 md:px-8"> <transition name="settings-fade" mode="out-in"> <?php $slideshowCount = wp_count_posts('ml-slider'); ?> <component :needs-slideshows="<?php echo $slideshowCount->publish < 1 ? 'true' : 'false'; ?>" :is="$options.components[component]"></component> </transition> </div> </main> </div> </div> </metaslider-settings-page> </metaslider> </div> </div> admin/views/pages/start.php 0000644 00000006646 15121325454 0011754 0 ustar 00 <?php if (!defined('ABSPATH')) die('No direct access.'); $demo_options = array( array( 'slug' => 'carousel', 'label' => esc_html__( 'Carousel Slideshow', 'ml-slider' ) ), array( 'slug' => 'withcaption', 'label' => esc_html__( 'Carousel Slideshow with Captions', 'ml-slider' ) ) ); // Allow to add new options $demo_options = apply_filters( 'metaslider_quickstart_options', $demo_options ); ?> <div id="metaslider-ui"> <div class="metaslider-start mt-16"> <div class="metaslider-welcome"> <div class="welcome-panel-content items-center"> <h2><?php esc_html_e('Thanks for using MetaSlider, the WordPress slideshow plugin', 'ml-slider'); ?></h2> </div> <div class="welcome-panel-content" style="min-height:270px;"> <div class="ms-panel-container"> <div class=""> <div> <h3 class="ms-heading"><?php esc_html_e('Create a slideshow with your images', 'ml-slider'); ?></h3> <p><?php esc_html_e('Choose your own images to start a new slideshow.', 'ml-slider'); ?></p> </div> <div> <div id="plupload-upload-ui" class="hide-if-no-js"> <div id="drag-drop-area"> <div class="drag-drop-inside"> <p class="drag-drop-info"><?php _e('Drop files to upload'); ?></p> <p><?php _ex('or', 'Uploader: Drop files to upload - or - Select Files'); ?></p> <p class="drag-drop-buttons"> <input id="plupload-browse-button" type="button" value="<?php esc_attr_e('Select Files'); ?>" class="button" /> <button id="quickstart-browse-button" class="button"><?php esc_html_e('Open Media Library', 'ml-slider'); ?></button> </p> </div> </div> </div> <div class="media-upload-form"> <div id="media-items" class="hide-if-no-js"></div> </div> </div> </div> <div class=""> <div> <h3 class="ms-heading"><?php esc_html_e('Create a slideshow with sample images', 'ml-slider'); ?></h3> <p> <?php echo apply_filters( 'metaslider_quickstart_description', esc_html__('Create a demo slideshow.', 'ml-slider')); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> </p> </div> <div class="try-gutenberg-action"> <select id="sampleslider-options"> <option value="<?php echo esc_url(wp_nonce_url(admin_url("admin-post.php?action=metaslider_create_slider"), "metaslider_create_slider")); ?>"><?php esc_html_e('Blank Slideshow', 'ml-slider'); ?></option> <option value="<?php echo esc_url(wp_nonce_url(admin_url("admin-post.php?action=metaslider_create_slider&metaslider_add_sample_slides"), "metaslider_create_slider")); ?>"><?php esc_html_e('Image Slideshow', 'ml-slider'); ?></option> <?php foreach ( $demo_options as $item ) : ?> <option value="<?php echo esc_url( wp_nonce_url( admin_url( 'admin-post.php?action=metaslider_create_slider&metaslider_add_sample_slides=' . $item['slug'] ), 'metaslider_create_slider' ) ) ?>"> <?php echo esc_html( $item['label'] ) ?> </option> <?php endforeach; ?> </select> <button id="sampleslider-btn" class="button button-primary"><?php esc_html_e('Create a Slideshow', 'ml-slider'); ?></button> </div> </div> </div> </div> </div> </div> </div> <?php // TODO: I think after here maybe we can add images from their media library, or perhaps from an external image API admin/views/pages/parts/slider-settings-legacy.php 0000644 00000132560 15121325454 0016325 0 ustar 00 <table class="ms-settings-table border-0"> <tbody> <?php $aFields = array( 'type' => array( 'priority' => 0, 'type' => 'slider-lib', 'value' => $this->slider->get_setting('type'), 'options' => array( 'flex' => array('label' => "FlexSlider"), 'responsive' => array('label' => "R. Slides"), 'nivo' => array('label' => "Nivo Slider"), 'coin' => array('label' => "Coin Slider") ) ), 'mainOptions' => array( 'priority' => 1, 'type' => 'highlight', 'value' => esc_html__( 'Main Options', 'ml-slider' ) ), 'width' => array( 'priority' => 10, 'type' => 'number', 'size' => 3, 'min' => 0, 'max' => 9999, 'step' => 1, 'value' => $this->slider->get_setting('width'), 'label' => __("Width", "ml-slider"), 'class' => 'coin flex responsive nivo', 'helptext' => __("Slideshow width", "ml-slider"), 'after' => __("px", "ml-slider") ), 'height' => array( 'priority' => 20, 'type' => 'number', 'size' => 3, 'min' => 0, 'max' => 9999, 'step' => 1, 'value' => $this->slider->get_setting('height'), 'label' => __("Height", "ml-slider"), 'class' => 'coin flex responsive nivo', 'helptext' => __("Slideshow height", "ml-slider"), 'after' => __("px", "ml-slider") ), 'effect' => array( 'priority' => 30, 'type' => 'select', 'value' => $this->slider->get_setting('effect'), 'label' => __("Transition Effect", "ml-slider"), 'class' => 'effect coin flex responsive nivo width w-40', 'helptext' => __("This animation is used when changing slides.", "ml-slider"), 'dependencies' => array( array( 'show' => 'easing', // Show Easing setting 'when' => 'slide' // When Effect is 'slide' ), array( 'show' => 'firstSlideFadeIn', 'when' => 'fade' ) ), 'options' => array( 'random' => array( 'class' => 'option coin nivo', 'label' => __("Random", "ml-slider") ), 'swirl' => array( 'class' => 'option coin', 'label' => __("Swirl", "ml-slider") ), 'rain' => array( 'class' => 'option coin', 'label' => __("Rain", "ml-slider") ), 'straight' => array( 'class' => 'option coin', 'label' => __("Straight", "ml-slider") ), 'sliceDown' => array( 'class' => 'option nivo', 'label' => __("Slice Down", "ml-slider") ), 'sliceUp' => array( 'class' => 'option nivo', 'label' => __("Slice Up", "ml-slider") ), 'sliceUpLeft' => array( 'class' => 'option nivo', 'label' => __("Slice Up Left", "ml-slider") ), 'sliceUpDown' => array( 'class' => 'option nivo', 'label' => __("Slide Up Down", "ml-slider") ), 'sliceUpDownLeft' => array( 'class' => 'option nivo', 'label' => __("Slice Up Down Left", "ml-slider") ), 'fade' => array( 'class' => 'option nivo flex responsive', 'label' => __("Fade", "ml-slider") ), 'fold' => array( 'class' => 'option nivo', 'label' => __("Fold", "ml-slider") ), 'slideInRight' => array( 'class' => 'option nivo', 'label' => __("Slide in Right", "ml-slider") ), 'slideInLeft' => array( 'class' => 'option nivo', 'label' => __("Slide in Left", "ml-slider") ), 'boxRandom' => array( 'class' => 'option nivo', 'label' => __("Box Random", "ml-slider") ), 'boxRain' => array( 'class' => 'option nivo', 'label' => __("Box Rain", "ml-slider") ), 'boxRainReverse' => array( 'class' => 'option nivo', 'label' => __("Box Rain Reverse", "ml-slider") ), 'boxRainGrow' => array( 'class' => 'option nivo', 'label' => __("Box Rain Grow", "ml-slider") ), 'boxRainGrowReverse' => array( 'class' => 'option nivo', 'label' => __("Box Rain Grow Reverse", "ml-slider") ), 'slide' => array( 'class' => 'option flex', 'label' => __("Slide", "ml-slider") ) ), ), 'links' => array( 'priority' => 50, 'type' => 'checkbox', 'label' => __("Arrows", "ml-slider"), 'class' => 'option coin flex nivo responsive', 'checked' => $this->slider->get_setting( 'links' ) == 'true' ? 'checked' : '', 'helptext' => __( "Show the Previous / Next arrows.", "ml-slider" ), 'dependencies' => array( array( 'show' => 'mobileArrows_smartphone', 'when' => true ) ) ), 'navigation' => array( 'priority' => 60, 'type' => 'navigation', 'label' => __("Navigation", "ml-slider"), 'class' => 'option coin flex nivo responsive', 'value' => $this->slider->get_setting('navigation'), 'helptext' => __( "Show navigation options so that users can browse the slides.", "ml-slider" ), 'options' => array( 'false' => array( 'label' => __("Hidden", "ml-slider") ), 'true' => array( 'label' => __("Dots", "ml-slider") ), 'thumbs' => array( 'label' => __("Thumbnail", "ml-slider"), 'addon_required' => true ), 'filmstrip' => array( 'label' => __("Filmstrip", "ml-slider"), 'addon_required' => true ), ), 'dependencies' => array( array( 'show' => 'mobileNavigation_smartphone', 'when' => array( 'true', 'thumbs', 'filmstrip' ) ), array( 'show' => 'ariaCurrent', 'when' => array( 'true', 'thumbs', 'filmstrip' ) ), ) ), 'fullWidth' => array( 'priority' => 570, 'type' => 'checkbox', 'label' => esc_html__("100% width", "ml-slider"), 'class' => 'option flex nivo responsive', 'checked' => $this->slider->get_setting( 'fullWidth' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "Stretch the slideshow output to fill it's parent container.", "ml-slider" ) ), ); $aFields = apply_filters( 'metaslider_basic_settings', $aFields, $this->slider ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $this->build_settings_rows($aFields); ?> <tr class="empty-row-spacing"> <td colspan="2"></td> </tr> <tr class="highlight"> <td colspan="2"> <?php esc_html_e( 'Theme', 'ml-slider' ) ?> </td> </tr> <tr class="empty-row-spacing"> <td colspan="2"></td> </tr> <tr> <td colspan="2"> <metaslider-theme-viewer theme-directory-url="<?php echo esc_url(METASLIDER_THEMES_URL); ?>" ></metaslider-theme-viewer> </td> </tr> <tr class="empty-row-spacing"> <td colspan="2"></td> </tr> <?php // Mobile options if ( !isset( $global_settings['mobileSettings'] ) || ( isset( $global_settings['mobileSettings'] ) && true == $global_settings['mobileSettings'] ) ) { $default_settings = get_site_option( 'metaslider_default_settings' ); $breakpoints = array( 'smartphone' => isset( $default_settings['smartphone'] ) ? (int) $default_settings['smartphone'] : 320, 'tablet' => isset( $default_settings['tablet'] ) ? (int) $default_settings['tablet'] : 768, 'laptop' => isset( $default_settings['laptop'] ) ? (int) $default_settings['laptop'] : 1024, 'desktop' => isset( $default_settings['desktop'] ) ? (int) $default_settings['desktop'] : 1440 ); $aFields = array( 'advancedOptions' => array( 'priority' => 0, 'type' => 'highlight', 'value' => esc_html__( 'Mobile Options', 'ml-slider' ) ), 'mobileArrows' => array( 'priority' => 1, 'type' => 'mobile', 'label' => __("Hide arrows on", "ml-slider"), 'options' => array( 'smartphone' => array( 'checked' => $this->slider->get_setting('mobileArrows_smartphone') == 'true' ? 'checked' : '', 'helptext' => sprintf( __( 'When enabled this setting will hide the arrows on screen widths less than %spx.', 'ml-slider' ), $breakpoints['tablet'] ) ), 'tablet' => array( 'checked' => $this->slider->get_setting('mobileArrows_tablet') == 'true' ? 'checked' : '', 'helptext' => sprintf( __( 'When enabled this setting will hide the arrows on screen widths of %1$spx to %2$spx.', 'ml-slider' ), $breakpoints['tablet'], $breakpoints['laptop'] - 1 ) ), 'laptop' => array( 'checked' => $this->slider->get_setting('mobileArrows_laptop') == 'true' ? 'checked' : '', 'helptext' => sprintf( __( 'When enabled this setting will hide the arrows on screen widths of %1$spx to %2$spx.', 'ml-slider' ), $breakpoints['laptop'], $breakpoints['desktop'] - 1 ) ), 'desktop' => array( 'checked' => $this->slider->get_setting('mobileArrows_desktop') == 'true' ? 'checked' : '', 'helptext' => sprintf( __( 'When enabled this setting will hide the arrows on screen widths equal to or greater than %spx.', 'ml-slider' ), $breakpoints['desktop'] ) ), ), ), 'mobileNavigation' => array( 'priority' => 2, 'type' => 'mobile', 'label' => __("Hide navigation on", "ml-slider"), 'options' => array( 'smartphone' => array( 'checked' => $this->slider->get_setting('mobileNavigation_smartphone') == 'true' ? 'checked' : '', 'helptext' => sprintf( __( 'When enabled this setting will hide the navigation on screen widths less than %spx.', 'ml-slider' ), $breakpoints['tablet'] ) ), 'tablet' => array( 'checked' => $this->slider->get_setting('mobileNavigation_tablet') == 'true' ? 'checked' : '', 'helptext' => sprintf( __( 'When enabled this setting will hide the navigation on screen widths of %1$spx to %2$spx.', 'ml-slider' ), $breakpoints['tablet'], $breakpoints['laptop'] - 1 ) ), 'laptop' => array( 'checked' => $this->slider->get_setting('mobileNavigation_laptop') == 'true' ? 'checked' : '', 'helptext' => sprintf( __( 'When enabled this setting will hide the navigation on screen widths of %1$spx to %2$spx.', 'ml-slider' ), $breakpoints['laptop'], $breakpoints['desktop'] - 1 ) ), 'desktop' => array( 'checked' => $this->slider->get_setting('mobileNavigation_desktop') == 'true' ? 'checked' : '', 'helptext' => sprintf( __( 'When enabled this setting will hide the navigation on screen widths equal to or greater than %spx.', 'ml-slider' ), $breakpoints['desktop'] ) ), ) ), ); $aFields = apply_filters('metaslider_mobile_settings', $aFields, $this->slider); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $this->build_settings_rows($aFields); } ?> <tr class="empty-row-spacing"> <td colspan="2"></td> </tr> <?php // Advanced options $aFields = array( 'advancedOptions' => array( 'priority' => 3, 'type' => 'highlight', 'value' => esc_html__( 'Advanced Options', 'ml-slider' ) ), 'center' => array( 'priority' => 10, 'type' => 'checkbox', 'label' => esc_html__("Center align", "ml-slider"), 'class' => 'option coin flex nivo responsive', 'checked' => $this->slider->get_setting( 'center' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "Center align the slideshow in the available space on your website.", "ml-slider" ) ), 'autoPlay' => array( // Don't target 'autoPlay' to show/hide with 'dependencies' array key 'priority' => 20, 'type' => 'checkbox', 'label' => esc_html__("Auto play", "ml-slider"), 'class' => 'option flex nivo responsive coin', 'checked' => 'true' == $this->slider->get_setting( 'autoPlay' ) ? 'checked' : '', 'helptext' => esc_html__( "Transition between slides automatically.", "ml-slider" ) ), 'pausePlay' => array( // Don't target 'pausePlay' to show/hide with 'dependencies' array key 'priority' => 21, 'type' => 'checkbox', 'label' => esc_html__("Play / Pause Button", "ml-slider"), 'class' => 'option flex', 'checked' => $this->slider->get_setting( 'pausePlay' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "This allows user to pause or resume Auto Play on the slideshow.", "ml-slider" ) ), 'loop' => array( 'priority' => 25, 'type' => 'select', 'label' => __("Loop", "ml-slider"), 'class' => 'option flex nivo', 'helptext' => __('If you choose "Loop continuously", the slides will loop infinitely. If you choose "Stop on first slide", the slideshow will stop on the first slide after showing all the items. If you choose "Stop on last slide", the slides will stop on the last slide.', 'ml-slider'), 'value' => $this->slider->get_setting('loop'), 'options' => array( 'continuously' => array('label' => __("Loop continuously", "ml-slider"), 'class' => ''), 'stopOnLast' => array('label' => __("Stop on last slide", "ml-slider"), 'class' => ''), 'stopOnFirst' => array('label' => __("Stop on first slide", "ml-slider"), 'class' => ''), ) ), 'smartCrop' => array( 'priority' => 30, 'type' => 'select', 'label' => esc_html__("Image Crop", "ml-slider"), 'class' => 'option coin flex nivo responsive', 'value' => $this->slider->get_setting('smartCrop'), 'options' => array( 'true' => array( 'label' => esc_html__( "Smart Crop", "ml-slider" ), 'class' => '' ), 'false' => array( 'label' => esc_html__( "Standard", "ml-slider" ), 'class' => '' ), 'disabled' => array( 'label' => esc_html__( "Disabled", "ml-slider" ), 'class' => '' ), 'disabled_pad' => array( 'label' => esc_html__( "Disabled (Smart Pad)", "ml-slider" ), 'class' => 'option flex' ), ), 'helptext' => esc_html__( "Smart Crop ensures your responsive slides are cropped to a ratio that results in a consistent slideshow size.", "ml-slider" ) ), 'smoothHeight' => array( 'priority' => 35, 'type' => 'checkbox', 'label' => __("Smooth Height", "ml-slider"), 'class' => 'option flex', 'checked' => $this->slider->get_setting( 'smoothHeight' ) == 'true' ? 'checked' : '', 'helptext' => __( "Allow navigation to follow the slide's height smoothly.", "ml-slider" ) ), 'carouselMode' => array( 'priority' => 40, 'type' => 'checkbox', 'label' => esc_html__("Carousel mode", "ml-slider"), 'class' => 'option flex showNextWhenChecked', 'checked' => $this->slider->get_setting( 'carouselMode' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( 'Display multiple slides at once. Slideshow output will be 100% wide. Carousel Mode only uses the "Slide" Effect.', "ml-slider" ), 'dependencies' => array( array( 'show' => 'infiniteLoop', // Show Infinite loop 'when' => true // When carouselMode is true ), array( 'show' => 'loop', // Show Loop 'when' => false // When carouselMode is false ) ) ), 'infiniteLoop' => array( 'priority' => 43, 'type' => 'checkbox', 'label' => esc_html__("Loop Carousel Continuously", "ml-slider"), 'class' => 'option flex', 'checked' => $this->slider->get_setting( 'infiniteLoop' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "Infinite loop of slides when Carousel Mode is enabled. This option disables arrows and navigation.", "ml-slider" ) ), 'carouselMargin' => array( 'priority' => 45, 'min' => 0, 'max' => 9999, 'step' => 1, 'type' => 'number', 'label' => esc_html__("Carousel margin", "ml-slider"), 'class' => 'option flex', 'value' => $this->slider->get_setting('carouselMargin'), 'helptext' => esc_html__( "Pixel margin between slides in carousel.", "ml-slider" ), 'after' => esc_html__("px", "ml-slider") ), 'firstSlideFadeIn' => array( 'priority' => 47, 'type' => 'checkbox', 'label' => esc_html__("Fade in", "ml-slider"), 'class' => 'option flex', 'checked' => 'true' == $this->slider->get_setting( 'firstSlideFadeIn' ) ? 'checked' : '', 'helptext' => esc_html__( 'This adds an animation when the slideshow loads. It only uses the "Fade" transition effect.', "ml-slider" ), ), 'random' => array( 'priority' => 50, 'type' => 'checkbox', 'label' => esc_html__("Random", "ml-slider"), 'class' => 'option coin flex nivo responsive', 'checked' => $this->slider->get_setting( 'random' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "Randomise the order of the slides.", "ml-slider" ) ), 'hoverPause' => array( 'priority' => 60, 'type' => 'checkbox', 'label' => esc_html__("Hover pause", "ml-slider"), 'class' => 'option coin flex nivo responsive', 'checked' => $this->slider->get_setting( 'hoverPause' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "Pause the slideshow when hovering over slider, then resume when no longer hovering.", "ml-slider" ) ), 'reverse' => array( 'priority' => 70, 'type' => 'checkbox', 'label' => esc_html__("Reverse", "ml-slider"), 'class' => 'option flex', 'checked' => $this->slider->get_setting( 'reverse' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "Reverse the animation direction.", "ml-slider" ) ), 'touch' => array( 'priority' => 80, 'type' => 'checkbox', 'label' => esc_html__("Touch Swipe", "ml-slider"), 'class' => 'option flex', 'checked' => 'true' == $this->slider->get_setting( 'touch' ) ? 'checked' : '', 'helptext' => esc_html__( "Allow touch swipe navigation of the slider on touch-enabled devices.", "ml-slider" ) ), 'delay' => array( 'priority' => 85, 'type' => 'number', 'size' => 3, 'min' => 500, 'max' => 10000, 'step' => 100, 'value' => $this->slider->get_setting('delay'), 'label' => esc_html__("Slide delay", "ml-slider"), 'class' => 'option coin flex responsive nivo', 'helptext' => esc_html__( "How long to display each slide, in milliseconds.", "ml-slider" ), 'after' => esc_html_x( "ms", "Short for milliseconds", "ml-slider" ) ), 'animationSpeed' => array( 'priority' => 90, 'type' => 'number', 'size' => 3, 'min' => 0, 'max' => 2000, 'step' => 100, 'value' => $this->slider->get_setting('animationSpeed'), 'label' => esc_html__("Transition Speed", "ml-slider"), 'class' => 'option flex responsive nivo', 'helptext' => esc_html__( 'Choose the speed of the animation in milliseconds. You can select the animation in the "Effect" field.', 'ml-slider' ), 'after' => esc_html_x( "ms", "Short for milliseconds", "ml-slider" ) ), 'slices' => array( 'priority' => 100, 'type' => 'number', 'size' => 3, 'min' => 0, 'max' => 20, 'step' => 1, 'value' => $this->slider->get_setting('slices'), 'label' => esc_html__("Number of slices", "ml-slider"), 'class' => 'option nivo', 'helptext' => esc_html__("Number of slices", "ml-slider"), ), 'spw' => array( 'priority' => 110, 'type' => 'number', 'size' => 3, 'min' => 0, 'max' => 20, 'step' => 1, 'value' => $this->slider->get_setting('spw'), 'label' => esc_html__( "Number of squares", "ml-slider" ) . " (" . esc_html__("Width", "ml-slider") . ")", 'class' => 'option nivo', 'helptext' => esc_html__("Number of squares", "ml-slider"), 'after' => '' ), 'sph' => array( 'priority' => 120, 'type' => 'number', 'size' => 3, 'min' => 0, 'max' => 20, 'step' => 1, 'value' => $this->slider->get_setting('sph'), 'label' => esc_html__( "Number of squares", "ml-slider" ) . " (" . esc_html__("Height", "ml-slider") . ")", 'class' => 'option nivo', 'helptext' => esc_html__("Number of squares", "ml-slider"), 'after' => '' ), 'direction' => array( 'priority' => 130, 'type' => 'select', 'label' => esc_html__("Slide direction", "ml-slider"), 'class' => 'option flex', 'helptext' => esc_html__( 'Select the direction that slides will move. Vertical will not work if "Carousel mode" is enabled or "Effect" is set to "Fade".', 'ml-slider' ), 'value' => $this->slider->get_setting('direction'), 'options' => array( 'horizontal' => array( 'label' => esc_html__( "Horizontal", "ml-slider" ), 'class' => '' ), 'vertical' => array( 'label' => esc_html__( "Vertical", "ml-slider" ), 'class' => '' ), ) ), 'easing' => array( 'priority' => 140, 'type' => 'select', 'label' => esc_html__("Easing", "ml-slider"), 'class' => 'option flex', 'helptext' => esc_html__( 'Easing adds gradual acceleration and deceleration to slide transitions, rather than abrupt starts and stops. Easing only uses the "Slide" Effect.', "ml-slider" ), 'value' => $this->slider->get_setting('easing'), 'options' => $this->get_easing_options() ), 'prevText' => array( 'priority' => 150, 'type' => 'text', 'label' => esc_html__("Previous text", "ml-slider"), 'class' => 'option coin flex responsive nivo', 'helptext' => esc_html__( 'Set the text for the "previous" direction item.', "ml-slider" ), 'value' => $this->slider->get_setting( 'prevText' ) == 'false' ? '' : $this->slider->get_setting('prevText') ), 'nextText' => array( 'priority' => 160, 'type' => 'text', 'label' => esc_html__("Next text", "ml-slider"), 'class' => 'option coin flex responsive nivo', 'helptext' => esc_html__( 'Set the text for the "next" direction item.', "ml-slider" ), 'value' => $this->slider->get_setting( 'nextText' ) == 'false' ? '' : $this->slider->get_setting('nextText') ), 'sDelay' => array( 'priority' => 170, 'type' => 'number', 'size' => 3, 'min' => 0, 'max' => 500, 'step' => 10, 'value' => $this->slider->get_setting('sDelay'), 'label' => esc_html__("Square delay", "ml-slider"), 'class' => 'option coin', 'helptext' => esc_html__( "Delay between squares in ms.", "ml-slider" ), 'after' => esc_html_x( "ms", "Short for milliseconds", "ml-slider" ) ), 'opacity' => array( 'priority' => 180, 'type' => 'text', 'value' => $this->slider->get_setting('opacity'), 'label' => esc_html__("Opacity", "ml-slider"), 'class' => 'option coin', 'helptext' => esc_html__( "Opacity of title and navigation, between 0 and 1.", "ml-slider" ), 'after' => '' ), 'titleSpeed' => array( 'priority' => 190, 'type' => 'number', 'size' => 3, 'min' => 0, 'max' => 10000, 'step' => 100, 'value' => $this->slider->get_setting('titleSpeed'), 'label' => esc_html__("Caption speed", "ml-slider"), 'class' => 'option coin', 'helptext' => esc_html__( "Set the fade in speed of the caption.", "ml-slider" ), 'after' => esc_html_x( "ms", "Short for milliseconds", "ml-slider" ) ), 'accessibilityOptions' => array( 'priority' => 191, 'type' => 'highlight', 'value' => esc_html__( 'Accessibility Options', 'ml-slider' ), 'topspacing' => true ), 'keyboard' => array( 'priority' => 192, 'type' => 'checkbox', 'label' => esc_html__("Keyboard Controls", "ml-slider"), 'class' => 'option coin flex nivo responsive', 'checked' => 'true' == $this->slider->get_setting( 'keyboard' ) ? 'checked' : '', 'helptext' => esc_html__( "Use arrow keys to get to the next slide.", "ml-slider" ) ), 'tabIndex' => array( 'priority' => 193, 'type' => 'checkbox', 'label' => esc_html__("Tabindex for navigation", "ml-slider"), 'class' => 'option flex', 'checked' => $this->slider->get_setting( 'tabIndex' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "This helps make the slideshow navigation more accessible.", "ml-slider" ) ), 'ariaLive' => array( 'priority' => 195, 'type' => 'checkbox', 'label' => esc_html__("ARIA Live", "ml-slider"), 'class' => 'option flex', 'checked' => $this->slider->get_setting( 'ariaLive' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "If Autoplay is enabled, this causes screen readers to announce that the slides are changing.", "ml-slider" ) ), 'ariaCurrent' => array( 'priority' => 196, 'type' => 'checkbox', 'label' => esc_html__("ARIA Current", "ml-slider"), 'class' => 'option flex', 'checked' => $this->slider->get_setting( 'ariaCurrent' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "This is used on the navigation button for the active slide. It helps screen readers understand which slide is active.", "ml-slider" ) ), 'developerOptions' => array( 'priority' => 198, 'type' => 'highlight', 'value' => esc_html__( 'Developer Options', 'ml-slider' ), 'topspacing' => true ), 'cssClass' => array( 'priority' => 200, 'type' => 'text', 'label' => esc_html__("CSS classes", "ml-slider"), 'class' => 'option coin flex responsive nivo', 'helptext' => esc_html__( "Enter custom CSS classes to apply to the slider wrapper. Separate multiple classes with a space.", "ml-slider" ), 'value' => $this->slider->get_setting( 'cssClass' ) == 'false' ? '' : $this->slider->get_setting('cssClass') ), 'printCss' => array( 'priority' => 210, 'type' => 'checkbox', 'label' => esc_html__("Print CSS", "ml-slider"), 'class' => 'option coin flex responsive nivo useWithCaution', 'checked' => $this->slider->get_setting( 'printCss' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "Uncheck this if you would like to include your own CSS.", "ml-slider" ) ), 'printJs' => array( 'priority' => 220, 'type' => 'checkbox', 'label' => esc_html__("Print JS", "ml-slider"), 'class' => 'option coin flex responsive nivo useWithCaution', 'checked' => $this->slider->get_setting( 'printJs' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "Uncheck this if you would like to include your own Javascript.", "ml-slider" ) ), 'noConflict' => array( 'priority' => 230, 'type' => 'checkbox', 'label' => esc_html__("No conflict mode", "ml-slider"), 'class' => 'option flex', 'checked' => $this->slider->get_setting( 'noConflict' ) == 'true' ? 'checked' : '', 'helptext' => esc_html__( "Delay adding the flexslider class to the slideshow.", "ml-slider" ) ) ); $aFields = apply_filters( 'metaslider_advanced_settings', $aFields, $this->slider ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo $this->build_settings_rows($aFields); ?> <tr class="empty-row-spacing"> <td colspan="2"></td> </tr> <tr class="highlight"> <td colspan="2"> <?php esc_html_e( 'Shortcode', 'ml-slider' ) ?> </td> </tr> <tr class="empty-row-spacing"> <td colspan="2"></td> </tr> <tr> <td colspan="2"> <?php include METASLIDER_PATH . "admin/views/pages/parts/shortcode.php"; ?> </td> </tr> <tr class="empty-row-spacing"> <td colspan="2"></td> </tr> <?php // Show the restore button if there are trashed posts // Also, render but hide the link in case we want to show // it when the user deletes their first slide $count = count(metaslider_has_trashed_slides($this->slider->id)); if ( ! metaslider_viewing_trashed_slides( $this->slider->id ) ) { ?> <tr class="highlight trashed-slides-cont" style="<?php echo ! $count ? 'display: none;' : '' ?>"> <td colspan="2"> <?php esc_html_e( 'Trashed slides', 'ml-slider' ) ?> </td> </tr> <tr class="empty-row-spacing trashed-slides-cont" style="<?php echo ! $count ? 'display: none;' : '' ?>"> <td colspan="2"></td> </tr> <tr class="trashed-slides-cont" style="<?php echo ! $count ? 'display: none;' : '' ?>"> <td colspan="2"> <a class="restore-slide-link text-blue-dark hover:text-orange" href="<?php echo esc_url( admin_url( "admin.php?page=metaslider&id={$this->slider->id}&show_trashed=true" ) ); ?>"> <i><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-trash-2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg></i> <?php esc_attr_e( 'View trashed slides', 'ml-slider' ); ?> <?php echo $count ? '(' . (int) $count . ')' : '' ?> </a> </td> </tr> <tr class="empty-row-spacing trashed-slides-cont" style="<?php echo ! $count ? 'display: none;' : '' ?>"> <td colspan="2"></td> </tr> <?php } ?> </tbody> </table>