PageRenderTime 74ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/public_html/wp-content/plugins/ml-slider/ml-slider.php

https://bitbucket.org/NavilSN/cfsme-compass
PHP | 1994 lines | 1353 code | 341 blank | 300 comment | 170 complexity | 661b57b43f9e171a923b3de030226602 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /*
  3. * MetaSlider. Slideshow plugin for WordPress.
  4. *
  5. * Plugin Name: MetaSlider
  6. * Plugin URI: https://www.metaslider.com
  7. * Description: Easy to use slideshow plugin. Create SEO optimised responsive slideshows with Nivo Slider, Flex Slider, Coin Slider and Responsive Slides.
  8. * Version: 3.6.6
  9. * Author: Team Updraft
  10. * Author URI: https://www.metaslider.com
  11. * License: GPL-2.0+
  12. * Copyright: 2017 Simba Hosting Ltd
  13. *
  14. * Text Domain: ml-slider
  15. * Domain Path: /languages
  16. */
  17. if ( ! defined( 'ABSPATH' ) ) {
  18. exit; // disable direct access
  19. }
  20. if ( ! class_exists( 'MetaSliderPlugin' ) ) :
  21. /**
  22. * Register the plugin.
  23. *
  24. * Display the administration panel, insert JavaScript etc.
  25. */
  26. class MetaSliderPlugin {
  27. /**
  28. * @var string
  29. */
  30. public $version = '3.6.6';
  31. /**
  32. * @var string The lowest tier price for upgrades
  33. */
  34. public $pro_price = '39';
  35. /**
  36. * @var MetaSlider
  37. */
  38. public $slider = null;
  39. /**
  40. * Init
  41. */
  42. public static function init() {
  43. $metaslider = new self();
  44. }
  45. /**
  46. * Constructor
  47. */
  48. public function __construct() {
  49. $this->define_constants();
  50. $this->includes();
  51. $this->setup_actions();
  52. $this->setup_filters();
  53. $this->setup_shortcode();
  54. $this->register_slide_types();
  55. $this->admin = new MetaSlider_Admin_Pages($this);
  56. }
  57. /**
  58. * Define MetaSlider constants
  59. */
  60. private function define_constants() {
  61. define('METASLIDER_VERSION', $this->version);
  62. define('METASLIDER_BASE_URL', trailingslashit(plugins_url('ml-slider')));
  63. define('METASLIDER_ASSETS_URL', trailingslashit(METASLIDER_BASE_URL . 'assets'));
  64. define('METASLIDER_ADMIN_URL', trailingslashit(METASLIDER_BASE_URL . 'admin'));
  65. define('METASLIDER_PATH', plugin_dir_path(__FILE__));
  66. define('METASLIDER_PRO_PRICE', $this->pro_price);
  67. }
  68. /**
  69. * All MetaSlider classes
  70. */
  71. private function plugin_classes() {
  72. return array(
  73. 'metaslider' => METASLIDER_PATH . 'inc/slider/metaslider.class.php',
  74. 'metacoinslider' => METASLIDER_PATH . 'inc/slider/metaslider.coin.class.php',
  75. 'metaflexslider' => METASLIDER_PATH . 'inc/slider/metaslider.flex.class.php',
  76. 'metanivoslider' => METASLIDER_PATH . 'inc/slider/metaslider.nivo.class.php',
  77. 'metaresponsiveslider' => METASLIDER_PATH . 'inc/slider/metaslider.responsive.class.php',
  78. 'metaslide' => METASLIDER_PATH . 'inc/slide/metaslide.class.php',
  79. 'metaimageslide' => METASLIDER_PATH . 'inc/slide/metaslide.image.class.php',
  80. 'metasliderimagehelper' => METASLIDER_PATH . 'inc/metaslider.imagehelper.class.php',
  81. 'metaslidersystemcheck' => METASLIDER_PATH . 'inc/metaslider.systemcheck.class.php',
  82. 'metaslider_widget' => METASLIDER_PATH . 'inc/metaslider.widget.class.php',
  83. 'simple_html_dom' => METASLIDER_PATH . 'inc/simple_html_dom.php',
  84. 'metaslider_notices' => METASLIDER_PATH . 'admin/Notices.php',
  85. 'metaslider_admin_pages' => METASLIDER_PATH . 'admin/Pages.php',
  86. 'metaslider_tour' => METASLIDER_PATH . 'admin/Tour.php'
  87. );
  88. }
  89. /**
  90. * Load required classes
  91. */
  92. private function includes() {
  93. require_once(METASLIDER_PATH . 'admin/lib/helpers.php');
  94. $autoload_is_disabled = defined( 'METASLIDER_AUTOLOAD_CLASSES' ) && METASLIDER_AUTOLOAD_CLASSES === false;
  95. if ( function_exists( "spl_autoload_register" ) && ! ( $autoload_is_disabled ) ) {
  96. // >= PHP 5.2 - Use auto loading
  97. if ( function_exists( "__autoload" ) ) {
  98. spl_autoload_register( "__autoload" );
  99. }
  100. spl_autoload_register( array( $this, 'autoload' ) );
  101. } else {
  102. // < PHP5.2 - Require all classes
  103. foreach ( $this->plugin_classes() as $id => $path ) {
  104. if ( is_readable( $path ) && ! class_exists( $id ) ) {
  105. require_once( $path );
  106. }
  107. }
  108. }
  109. }
  110. /**
  111. * Autoload MetaSlider classes to reduce memory consumption
  112. */
  113. public function autoload( $class ) {
  114. $classes = $this->plugin_classes();
  115. $class_name = strtolower( $class );
  116. if ( isset( $classes[$class_name] ) && is_readable( $classes[$class_name] ) ) {
  117. require_once( $classes[$class_name] );
  118. }
  119. }
  120. /**
  121. * Register the [metaslider] shortcode.
  122. */
  123. private function setup_shortcode() {
  124. add_shortcode( 'metaslider', array( $this, 'register_shortcode' ) );
  125. add_shortcode( 'ml-slider', array( $this, 'register_shortcode' ) ); // backwards compatibility
  126. }
  127. /**
  128. * Hook MetaSlider into WordPress
  129. */
  130. private function setup_actions() {
  131. add_action('admin_menu', array($this, 'register_admin_pages'), 9553);
  132. add_action('init', array($this, 'register_post_types'));
  133. add_action('init', array($this, 'register_taxonomy'));
  134. add_action('init', array($this, 'load_plugin_textdomain'));
  135. add_action('admin_footer', array($this, 'admin_footer'), 11);
  136. add_action('widgets_init', array($this, 'register_metaslider_widget'));
  137. add_action('admin_post_metaslider_preview', array($this, 'do_preview'));
  138. add_action('admin_post_metaslider_switch_view', array($this, 'switch_view'));
  139. add_action('admin_post_metaslider_delete_slide', array($this, 'delete_slide'));
  140. add_action('admin_post_metaslider_delete_slider', array($this, 'delete_slider'));
  141. add_action('admin_post_metaslider_create_slider', array($this, 'create_slider'));
  142. add_action('admin_post_metaslider_update_slider', array($this, 'update_slider'));
  143. add_action('media_upload_vimeo', array($this, 'upgrade_to_pro_tab'));
  144. add_action('media_upload_youtube', array($this, 'upgrade_to_pro_tab'));
  145. add_action('media_upload_post_feed', array($this, 'upgrade_to_pro_tab'));
  146. add_action('media_upload_layer', array($this, 'upgrade_to_pro_tab'));
  147. // TODO: Refactor to Slide class object
  148. add_action('wp_ajax_delete_slide', array($this, 'ajax_delete_slide'));
  149. add_action('wp_ajax_undelete_slide', array($this, 'ajax_undelete_slide'));
  150. // TODO: Make this work
  151. // register_activation_hook(plugin_basename(__FILE__), array($this, 'after_activation'));
  152. }
  153. /**
  154. * Hook MetaSlider into WordPress
  155. */
  156. private function setup_filters() {
  157. add_filter('media_upload_tabs', array($this, 'custom_media_upload_tab_name'), 998);
  158. add_filter('media_view_strings', array($this, 'custom_media_uploader_tabs'), 5);
  159. add_filter('media_buttons_context', array($this, 'insert_metaslider_button'));
  160. add_filter("plugin_row_meta", array($this, 'get_extra_meta_links'), 10, 4);
  161. add_action('admin_head', array($this, 'add_star_styles'));
  162. add_action('admin_head', array($this, 'add_tour_nonce_to_activation_page'));
  163. // html5 compatibility for stylesheets enqueued within <body>
  164. add_filter('style_loader_tag', array($this, 'add_property_attribute_to_stylesheet_links'), 11, 2);
  165. }
  166. /**
  167. * Register MetaSlider widget
  168. */
  169. public function register_metaslider_widget() {
  170. register_widget('MetaSlider_Widget');
  171. }
  172. /**
  173. * Register ML Slider post type
  174. */
  175. public function register_post_types() {
  176. $show_ui = false;
  177. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  178. if ( is_admin() && current_user_can( $capability ) && ( isset($_GET['show_ui']) || defined("METASLIDER_DEBUG") && METASLIDER_DEBUG ) ) {
  179. $show_ui = true;
  180. }
  181. register_post_type( 'ml-slider', array(
  182. 'query_var' => false,
  183. 'rewrite' => false,
  184. 'public' => false,
  185. 'exclude_from_search' => true,
  186. 'publicly_queryable' => false,
  187. 'show_in_nav_menus' => false,
  188. 'show_ui' => $show_ui,
  189. 'labels' => array(
  190. 'name' => 'MetaSlider'
  191. )
  192. )
  193. );
  194. register_post_type( 'ml-slide', array(
  195. 'query_var' => false,
  196. 'rewrite' => false,
  197. 'public' => false,
  198. 'exclude_from_search' => true,
  199. 'publicly_queryable' => false,
  200. 'show_in_nav_menus' => false,
  201. 'show_ui' => $show_ui,
  202. 'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt'),
  203. 'labels' => array(
  204. 'name' => 'Meta Slides'
  205. )
  206. )
  207. );
  208. }
  209. /**
  210. * Register taxonomy to store slider => slides relationship
  211. */
  212. public function register_taxonomy() {
  213. $show_ui = false;
  214. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  215. if (is_admin() && current_user_can( $capability ) && ( isset($_GET['show_ui']) || defined("METASLIDER_DEBUG") && METASLIDER_DEBUG ) ) {
  216. $show_ui = true;
  217. }
  218. register_taxonomy( 'ml-slider', array('attachment', 'ml-slide'), array(
  219. 'hierarchical' => true,
  220. 'public' => false,
  221. 'query_var' => false,
  222. 'rewrite' => false,
  223. 'show_ui' => $show_ui,
  224. 'label' => "Slider"
  225. )
  226. );
  227. }
  228. /**
  229. * Register our slide types
  230. */
  231. private function register_slide_types() {
  232. $image = new MetaImageSlide();
  233. }
  234. /**
  235. * Add the menu pages
  236. */
  237. public function register_admin_pages() {
  238. if (metaslider_is_pro_active()) {
  239. $this->admin->add_page('MetaSlider Pro', 'metaslider');
  240. } else {
  241. $this->admin->add_page('MetaSlider');
  242. }
  243. if (metaslider_sees_upgrade_page()) {
  244. $this->admin->add_page(__('Add-ons', 'ml-slider'), 'upgrade', 'metaslider');
  245. }
  246. }
  247. /**
  248. * Shortcode used to display slideshow
  249. *
  250. * @return string HTML output of the shortcode
  251. */
  252. public function register_shortcode( $atts ) {
  253. extract( shortcode_atts( array(
  254. 'id' => false,
  255. 'restrict_to' => false
  256. ), $atts, 'metaslider' ) );
  257. if ( ! $id ) {
  258. return false;
  259. }
  260. // handle [metaslider id=123 restrict_to=home]
  261. if ($restrict_to && $restrict_to == 'home' && ! is_front_page()) {
  262. return;
  263. }
  264. if ($restrict_to && $restrict_to != 'home' && ! is_page( $restrict_to ) ) {
  265. return;
  266. }
  267. // we have an ID to work with
  268. $slider = get_post( $id );
  269. // check the slider is published and the ID is correct
  270. if ( ! $slider || $slider->post_status != 'publish' || $slider->post_type != 'ml-slider' ) {
  271. return "<!-- MetaSlider {$atts['id']} not found -->";
  272. }
  273. // lets go
  274. $this->set_slider( $id, $atts );
  275. $this->slider->enqueue_scripts();
  276. return $this->slider->render_public_slides();
  277. }
  278. /**
  279. * Set first activation option to database
  280. */
  281. public function after_activation() {
  282. // Set date showing the first activation and redirect
  283. if (!get_option('ms_was_installed_on')) {
  284. update_option('ms_was_installed_on', time());
  285. }
  286. }
  287. /**
  288. * Initialise translations
  289. */
  290. public function load_plugin_textdomain() {
  291. load_plugin_textdomain( 'ml-slider', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
  292. }
  293. /**
  294. * Outputs a blank page containing a slideshow preview (for use in the 'Preview' iFrame)
  295. */
  296. public function do_preview() {
  297. remove_action('wp_footer', 'wp_admin_bar_render', 1000);
  298. if ( isset( $_GET['slider_id'] ) && absint( $_GET['slider_id'] ) > 0 ) {
  299. $id = absint( $_GET['slider_id'] );
  300. ?>
  301. <!DOCTYPE html>
  302. <html>
  303. <head>
  304. <style type='text/css'>
  305. body, html {
  306. overflow: hidden;
  307. margin: 0;
  308. padding: 0;
  309. }
  310. </style>
  311. <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
  312. <meta http-equiv="Pragma" content="no-cache" />
  313. <meta http-equiv="Expires" content="0" />
  314. </head>
  315. <body>
  316. <?php echo do_shortcode("[metaslider id={$id}]"); ?>
  317. <?php wp_footer(); ?>
  318. </body>
  319. </html>
  320. <?php
  321. }
  322. die();
  323. }
  324. /**
  325. * Check our WordPress installation is compatible with MetaSlider
  326. */
  327. public function do_system_check() {
  328. $systemCheck = new MetaSliderSystemCheck();
  329. $systemCheck->check();
  330. }
  331. /**
  332. * Update the tab options in the media manager
  333. */
  334. public function custom_media_uploader_tabs( $strings ) {
  335. //update strings
  336. if ( ( isset( $_GET['page'] ) && $_GET['page'] == 'metaslider' ) ) {
  337. $strings['insertMediaTitle'] = __( "Image", "ml-slider" );
  338. $strings['insertIntoPost'] = __( "Add to slideshow", "ml-slider" );
  339. // remove options
  340. $strings_to_remove = array(
  341. 'createVideoPlaylistTitle',
  342. 'createGalleryTitle',
  343. 'insertFromUrlTitle',
  344. 'createPlaylistTitle'
  345. );
  346. foreach ($strings_to_remove as $string) {
  347. if (isset($strings[$string])) {
  348. unset($strings[$string]);
  349. }
  350. }
  351. }
  352. return $strings;
  353. }
  354. /**
  355. * Add extra tabs to the default wordpress Media Manager iframe
  356. *
  357. * @var array existing media manager tabs
  358. */
  359. public function custom_media_upload_tab_name( $tabs ) {
  360. $metaslider_tabs = array( 'post_feed', 'layer', 'youtube', 'vimeo' );
  361. // restrict our tab changes to the MetaSlider plugin page
  362. if ( ( isset( $_GET['page'] ) && $_GET['page'] == 'metaslider' ) || ( isset( $_GET['tab'] ) && in_array( $_GET['tab'], $metaslider_tabs ) ) ) {
  363. $newtabs = array();
  364. if ( function_exists( 'is_plugin_active' ) && ! is_plugin_active( 'ml-slider-pro/ml-slider-pro.php' ) ) {
  365. $newtabs = array(
  366. 'post_feed' => __( "Post Feed", "metaslider" ),
  367. 'vimeo' => __( "Vimeo", "metaslider" ),
  368. 'youtube' => __( "YouTube", "metaslider" ),
  369. 'layer' => __( "Layer Slide", "metaslider" )
  370. );
  371. }
  372. if ( isset( $tabs['nextgen'] ) )
  373. unset( $tabs['nextgen'] );
  374. if ( is_array( $tabs ) ) {
  375. return array_merge( $tabs, $newtabs );
  376. } else {
  377. return $newtabs;
  378. }
  379. }
  380. return $tabs;
  381. }
  382. /**
  383. * Set the current slider
  384. */
  385. public function set_slider( $id, $shortcode_settings = array() ) {
  386. $type = 'flex';
  387. if ( isset( $shortcode_settings['type'] ) ) {
  388. $type = $shortcode_settings['type'];
  389. } else if ( $settings = get_post_meta( $id, 'ml-slider_settings', true ) ) {
  390. if ( is_array( $settings ) && isset( $settings['type'] ) ) {
  391. $type = $settings['type'];
  392. }
  393. }
  394. if ( ! in_array( $type, array( 'flex', 'coin', 'nivo', 'responsive' ) ) ) {
  395. $type = 'flex';
  396. }
  397. $this->slider = $this->load_slider( $type, $id, $shortcode_settings );
  398. }
  399. /**
  400. * Create a new slider based on the sliders type setting
  401. */
  402. private function load_slider( $type, $id, $shortcode_settings ) {
  403. switch ( $type ) {
  404. case( 'coin' ):
  405. return new MetaCoinSlider( $id, $shortcode_settings );
  406. case( 'flex' ):
  407. return new MetaFlexSlider( $id, $shortcode_settings );
  408. case( 'nivo' ):
  409. return new MetaNivoSlider( $id, $shortcode_settings );
  410. case( 'responsive' ):
  411. return new MetaResponsiveSlider( $id, $shortcode_settings );
  412. default:
  413. return new MetaFlexSlider( $id, $shortcode_settings );
  414. }
  415. }
  416. /**
  417. *
  418. */
  419. public function update_slider() {
  420. check_admin_referer( "metaslider_update_slider" );
  421. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  422. if ( ! current_user_can( $capability ) ) {
  423. return;
  424. }
  425. $slider_id = absint( $_POST['slider_id'] );
  426. if ( ! $slider_id ) {
  427. return;
  428. }
  429. // update settings
  430. if ( isset( $_POST['settings'] ) ) {
  431. $new_settings = $_POST['settings'];
  432. $old_settings = get_post_meta( $slider_id, 'ml-slider_settings', true );
  433. // convert submitted checkbox values from 'on' or 'off' to boolean values
  434. $checkboxes = apply_filters( "metaslider_checkbox_settings", array( 'noConflict', 'fullWidth', 'hoverPause', 'links', 'reverse', 'random', 'printCss', 'printJs', 'smoothHeight', 'center', 'carouselMode', 'autoPlay' ) );
  435. foreach ( $checkboxes as $checkbox ) {
  436. if ( isset( $new_settings[$checkbox] ) && $new_settings[$checkbox] == 'on' ) {
  437. $new_settings[$checkbox] = "true";
  438. } else {
  439. $new_settings[$checkbox] = "false";
  440. }
  441. }
  442. $settings = array_merge( (array)$old_settings, $new_settings );
  443. // update the slider settings
  444. update_post_meta( $slider_id, 'ml-slider_settings', $settings );
  445. }
  446. // update slideshow title
  447. if ( isset( $_POST['title'] ) ) {
  448. $slide = array(
  449. 'ID' => $slider_id,
  450. 'post_title' => esc_html( $_POST['title'] )
  451. );
  452. wp_update_post( $slide );
  453. }
  454. // update individual slides
  455. if ( isset( $_POST['attachment'] ) ) {
  456. foreach ( $_POST['attachment'] as $slide_id => $fields ) {
  457. do_action( "metaslider_save_{$fields['type']}_slide", $slide_id, $slider_id, $fields );
  458. }
  459. }
  460. }
  461. /**
  462. * Delete a slide via ajax.
  463. * @return string Returns the status of the request
  464. */
  465. public function ajax_undelete_slide() {
  466. if (!wp_verify_nonce($_REQUEST['_wpnonce'], 'metaslider_undelete_slide')) {
  467. return wp_send_json_error(array(
  468. 'message' => __('The security check failed. Please refresh the page and try again.', 'ml-slider')
  469. ), 401);
  470. }
  471. $result = $this->undelete_slide(absint($_POST['slide_id']), absint($_POST['slider_id']));
  472. if (is_wp_error($result)) {
  473. return wp_send_json_error(array(
  474. 'message' => $result->get_error_message()
  475. ), 409);
  476. }
  477. return wp_send_json_success(array(
  478. 'message' => __('The slide was successfully restored', 'ml-slider'),
  479. ), 200);
  480. }
  481. /**
  482. * Undeletes a slide.
  483. * @param int $slide_id The ID of the slide
  484. * @param int $slider_id The ID of the slider (for legacy purposes)
  485. * @return mixed
  486. */
  487. public function undelete_slide($slide_id, $slider_id) {
  488. if ('ml-slide' === get_post_type($slide_id)) {
  489. return wp_update_post(array(
  490. 'ID' => $slide_id,
  491. 'post_status' => 'publish'
  492. ), new WP_Error('update_failed', __('The attempt to restore the slide failed.', 'ml-slider'), array('status' => 409)));
  493. }
  494. // Legacy: This removes the relationship between the slider and slide
  495. // This restores the relationship between a slide and slider.
  496. // If using a newer version, this relationship is never lost on delete.
  497. // Get the slider's term and apply it to the slide.
  498. $term = get_term_by('name', $slider_id, 'ml-slider');
  499. return wp_set_object_terms($slide_id, $term->term_id, 'ml-slider');
  500. }
  501. /**
  502. * Delete a slide via ajax.
  503. */
  504. public function ajax_delete_slide() {
  505. if (!wp_verify_nonce($_REQUEST['_wpnonce'], 'metaslider_delete_slide')) {
  506. return wp_send_json_error(array(
  507. 'message' => __('The security check failed. Please refresh the page and try again.', 'ml-slider')
  508. ), 401);
  509. }
  510. $result = $this->delete_slide(absint($_POST['slide_id']), absint($_POST['slider_id']));
  511. if (is_wp_error($result)) {
  512. return wp_send_json_error(array(
  513. 'message' => $result->get_error_message()
  514. ), 409);
  515. }
  516. return wp_send_json_success(array(
  517. 'message' => __('The slide was successfully trashed', 'ml-slider'),
  518. ), 200);
  519. }
  520. /**
  521. * Delete a slide by either trashing it or for
  522. * legacy reasons removing the taxonomy relationship.
  523. * @param int $slide_id
  524. * @param int $slider_id
  525. * @return mixed Will return the terms or WP_Error
  526. */
  527. public function delete_slide($slide_id, $slider_id) {
  528. if ('ml-slide' === get_post_type($slide_id)) {
  529. return wp_update_post(array(
  530. 'ID' => $slide_id,
  531. 'post_status' => 'trash'
  532. ), new WP_Error('update_failed', 'The attempt to delete the slide failed.', array('status' => 409)));
  533. }
  534. // Legacy: This removes the relationship between the slider and slide
  535. /* A slider with ID 216 might have a term_id of 7
  536. * A slide with ID 217 could have a term_taxonomy_id of 7
  537. * Multiple slides would have this term_taxonomy_id of 7 */
  538. // This returns the term_taxonomy_id (7 from example)
  539. $current_terms = wp_get_object_terms($slide_id, 'ml-slider', array('fields' => 'ids'));
  540. // This returns the term object, named after the slider ID
  541. // The $term->term_id would be 7 in the example above
  542. // It also includes the count of slides attached to the slider
  543. $term = get_term_by('name', $slider_id, 'ml-slider');
  544. // I'm not sure why this is here. It seems this is only useful if
  545. // a slide was attached to multiple sliders. A slide should only
  546. // have one $current_terms (7 above)
  547. $new_terms = array();
  548. foreach ($current_terms as $current_term) {
  549. if ($current_term != $term->term_id) {
  550. $new_terms[] = absint($current_term);
  551. }
  552. }
  553. // This only works becasue $new_terms is an empty array,
  554. // which deletes the relationship. I'm leaving the loop above
  555. // in case it's here for some legacy reason I'm unaware of.
  556. return wp_set_object_terms($slide_id, $new_terms, 'ml-slider');
  557. }
  558. /**
  559. * Delete a slider (send it to trash)
  560. */
  561. public function delete_slider() {
  562. // check nonce
  563. check_admin_referer( "metaslider_delete_slider" );
  564. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  565. if ( ! current_user_can( $capability ) ) {
  566. return;
  567. }
  568. $slider_id = absint( $_GET['slider_id'] );
  569. if ( get_post_type( $slider_id ) != 'ml-slider' ) {
  570. wp_redirect( admin_url( "admin.php?page=metaslider" ) );
  571. wp_die();
  572. }
  573. // send the post to trash
  574. $id = wp_update_post( array(
  575. 'ID' => $slider_id,
  576. 'post_status' => 'trash'
  577. )
  578. );
  579. $this->delete_all_slides_from_slider($slider_id);
  580. $slider_id = $this->find_slider( 'modified', 'DESC' );
  581. wp_redirect( admin_url( "admin.php?page=metaslider&id={$slider_id}" ) );
  582. }
  583. /**
  584. * Trashes all new format slides for a given slideshow ID
  585. *
  586. * @param int $slider_id
  587. * @return int - The ID of the slideshow from which the slides were removed
  588. */
  589. private function delete_all_slides_from_slider($slider_id) {
  590. // find slides and trash them
  591. $args = array(
  592. 'force_no_custom_order' => true,
  593. 'orderby' => 'menu_order',
  594. 'order' => 'ASC',
  595. 'post_type' => array('ml-slide'),
  596. 'post_status' => array('publish'),
  597. 'lang' => '', // polylang, ingore language filter
  598. 'suppress_filters' => 1, // wpml, ignore language filter
  599. 'posts_per_page' => -1,
  600. 'tax_query' => array(
  601. array(
  602. 'taxonomy' => 'ml-slider',
  603. 'field' => 'slug',
  604. 'terms' => $slider_id
  605. )
  606. )
  607. );
  608. $query = new WP_Query( $args );
  609. while ( $query->have_posts() ) {
  610. $query->next_post();
  611. $id = $query->post->ID;
  612. $id = wp_update_post( array(
  613. 'ID' => $id,
  614. 'post_status' => 'trash'
  615. )
  616. );
  617. }
  618. return $slider_id;
  619. }
  620. /**
  621. *
  622. */
  623. public function switch_view() {
  624. global $user_ID;
  625. $view = $_GET['view'];
  626. $allowed_views = array('tabs', 'dropdown');
  627. if ( ! in_array( $view, $allowed_views ) ) {
  628. return;
  629. }
  630. delete_user_meta( $user_ID, "metaslider_view" );
  631. if ( $view == 'dropdown' ) {
  632. add_user_meta( $user_ID, "metaslider_view", "dropdown");
  633. }
  634. wp_redirect( admin_url( "admin.php?page=metaslider" ) );
  635. }
  636. /**
  637. * Create a new slider
  638. */
  639. public function create_slider() {
  640. // check nonce
  641. check_admin_referer( "metaslider_create_slider" );
  642. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  643. if ( ! current_user_can( $capability ) ) {
  644. return;
  645. }
  646. $defaults = array();
  647. // if possible, take a copy of the last edited slider settings in place of default settings
  648. if ( $last_modified = $this->find_slider( 'modified', 'DESC' ) ) {
  649. $defaults = get_post_meta( $last_modified, 'ml-slider_settings', true );
  650. }
  651. // insert the post
  652. $id = wp_insert_post( array(
  653. 'post_title' => __("New Slideshow", "ml-slider"),
  654. 'post_status' => 'publish',
  655. 'post_type' => 'ml-slider'
  656. )
  657. );
  658. // use the default settings if we can't find anything more suitable.
  659. if ( empty( $defaults ) ) {
  660. $slider = new MetaSlider( $id, array() );
  661. $defaults = $slider->get_default_parameters();
  662. }
  663. // insert the post meta
  664. add_post_meta( $id, 'ml-slider_settings', $defaults, true );
  665. // create the taxonomy term, the term is the ID of the slider itself
  666. wp_insert_term( $id, 'ml-slider' );
  667. wp_redirect( admin_url( "admin.php?page=metaslider&id={$id}" ) );
  668. }
  669. /**
  670. * Find a single slider ID. For example, last edited, or first published.
  671. *
  672. * @param string $orderby field to order.
  673. * @param string $order direction (ASC or DESC).
  674. * @return int slider ID.
  675. */
  676. private function find_slider( $orderby, $order ) {
  677. $args = array(
  678. 'force_no_custom_order' => true,
  679. 'post_type' => 'ml-slider',
  680. 'num_posts' => 1,
  681. 'post_status' => 'publish',
  682. 'suppress_filters' => 1, // wpml, ignore language filter
  683. 'orderby' => $orderby,
  684. 'order' => $order
  685. );
  686. $the_query = new WP_Query( $args );
  687. while ( $the_query->have_posts() ) {
  688. $the_query->the_post();
  689. return $the_query->post->ID;
  690. }
  691. wp_reset_query();
  692. return false;
  693. }
  694. /**
  695. * Get sliders. Returns a nicely formatted array of currently
  696. * published sliders.
  697. *
  698. * @param string $sort_key
  699. * @return array all published sliders
  700. */
  701. public function all_meta_sliders( $sort_key = 'date' ) {
  702. $sliders = array();
  703. // list the tabs
  704. $args = array(
  705. 'post_type' => 'ml-slider',
  706. 'post_status' => 'publish',
  707. 'orderby' => $sort_key,
  708. 'suppress_filters' => 1, // wpml, ignore language filter
  709. 'order' => 'ASC',
  710. 'posts_per_page' => -1
  711. );
  712. $args = apply_filters( 'metaslider_all_meta_sliders_args', $args );
  713. // WP_Query causes issues with other plugins using admin_footer to insert scripts
  714. // use get_posts instead
  715. $all_sliders = get_posts( $args );
  716. foreach( $all_sliders as $slideshow ) {
  717. $active = $this->slider && ( $this->slider->id == $slideshow->ID ) ? true : false;
  718. $sliders[] = array(
  719. 'active' => $active,
  720. 'title' => $slideshow->post_title,
  721. 'id' => $slideshow->ID
  722. );
  723. }
  724. return $sliders;
  725. }
  726. /**
  727. * Compare array values
  728. *
  729. * @param array $elem1
  730. * @param array $elem2
  731. * @return bool
  732. */
  733. private function compare_elems( $elem1, $elem2 ) {
  734. return $elem1['priority'] > $elem2['priority'];
  735. }
  736. /**
  737. *
  738. * @param array $aFields - array of field to render
  739. * @return string
  740. */
  741. public function build_settings_rows( $aFields ) {
  742. // order the fields by priority
  743. uasort( $aFields, array( $this, "compare_elems" ) );
  744. $return = "";
  745. // loop through the array and build the settings HTML
  746. foreach ( $aFields as $id => $row ) {
  747. // checkbox input type
  748. if ( $row['type'] == 'checkbox' ) {
  749. $return .= "<tr><td class='tipsy-tooltip' title=\"{$row['helptext']}\">{$row['label']}</td><td><input class='option {$row['class']} {$id}' type='checkbox' name='settings[{$id}]' {$row['checked']} />";
  750. if ( isset( $row['after'] ) ) {
  751. $return .= "<span class='after'>{$row['after']}</span>";
  752. }
  753. $return .= "</td></tr>";
  754. }
  755. // navigation row
  756. if ( $row['type'] == 'navigation' ) {
  757. $navigation_row = "<tr class='{$row['type']}'><td class='tipsy-tooltip' title=\"{$row['helptext']}\">{$row['label']}</td><td><ul>";
  758. foreach ( $row['options'] as $k => $v ) {
  759. $tease = isset($v['addon_required']) ? 'disabled' : '';
  760. if ( $row['value'] === true && $k === 'true' ) {
  761. $checked = checked( true, true, false );
  762. } else if ( $row['value'] === false && $k === 'false' ) {
  763. $checked = checked( true, true, false );
  764. } else {
  765. $checked = checked( $k, $row['value'], false );
  766. }
  767. $disabled = $k == 'thumbnails' ? 'disabled' : '';
  768. $navigation_row .= "<li><label class='{$tease}'><input {$tease} type='radio' name='settings[{$id}]' value='{$k}' {$checked} {$disabled}/>{$v['label']}</label>";
  769. if (isset($v['addon_required']) && $v['addon_required']) {
  770. $navigation_row .= sprintf(" <a target='_blank' class='get-addon' href='%s' title='%s'>%s</a>", metaslider_get_upgrade_link(), __('Get the add-on pack today!', 'ml-slider'), __('Learn More', 'ml-slider'));
  771. }
  772. $navigation_row .= "</li>";
  773. }
  774. $navigation_row .= "</ul></td></tr>";
  775. $return .= apply_filters( 'metaslider_navigation_options', $navigation_row, $this->slider );
  776. }
  777. // navigation row
  778. if ( $row['type'] == 'radio' ) {
  779. $navigation_row = "<tr class='{$row['type']}'><td class='tipsy-tooltip' title=\"{$row['helptext']}\">{$row['label']}</td><td><ul>";
  780. foreach ( $row['options'] as $k => $v ) {
  781. $checked = checked( $k, $row['value'], false );
  782. $class = isset( $v['class'] ) ? $v['class'] : "";
  783. $navigation_row .= "<li><label><input type='radio' name='settings[{$id}]' value='{$k}' {$checked} class='radio {$class}'/>{$v['label']}</label></li>";
  784. }
  785. $navigation_row .= "</ul></td></tr>";
  786. $return .= apply_filters( 'metaslider_navigation_options', $navigation_row, $this->slider );
  787. }
  788. // header/divider row
  789. if ( $row['type'] == 'divider' ) {
  790. $return .= "<tr class='{$row['type']}'><td colspan='2' class='divider'><b>{$row['value']}</b></td></tr>";
  791. }
  792. // slideshow select row
  793. if ( $row['type'] == 'slider-lib' ) {
  794. $return .= "<tr class='{$row['type']}'><td colspan='2' class='slider-lib-row'>";
  795. foreach ( $row['options'] as $k => $v ) {
  796. $checked = checked( $k, $row['value'], false );
  797. $return .= "<input class='select-slider' id='{$k}' rel='{$k}' type='radio' name='settings[type]' value='{$k}' {$checked} />
  798. <label tabindex='0' for='{$k}'>{$v['label']}</label>";
  799. }
  800. $return .= "</td></tr>";
  801. }
  802. // number input type
  803. if ( $row['type'] == 'number' ) {
  804. $return .= "<tr class='{$row['type']}'><td class='tipsy-tooltip' title=\"{$row['helptext']}\">{$row['label']}</td><td><input class='option {$row['class']} {$id}' type='number' min='{$row['min']}' max='{$row['max']}' step='{$row['step']}' name='settings[{$id}]' value='" . absint( $row['value'] ) . "' /><span class='after'>{$row['after']}</span></td></tr>";
  805. }
  806. // select drop down
  807. if ( $row['type'] == 'select' ) {
  808. $return .= "<tr class='{$row['type']}'><td class='tipsy-tooltip' title=\"{$row['helptext']}\">{$row['label']}</td><td><select class='option {$row['class']} {$id}' name='settings[{$id}]'>";
  809. foreach ( $row['options'] as $k => $v ) {
  810. $selected = selected( $k, $row['value'], false );
  811. $return .= "<option class='{$v['class']}' value='{$k}' {$selected}>{$v['label']}</option>";
  812. }
  813. $return .= "</select></td></tr>";
  814. }
  815. // theme drop down
  816. if ( $row['type'] == 'theme' ) {
  817. $return .= "<tr class='{$row['type']}'><td class='tipsy-tooltip' title=\"{$row['helptext']}\">{$row['label']}</td><td><select class='option {$row['class']} {$id}' name='settings[{$id}]'>";
  818. $themes = "";
  819. foreach ( $row['options'] as $k => $v ) {
  820. $selected = selected( $k, $row['value'], false );
  821. $themes .= "<option class='{$v['class']}' value='{$k}' {$selected}>{$v['label']}</option>";
  822. }
  823. $return .= apply_filters( 'metaslider_get_available_themes', $themes, $this->slider->get_setting( 'theme' ) );
  824. $return .= "</select></td></tr>";
  825. }
  826. // text input type
  827. if ( $row['type'] == 'text' ) {
  828. $return .= "<tr class='{$row['type']}'><td class='tipsy-tooltip' title=\"{$row['helptext']}\">{$row['label']}</td><td><input class='option {$row['class']} {$id}' type='text' name='settings[{$id}]' value='" . esc_attr( $row['value'] ) . "' /></td></tr>";
  829. }
  830. // text input type
  831. if ( $row['type'] == 'textarea' ) {
  832. $return .= "<tr class='{$row['type']}'><td class='tipsy-tooltip' title=\"{$row['helptext']}\" colspan='2'>{$row['label']}</td></tr><tr><td colspan='2'><textarea class='option {$row['class']} {$id}' name='settings[{$id}]' />{$row['value']}</textarea></td></tr>";
  833. }
  834. // text input type
  835. if ( $row['type'] == 'title' ) {
  836. $return .= "<tr class='{$row['type']}'><td class='tipsy-tooltip' title=\"{$row['helptext']}\">{$row['label']}</td><td><input class='option {$row['class']} {$id}' type='text' name='{$id}' value='" . esc_attr( $row['value'] ) . "' /></td></tr>";
  837. }
  838. }
  839. return $return;
  840. }
  841. /**
  842. * Return an indexed array of all easing options
  843. *
  844. * @return array
  845. */
  846. private function get_easing_options() {
  847. $options = array(
  848. 'linear', 'swing', 'jswing', 'easeInQuad', 'easeOutQuad', 'easeInOutQuad',
  849. 'easeInCubic', 'easeOutCubic', 'easeInOutCubic', 'easeInQuart',
  850. 'easeOutQuart', 'easeInOutQuart', 'easeInQuint', 'easeOutQuint',
  851. 'easeInOutQuint', 'easeInSine', 'easeOutSine', 'easeInOutSine',
  852. 'easeInExpo', 'easeOutExpo', 'easeInOutExpo', 'easeInCirc', 'easeOutCirc',
  853. 'easeInOutCirc', 'easeInElastic', 'easeOutElastic', 'easeInOutElastic',
  854. 'easeInBack', 'easeOutBack', 'easeInOutBack', 'easeInBounce', 'easeOutBounce',
  855. 'easeInOutBounce'
  856. );
  857. foreach ( $options as $option ) {
  858. $return[$option] = array(
  859. 'label' => ucfirst( preg_replace( '/(\w+)([A-Z])/U', '\\1 \\2', $option ) ),
  860. 'class' => ''
  861. );
  862. }
  863. return $return;
  864. }
  865. /**
  866. * Output the slideshow selector.
  867. *
  868. * Show tabs or a dropdown list depending on the users saved preference.
  869. */
  870. public function print_slideshow_selector() {
  871. global $user_ID;
  872. // First check if we have any slideshows yet
  873. if ($tabs = $this->all_meta_sliders()) {
  874. // Next check if they have the tabs view selected
  875. if ('tabs' == $this->get_view()) {
  876. // Render the tabs
  877. echo "<div class='nav-tab-wrapper'>";
  878. foreach ($tabs as $tab) {
  879. if ( $tab['active'] ) {
  880. echo "<div class='nav-tab nav-tab-active'><input class='no_last_pass' type='text' name='title' value='" . esc_attr($tab['title']) . "'></div>";
  881. } else {
  882. echo "<a href='?page=metaslider&amp;id={$tab['id']}' title= '" . esc_attr($tab['title']) . "' class='nav-tab'>" . esc_html( $tab['title'] ) . "</a>";
  883. }
  884. }
  885. echo $this->get_add_slideshow_button("New", 'nav-tab');
  886. echo "</div>";
  887. // This will render the select dropdown view
  888. // TODO make this resemble the WP Nav menu UI perhaps
  889. } else {
  890. echo "<div class='manage-menus'><label for='select-slideshow' class='selected-menu'>" . __("Select Slideshow", "ml-slider") . ": </label>";
  891. echo "<select name='select-slideshow' onchange='if (this.value) window.location.href=this.value'>";
  892. $tabs = $this->all_meta_sliders('title');
  893. foreach ($tabs as $tab) {
  894. $selected = $tab['active'] ? " selected" : "";
  895. if ($tab['active']) {
  896. $title = $tab['title'];
  897. }
  898. echo "<option value='?page=metaslider&amp;id={$tab['id']}'{$selected}>{$tab['title']}</option>";
  899. }
  900. echo "</select>";
  901. echo "<span class='add-new-menu-action'> " . __( 'or', "ml-slider" ) . " ";
  902. echo "<a href='". wp_nonce_url(admin_url("admin-post.php?action=metaslider_create_slider"), "metaslider_create_slider") ."' id='create_new_tab' class='' title='" . __('Create a New Slideshow', 'ml-slider') . "'>create a new slideshow</a>";
  903. echo "</span></div>";
  904. }
  905. // This section is shown when there are no slideshows
  906. } else {
  907. echo "<div class='nav-tab-wrapper'>";
  908. echo "<div class='fake-tabs nav-tab nav-tab-active'><span class='blurred-out'>" . __('New Slideshow', 'ml-slider') ."</span></div>";
  909. echo $this->get_add_slideshow_button("New", 'nav-tab');
  910. echo "</div>";
  911. }
  912. }
  913. /**
  914. * Return a button to sadd a new slideshow.
  915. */
  916. protected function get_add_slideshow_button($text = '', $classes = '') {
  917. $add_url = wp_nonce_url(admin_url("admin-post.php?action=metaslider_create_slider"), "metaslider_create_slider");
  918. if ('' == $text) {
  919. $text = __('Add a New Slideshow', 'ml-slider');
  920. }
  921. return "<a href='{$add_url}' id='create_new_tab' class='ml-add-new {$classes}' title='" . __('Add a New Slideshow', 'ml-slider') . "'><i><svg xmlns='http://www.w3.org/2000/svg' width='18' height='18' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-plus-circle'><circle cx='12' cy='12' r='10'/><line x1='12' y1='8' x2='12' y2='16'/><line x1='8' y1='12' x2='16' y2='12'/></svg></i> {$text}</a>";
  922. }
  923. /**
  924. * Return the users saved view preference.
  925. */
  926. public function get_view() {
  927. global $user_ID;
  928. if ( get_user_meta( $user_ID, "metaslider_view", true ) ) {
  929. return get_user_meta( $user_ID, "metaslider_view", true );
  930. }
  931. return 'tabs';
  932. }
  933. /**
  934. * Render the admin page (tabs, slides, settings)
  935. */
  936. public function render_admin_page() {
  937. // Default to the most recently modified slider
  938. $slider_id = $this->find_slider('modified', 'DESC');
  939. // If the id parameter exists, verify and use that.
  940. if (isset($_REQUEST['id']) && $id = $_REQUEST['id']) {
  941. if (in_array(get_post_status(absint($id)), array('publish', 'inherit'))) {
  942. $slider_id = $id;
  943. }
  944. }
  945. // "Set the slider"
  946. // TODO figure out what this does and if it can be better stated
  947. // Perhaps maybe "apply_settings()" or something.
  948. if ($slider_id) {
  949. $this->set_slider($slider_id);
  950. }
  951. echo "<div class='wrap metaslider-ui-top' style='margin-top:0;'>";
  952. echo $this->documentation_button();
  953. echo $this->toggle_layout_button();
  954. if (metaslider_sees_call_to_action()) {
  955. echo $this->upgrade_to_pro_top_button();
  956. }
  957. echo "</div>";
  958. $this->do_system_check();
  959. $slider_id = $this->slider ? $this->slider->id : 0;
  960. ?>
  961. <script type='text/javascript'>
  962. var metaslider_slider_id = <?php echo $slider_id; ?>;
  963. </script>
  964. <div class="wrap metaslider metaslider-ui">
  965. <h1 class="wp-heading-inline metaslider-title">
  966. <img width=50 height=50 src="<?php echo METASLIDER_ADMIN_URL ?>images/metaslider_logo_large.png" alt="MetaSlider">
  967. MetaSlider
  968. <?php if (metaslider_is_pro_active()) {
  969. echo ' Pro';
  970. } ?>
  971. </h1>
  972. <?php if (metaslider_sees_notices($this)) {
  973. echo $this->notices->do_notice(false, 'header', true);
  974. } ?>
  975. <form accept-charset="UTF-8" action="<?php echo admin_url( 'admin-post.php'); ?>" method="post">
  976. <input type="hidden" name="action" value="metaslider_update_slider">
  977. <input type="hidden" name="slider_id" value="<?php echo $slider_id; ?>">
  978. <?php wp_nonce_field( 'metaslider_update_slider' ); ?>
  979. <?php $this->print_slideshow_selector(); ?>
  980. <?php if ( ! $this->slider ) return; ?>
  981. <div id='poststuff' class="metaslider-inner wp-clearfix">
  982. <div id='post-body' class='metabox-holder columns-2'>
  983. <div id='post-body-content'>
  984. <div class="left">
  985. <?php do_action( "metaslider_admin_table_before", $this->slider->id ); ?>
  986. <table class="widefat sortable metaslider-slides-container">
  987. <thead>
  988. <tr>
  989. <?php if (metaslider_viewing_trashed_slides($this->slider->id)) {
  990. // If they are on the trash page, show them?>
  991. <th class="trashed-header">
  992. <h3><i><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" 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 _e('Trashed Slides', 'ml-slider'); ?></h3>
  993. <small> <?php printf(__('<a href="%s">view active</a>', 'ml-slider'), admin_url("?page=metaslider&id={$this->slider->id}")); ?></small>
  994. </th>
  995. <?php } else { ?>
  996. <th class="slider-title" colspan="2">
  997. <h3 class="alignleft"><?php echo get_the_title($this->slider->id) ?></h3>
  998. <input class="metaslider-shortcode" readonly='readonly' onclick="this.select()" type='text' value='[metaslider id=<?php echo $this->slider->id ?>]'>
  999. <?php if (!metaslider_viewing_trashed_slides($this->slider->id)) {
  1000. // Remove the actions on trashed view?>
  1001. <button class='ml-button ml-has-icon ml-skinless-button alignright add-slide' data-editor='content' title='<?php _e( "Add a New Slide", "ml-slider" ) ?>'>
  1002. <i style="top:0;"><svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus-circle"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/></svg></i>
  1003. <span><?php _e("Add Slide", "ml-slider") ?></span>
  1004. </button>
  1005. <?php } ?>
  1006. <?php do_action( "metaslider_admin_table_header_right", $this->slider->id ); ?>
  1007. </th>
  1008. <?php } ?>
  1009. </tr>
  1010. </thead>
  1011. <tbody>
  1012. <?php
  1013. $this->slider->render_admin_slides();
  1014. ?>
  1015. </tbody>
  1016. </table>
  1017. <?php do_action( "metaslider_admin_table_after", $this->slider->id ); ?>
  1018. </div>
  1019. </div>
  1020. <div id="postbox-container-1" class="postbox-container ml-sidebar metaslider-settings-area">
  1021. <div class='right'>
  1022. <?php if (metaslider_viewing_trashed_slides($this->slider->id)) {
  1023. // Show a notice explaining the trash?>
  1024. <div class="ms-postbox trashed-notice">
  1025. <div class="notice-info"><?php printf(__('You are viewing slides that have been trashed, which will be automatically deleted in %s days. Click <a href="%s">here</a> to view active slides.', 'ml-slider'), EMPTY_TRASH_DAYS, admin_url("?page=metaslider&id={$this->slider->id}")); ?></div>
  1026. <?php // TODO this is a temp fix to avoid a compatability check in pro
  1027. echo "<input type='checkbox' style='display:none;' checked class='select-slider' rel='flex'></inpu>";
  1028. ?>
  1029. </div>
  1030. <?php } else {?>
  1031. <div class="ms-postbox" id="metaslider_configuration">
  1032. <div class='configuration metaslider-actions'>
  1033. <button class='metaslider-preview ml-button ml-has-icon ml-skinless-button' type='submit' id='ms-preview' title='<?php _e("Preview Slideshow", "ml-slider") ?>' data-slider_id='<?php echo $this->slider->id ?>' data-slider_width='<?php echo $this->slider->get_setting("width"); ?>' data-slider_height='<?php echo $this->slider->get_setting("height") ?>'>
  1034. <i><svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-eye"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></i>
  1035. <span><?php _e("Preview", "ml-slider") ?></span>
  1036. </button>
  1037. <button class='alignright button button-primary' type='submit' name='save' id='ms-save'>
  1038. <?php _e("Save", "ml-slider"); ?>
  1039. </button>
  1040. <span class="spinner"></span>
  1041. </div>
  1042. <div class="inside wp-clearfix">
  1043. <table class="settings">
  1044. <tbody>
  1045. <?php
  1046. $aFields = array(
  1047. 'type' => array(
  1048. 'priority' => 0,
  1049. 'type' => 'slider-lib',
  1050. 'value' => $this->slider->get_setting('type'),
  1051. 'options' => array(
  1052. 'flex' => array('label' => "FlexSlider"),
  1053. 'responsive' => array('label' => "R. Slides"),
  1054. 'nivo' => array('label' => "Nivo Slider"),
  1055. 'coin' => array('label' => "Coin Slider")
  1056. )
  1057. ),
  1058. 'width' => array(
  1059. 'priority' => 10,
  1060. 'type' => 'number',
  1061. 'size' => 3,
  1062. 'min' => 0,
  1063. 'max' => 9999,
  1064. 'step' => 1,
  1065. 'value' => $this->slider->get_setting( 'width' ),
  1066. 'label' => __( "Width", "ml-slider" ),
  1067. 'class' => 'coin flex responsive nivo',
  1068. 'helptext' => __( "Slideshow width", "ml-slider" ),
  1069. 'after' => __( "px", "ml-slider" )
  1070. ),
  1071. 'height' => array(
  1072. 'priority' => 20,
  1073. 'type' => 'number',
  1074. 'size' => 3,
  1075. 'min' => 0,
  1076. 'max' => 9999,
  1077. 'step' => 1,
  1078. 'value' => $this->slider->get_setting( 'height' ),
  1079. 'label' => __( "Height", "ml-slider" ),
  1080. 'class' => 'coin flex responsive nivo',
  1081. 'helptext' => __( "Slideshow height", "ml-slider" ),
  1082. 'after' => __( "px", "ml-slider" )
  1083. ),
  1084. 'effect' => array(
  1085. 'priority' => 30,
  1086. 'type' => 'select',
  1087. 'value' => $this->slider->get_setting( 'effect' ),
  1088. 'label' => __( "Effect", "ml-slider" ),
  1089. 'class' => 'effect coin flex responsive nivo',
  1090. 'helptext' => __( "Slide transition effect", "ml-slider" ),
  1091. 'options' => array(
  1092. 'random' => array( 'class' => 'option coin nivo' , 'label' => __( "Random", "ml-slider" ) ),
  1093. 'swirl' => array( 'class' => 'option coin', 'label' => __( "Swirl", "ml-slider" ) ),
  1094. 'rain' => array( 'class' => 'option coin', 'label' => __( "Rain", "ml-slider" ) ),
  1095. 'straight' => array( 'class' => 'option coin', 'label' => __( "Straight", "ml-slider" ) ),
  1096. 'sliceDown' => array( 'class' => 'option nivo', 'label' => __( "Slide Down", "ml-slider" ) ),
  1097. 'sliceUp' => array( 'class' => 'option nivo', 'label' => __( "Slice Up", "ml-slider" ) ),
  1098. 'sliceUpLeft' => array( 'class' => 'option nivo', 'label' => __( "Slide Up Left", "ml-slider" ) ),
  1099. 'sliceUpDown' => array( 'class' => 'option nivo', 'label' => __( "Slice Up Down", "ml-slider" ) ),
  1100. 'slideUpDownLeft' => array( 'class' => 'option nivo', 'label' => __( "Slide Up Down Left", "ml-slider" ) ),
  1101. 'fold' => array( 'class' => 'option nivo', 'label' => __( "Fold", "ml-slider" ) ),
  1102. 'fade' => array( 'class' => 'option nivo flex responsive', 'label' => __( "Fade", "ml-slider" ) ),
  1103. 'slideInRight' => array( 'class' => 'option nivo', 'label' => __( "Slide In Right", "ml-slider" ) ),
  1104. 'slideInLeft' => array( 'class' => 'option nivo', 'label' => __( "Slide In Left", "ml-slider" ) ),
  1105. 'boxRandom' => array( 'class' => 'option nivo', 'label' => __( "Box Random", "ml-slider" ) ),
  1106. 'boxRain' => array( 'class' => 'option nivo', 'label' => __( "Box Rain", "ml-slider" ) ),
  1107. 'boxRainReverse' => array( 'class' => 'option nivo', 'label' => __( "Box Rain Reverse", "ml-slider" ) ),
  1108. 'boxRainGrowReverse' => array( 'class' => 'option nivo', 'label' => __( "Box Rain Grow Reverse", "ml-slider" ) ),
  1109. 'slide' => array( 'class' => 'option flex', 'label' => __( "Slide", "ml-slider" ) )
  1110. ),
  1111. ),
  1112. 'theme' => array(
  1113. 'priority' => 40,
  1114. 'type' => 'theme',
  1115. 'value' => $this->slider->get_setting( 'theme' ),
  1116. 'label' => __( "Theme", "ml-slider" ),
  1117. 'class' => 'effect coin flex responsive nivo',
  1118. 'helptext' => __( "Slideshow theme", "ml-slider" ),
  1119. 'options' => array(
  1120. 'default' => array( 'class' => 'option nivo flex coin responsive' , 'label' => __( "Default", "ml-slider" ) ),
  1121. 'dark' => array( 'class' => 'option nivo', 'label' => __( "Dark (Nivo)", "ml-slider" ) ),
  1122. 'light' => array( 'class' => 'option nivo', 'label' => __( "Light (Nivo)", "ml-slider" ) ),
  1123. 'bar' => array( 'class' => 'option nivo', 'label' => __( "Bar (Nivo)", "ml-slider" ) ),
  1124. ),
  1125. ),
  1126. 'links' => array(
  1127. 'priority' => 50,
  1128. 'type' => 'checkbox',
  1129. 'label' => __( "Arrows", "ml-slider" ),
  1130. 'class' => 'option coin flex nivo responsive',
  1131. 'checked' => $this->slider->get_setting( 'links' ) == 'true' ? 'checked' : '',
  1132. 'helptext' => __( "Show the previous/next arrows", "ml-slider" )
  1133. ),
  1134. 'navigation' => array(
  1135. 'priority' => 60,
  1136. 'type' => 'navigation',
  1137. 'label' => __("Navigation", "ml-slider"),
  1138. 'class' => 'option coin flex nivo responsive',
  1139. 'value' => $this->slider->get_setting('navigation'),
  1140. 'helptext' => __("Show the slide navigation bullets", "ml-slider"),
  1141. 'options' => array(
  1142. 'false' => array('label' => __("Hidden", "ml-slider")),
  1143. 'true' => array('label' => __("Dots", "ml-slider")),
  1144. 'thumbs' => array(
  1145. 'label' => __("Thumbnail", "ml-slider"),
  1146. 'addon_required' => true
  1147. ),
  1148. 'filmstrip' => array(
  1149. 'label' => __("Filmstrip", "ml-slider"),
  1150. 'addon_required' => true
  1151. ),
  1152. )
  1153. ),
  1154. );
  1155. if ( $this->get_view() == 'dropdown' ) {
  1156. $aFields['title'] = array(
  1157. 'type' => 'title',
  1158. 'priority' => 5,
  1159. 'class' => 'option flex nivo responsive coin',
  1160. 'value' => get_the_title($this->slider->id),
  1161. 'label' => __( "Title", "ml-slider" ),
  1162. 'helptext' => __( "Slideshow title", "ml-slider" )
  1163. );
  1164. }
  1165. $aFields = apply_filters( 'metaslider_basic_settings', $aFields, $this->slider );
  1166. echo $this->build_settings_rows( $aFields );
  1167. ?>
  1168. </tbody>
  1169. </table>
  1170. <?php // Show the restore button if there are trashed posts
  1171. // Also, render but hide the link in case we want to show
  1172. // it when the user deletes their first slide
  1173. $count = count(metaslider_has_trashed_slides($this->slider->id));
  1174. if (!metaslider_viewing_trashed_slides($this->slider->id)) { ?>
  1175. <a <?php echo $count ? '' : "style='display:none;'" ?> class="restore-slide-link" title="<?php _e('View trashed slides', 'ml-slider'); ?>" href="<?php echo admin_url("?page=metaslider&id={$this->slider->id}&show_trashed=true"); ?>">
  1176. <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 echo __('Trash', 'ml-slider'); if ($count) echo " <span>({$count})</span>";?>
  1177. </a>
  1178. <?php } ?>
  1179. </div>
  1180. </div>
  1181. <div class="ms-postbox ms-toggle closed" id="metaslider_advanced_settings">
  1182. <div class="handlediv" title="Click to toggle"><br></div><h3 class="hndle"><span><?php _e( "Advanced Settings", "ml-slider" ) ?></span></h3>
  1183. <div class="inside">
  1184. <table>
  1185. <tbody>
  1186. <?php
  1187. $aFields = array(
  1188. 'fullWidth' => array(
  1189. 'priority' => 5,
  1190. 'type' => 'checkbox',
  1191. 'label' => __( "Stretch", "ml-slider" ),
  1192. 'class' => 'option flex nivo responsive',
  1193. 'after' => __( "100% wide output", "ml-slider" ),
  1194. 'checked' => $this->slider->get_setting( 'fullWidth' ) == 'true' ? 'checked' : '',
  1195. 'helptext' => __( "Stretch the slideshow output to fill it's parent container", "ml-slider" )
  1196. ),
  1197. 'center' => array(
  1198. 'priority' => 10,
  1199. 'type' => 'checkbox',
  1200. 'label' => __( "Center align", "ml-slider" ),
  1201. 'class' => 'option coin flex nivo responsive',
  1202. 'checked' => $this->slider->get_setting( 'center' ) == 'true' ? 'checked' : '',
  1203. 'helptext' => __( "Center align the slideshow", "ml-slider" )
  1204. ),
  1205. 'autoPlay' => array(
  1206. 'priority' => 20,
  1207. 'type' => 'checkbox',
  1208. 'label' => __( "Auto play", "ml-slider" ),
  1209. 'class' => 'option flex nivo responsive',
  1210. 'checked' => $this->slider->get_setting( 'autoPlay' ) == 'true' ? 'checked' : '',
  1211. 'helptext' => __( "Transition between slides automatically", "ml-slider" )
  1212. ),
  1213. 'smartCrop' => array(
  1214. 'priority' => 30,
  1215. 'type' => 'select',
  1216. 'label' => __( "Image Crop", "ml-slider" ),
  1217. 'class' => 'option coin flex nivo responsive',
  1218. 'value' => $this->slider->get_setting( 'smartCrop' ),
  1219. 'options' => array(
  1220. 'true' => array( 'label' => __( "Smart Crop", "ml-slider" ), 'class' => '' ),
  1221. 'false' => array( 'label' => __( "Standard", "ml-slider" ), 'class' => '' ),
  1222. 'disabled' => array( 'label' => __( "Disabled", "ml-slider" ), 'class' => '' ),
  1223. 'disabled_pad' => array( 'label' => __( "Disabled (Smart Pad)", "ml-slider" ), 'class' => 'option flex' ),
  1224. ),
  1225. 'helptext' => __( "Smart Crop ensures your responsive slides are cropped to a ratio that results in a consistent slideshow size", "ml-slider" )
  1226. ),
  1227. 'carouselMode' => array(
  1228. 'priority' => 40,
  1229. 'type' => 'checkbox',
  1230. 'label' => __( "Carousel mode", "ml-slider" ),
  1231. 'class' => 'option flex showNextWhenChecked',
  1232. 'checked' => $this->slider->get_setting( 'carouselMode' ) == 'true' ? 'checked' : '',
  1233. 'helptext' => __( "Display multiple slides at once. Slideshow output will be 100% wide.", "ml-slider" )
  1234. ),
  1235. 'carouselMargin' => array(
  1236. 'priority' => 45,
  1237. 'min' => 0,
  1238. 'max' => 9999,
  1239. 'step' => 1,
  1240. 'type' => 'number',
  1241. 'label' => __( "Carousel margin", "ml-slider" ),
  1242. 'class' => 'option flex',
  1243. 'value' => $this->slider->get_setting( 'carouselMargin' ),
  1244. 'helptext' => __( "Pixel margin between slides in carousel.", "ml-slider" ),
  1245. 'after' => __( "px", "ml-slider" )
  1246. ),
  1247. 'random' => array(
  1248. 'priority' => 50,
  1249. 'type' => 'checkbox',
  1250. 'label' => __( "Random", "ml-slider" ),
  1251. 'class' => 'option coin flex nivo responsive',
  1252. 'checked' => $this->slider->get_setting( 'random' ) == 'true' ? 'checked' : '',
  1253. 'helptext' => __( "Randomise the order of the slides", "ml-slider" )
  1254. ),
  1255. 'hoverPause' => array(
  1256. 'priority' => 60,
  1257. 'type' => 'checkbox',
  1258. 'label' => __( "Hover pause", "ml-slider" ),
  1259. 'class' => 'option coin flex nivo responsive',
  1260. 'checked' => $this->slider->get_setting( 'hoverPause' ) == 'true' ? 'checked' : '',
  1261. 'helptext' => __( "Pause the slideshow when hovering over slider, then resume when no longer hovering.", "ml-slider" )
  1262. ),
  1263. 'reverse' => array(
  1264. 'priority' => 70,
  1265. 'type' => 'checkbox',
  1266. 'label' => __( "Reverse", "ml-slider" ),
  1267. 'class' => 'option flex',
  1268. 'checked' => $this->slider->get_setting( 'reverse' ) == 'true' ? 'checked' : '',
  1269. 'helptext' => __( "Reverse the animation direction", "ml-slider" )
  1270. ),
  1271. 'delay' => array(
  1272. 'priority' => 80,
  1273. 'type' => 'number',
  1274. 'size' => 3,
  1275. 'min' => 500,
  1276. 'max' => 10000,
  1277. 'step' => 100,
  1278. 'value' => $this->slider->get_setting( 'delay' ),
  1279. 'label' => __( "Slide delay", "ml-slider" ),
  1280. 'class' => 'option coin flex responsive nivo',
  1281. 'helptext' => __( "How long to display each slide, in milliseconds", "ml-slider" ),
  1282. 'after' => __( "ms", "ml-slider" )
  1283. ),
  1284. 'animationSpeed' => array(
  1285. 'priority' => 90,
  1286. 'type' => 'number',
  1287. 'size' => 3,
  1288. 'min' => 0,
  1289. 'max' => 2000,
  1290. 'step' => 100,
  1291. 'value' => $this->slider->get_setting( 'animationSpeed' ),
  1292. 'label' => __( "Animation speed", "ml-slider" ),
  1293. 'class' => 'option flex responsive nivo',
  1294. 'helptext' => __( "Set the speed of animations, in milliseconds", "ml-slider" ),
  1295. 'after' => __( "ms", "ml-slider" )
  1296. ),
  1297. 'slices' => array(
  1298. 'priority' => 100,
  1299. 'type' => 'number',
  1300. 'size' => 3,
  1301. 'min' => 0,
  1302. 'max' => 20,
  1303. 'step' => 1,
  1304. 'value' => $this->slider->get_setting( 'slices' ),
  1305. 'label' => __( "Number of slices", "ml-slider" ),
  1306. 'class' => 'option nivo',
  1307. 'helptext' => __( "Number of slices", "ml-slider" ),
  1308. 'after' => __( "ms", "ml-slider" )
  1309. ),
  1310. 'spw' => array(
  1311. 'priority' => 110,
  1312. 'type' => 'number',
  1313. 'size' => 3,
  1314. 'min' => 0,
  1315. 'max' => 20,
  1316. 'step' => 1,
  1317. 'value' => $this->slider->get_setting( 'spw' ),
  1318. 'label' => __( "Number of squares", "ml-slider" ) . " (" . __( "Width", "ml-slider" ) . ")",
  1319. 'class' => 'option nivo',
  1320. 'helptext' => __( "Number of squares", "ml-slider" ),
  1321. 'after' => ''
  1322. ),
  1323. 'sph' => array(
  1324. 'priority' => 120,
  1325. 'type' => 'number',
  1326. 'size' => 3,
  1327. 'min' => 0,
  1328. 'max' => 20,
  1329. 'step' => 1,
  1330. 'value' => $this->slider->get_setting( 'sph' ),
  1331. 'label' => __( "Number of squares", "ml-slider" ) . " (" . __( "Height", "ml-slider" ) . ")",
  1332. 'class' => 'option nivo',
  1333. 'helptext' => __( "Number of squares", "ml-slider" ),
  1334. 'after' => ''
  1335. ),
  1336. 'direction' => array(
  1337. 'priority' => 130,
  1338. 'type' => 'select',
  1339. 'label' => __( "Slide direction", "ml-slider" ),
  1340. 'class' => 'option flex',
  1341. 'helptext' => __( "Select the sliding direction", "ml-slider" ),
  1342. 'value' => $this->slider->get_setting( 'direction' ),
  1343. 'options' => array(
  1344. 'horizontal' => array( 'label' => __( "Horizontal", "ml-slider" ), 'class' => '' ),
  1345. 'vertical' => array( 'label' => __( "Vertical", "ml-slider" ), 'class' => '' ),
  1346. )
  1347. ),
  1348. 'easing' => array(
  1349. 'priority' => 140,
  1350. 'type' => 'select',
  1351. 'label' => __( "Easing", "ml-slider" ),
  1352. 'class' => 'option flex',
  1353. 'helptext' => __( "Animation easing effect", "ml-slider" ),
  1354. 'value' => $this->slider->get_setting( 'easing' ),
  1355. 'options' => $this->get_easing_options()
  1356. ),
  1357. 'prevText' => array(
  1358. 'priority' => 150,
  1359. 'type' => 'text',
  1360. 'label' => __( "Previous text", "ml-slider" ),
  1361. 'class' => 'option coin flex responsive nivo',
  1362. 'helptext' => __( "Set the text for the 'previous' direction item", "ml-slider" ),
  1363. 'value' => $this->slider->get_setting( 'prevText' ) == 'false' ? '' : $this->slider->get_setting( 'prevText' )
  1364. ),
  1365. 'nextText' => array(
  1366. 'priority' => 160,
  1367. 'type' => 'text',
  1368. 'label' => __( "Next text", "ml-slider" ),
  1369. 'class' => 'option coin flex responsive nivo',
  1370. 'helptext' => __( "Set the text for the 'next' direction item", "ml-slider" ),
  1371. 'value' => $this->slider->get_setting( 'nextText' ) == 'false' ? '' : $this->slider->get_setting( 'nextText' )
  1372. ),
  1373. 'sDelay' => array(
  1374. 'priority' => 170,
  1375. 'type' => 'number',
  1376. 'size' => 3,
  1377. 'min' => 0,
  1378. 'max' => 500,
  1379. 'step' => 10,
  1380. 'value' => $this->slider->get_setting( 'sDelay' ),
  1381. 'label' => __( "Square delay", "ml-slider" ),
  1382. 'class' => 'option coin',
  1383. 'helptext' => __( "Delay between squares in ms", "ml-slider" ),
  1384. 'after' => __( "ms", "ml-slider" )
  1385. ),
  1386. 'opacity' => array(
  1387. 'priority' => 180,
  1388. 'type' => 'number',
  1389. 'size' => 3,
  1390. 'min' => 0,
  1391. 'max' => 1,
  1392. 'step' => 0.1,
  1393. 'value' => $this->slider->get_setting( 'opacity' ),
  1394. 'label' => __( "Opacity", "ml-slider" ),
  1395. 'class' => 'option coin',
  1396. 'helptext' => __( "Opacity of title and navigation", "ml-slider" ),
  1397. 'after' => ''
  1398. ),
  1399. 'titleSpeed' => array(
  1400. 'priority' => 190,
  1401. 'type' => 'number',
  1402. 'size' => 3,
  1403. 'min' => 0,
  1404. 'max' => 10000,
  1405. 'step' => 100,
  1406. 'value' => $this->slider->get_setting( 'titleSpeed' ),
  1407. 'label' => __( "Caption speed", "ml-slider" ),
  1408. 'class' => 'option coin',
  1409. 'helptext' => __( "Set the fade in speed of the caption", "ml-slider" ),
  1410. 'after' => __( "ms", "ml-slider" )
  1411. ),
  1412. 'developerOptions' => array(
  1413. 'priority' => 195,
  1414. 'type' => 'divider',
  1415. 'class' => 'option coin flex responsive nivo',
  1416. 'value' => __( "Developer options", "ml-slider" )
  1417. ),
  1418. 'cssClass' => array(
  1419. 'priority' => 200,
  1420. 'type' => 'text',
  1421. 'label' => __( "CSS classes", "ml-slider" ),
  1422. 'class' => 'option coin flex responsive nivo',
  1423. 'helptext' => __( "Specify any custom CSS Classes you would like to be added to the slider wrapper", "ml-slider" ),
  1424. 'value' => $this->slider->get_setting( 'cssClass' ) == 'false' ? '' : $this->slider->get_setting( 'cssClass' )
  1425. ),
  1426. 'printCss' => array(
  1427. 'priority' => 210,
  1428. 'type' => 'checkbox',
  1429. 'label' => __( "Print CSS", "ml-slider" ),
  1430. 'class' => 'option coin flex responsive nivo useWithCaution',
  1431. 'checked' => $this->slider->get_setting( 'printCss' ) == 'true' ? 'checked' : '',
  1432. 'helptext' => __( "Uncheck this is you would like to include your own CSS", "ml-slider" )
  1433. ),
  1434. 'printJs' => array(
  1435. 'priority' => 220,
  1436. 'type' => 'checkbox',
  1437. 'label' => __( "Print JS", "ml-slider" ),
  1438. 'class' => 'option coin flex responsive nivo useWithCaution',
  1439. 'checked' => $this->slider->get_setting( 'printJs' ) == 'true' ? 'checked' : '',
  1440. 'helptext' => __( "Uncheck this is you would like to include your own Javascript", "ml-slider" )
  1441. ),
  1442. 'noConflict' => array(
  1443. 'priority' => 230,
  1444. 'type' => 'checkbox',
  1445. 'label' => __( "No conflict mode", "ml-slider" ),
  1446. 'class' => 'option flex',
  1447. 'checked' => $this->slider->get_setting( 'noConflict' ) == 'true' ? 'checked' : '',
  1448. 'helptext' => __( "Delay adding the flexslider class to the slideshow", "ml-slider" )
  1449. ),
  1450. );
  1451. $aFields = apply_filters( 'metaslider_advanced_settings', $aFields, $this->slider );
  1452. echo $this->build_settings_rows( $aFields );
  1453. ?>
  1454. </tbody>
  1455. </table>
  1456. </div>
  1457. </div>
  1458. <?php $url = wp_nonce_url(admin_url("admin-post.php?action=metaslider_delete_slider&amp;slider_id={$this->slider->id}"), "metaslider_delete_slider"); ?>
  1459. <a class='delete-slider alignright ml-has-icon ml-button ml-delete-button' href='<?php echo $url ?>'><i><svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-x"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></i><span><?php _e( "Delete Slideshow", "ml-slider" ) ?></span></a>
  1460. </div>
  1461. <?php } ?>
  1462. </div>
  1463. </div>
  1464. </div>
  1465. </form>
  1466. </div>
  1467. <?php
  1468. }
  1469. /**
  1470. * Append the 'Add Slider' button to selected admin pages
  1471. */
  1472. public function insert_metaslider_button( $context ) {
  1473. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  1474. if ( ! current_user_can( $capability ) ) {
  1475. return $context;
  1476. }
  1477. global $pagenow;
  1478. if ( in_array( $pagenow, array( 'post.php', 'page.php', 'post-new.php', 'post-edit.php' ) ) ) {
  1479. $context .= '<a href="#TB_inline?&inlineId=choose-meta-slider" class="thickbox button" title="' .
  1480. __( "Select slideshow to insert into post", "ml-slider" ) .
  1481. '"><span class="wp-media-buttons-icon" style="background: url(' . METASLIDER_ASSETS_URL .
  1482. '/metaslider/matchalabs.png); background-repeat: no-repeat; background-position: left bottom;"></span> ' .
  1483. __( "Add slider", "ml-slider" ) . '</a>';
  1484. }
  1485. return $context;
  1486. }
  1487. /**
  1488. * Append the 'Choose MetaSlider' thickbox content to the bottom of selected admin pages
  1489. */
  1490. public function admin_footer() {
  1491. global $pagenow;
  1492. // Only run in post/page creation and edit screens
  1493. if ( in_array( $pagenow, array( 'post.php', 'page.php', 'post-new.php', 'post-edit.php' ) ) ) {
  1494. $sliders = $this->all_meta_sliders( 'title' );
  1495. ?>
  1496. <script type="text/javascript">
  1497. jQuery(document).ready(function() {
  1498. jQuery('#insertMetaSlider').on('click', function() {
  1499. var id = jQuery('#metaslider-select option:selected').val();
  1500. window.send_to_editor('[metaslider id=' + id + ']');
  1501. tb_remove();
  1502. })
  1503. });
  1504. </script>
  1505. <div id="choose-meta-slider" style="display: none;">
  1506. <div class="wrap">
  1507. <?php
  1508. if ( count( $sliders ) ) {
  1509. echo "<h3 style='margin-bottom: 20px;'>" . __( "Insert MetaSlider", "ml-slider" ) . "</h3>";
  1510. echo "<select id='metaslider-select'>";
  1511. echo "<option disabled=disabled>" . __( "Choose slideshow", "ml-slider" ) . "</option>";
  1512. foreach ( $sliders as $slider ) {
  1513. echo "<option value='{$slider['id']}'>{$slider['title']}</option>";
  1514. }
  1515. echo "</select>";
  1516. echo "<button class='button primary' id='insertMetaSlider'>" . __( "Insert slideshow", "ml-slider" ) . "</button>";
  1517. } else {
  1518. _e( "No slideshows found", "ml-slider" );
  1519. }
  1520. ?>
  1521. </div>
  1522. </div>
  1523. <?php
  1524. }
  1525. }
  1526. /**
  1527. * Return the MetaSlider pro upgrade iFrame
  1528. */
  1529. public function upgrade_to_pro_tab() {
  1530. if ( function_exists( 'is_plugin_active' ) && ! is_plugin_active( 'ml-slider-pro/ml-slider-pro.php' ) ) {
  1531. return wp_iframe( array( $this, 'upgrade_to_pro_iframe' ) );
  1532. }
  1533. }
  1534. /**
  1535. * Media Manager iframe HTML
  1536. */
  1537. public function upgrade_to_pro_iframe() {
  1538. wp_enqueue_style('metaslider-admin-styles', METASLIDER_ADMIN_URL . 'assets/css/admin.css', false, METASLIDER_VERSION);
  1539. wp_enqueue_script('google-font-api', 'https://fonts.googleapis.com/css?family=PT+Sans:400,700' , false, METASLIDER_VERSION);
  1540. $link = apply_filters( 'metaslider_hoplink', 'https://www.metaslider.com/upgrade/' );
  1541. $link .= '?utm_source=lite&amp;utm_medium=more-slide-types&amp;utm_campaign=pro';
  1542. echo implode("", array(
  1543. "<div class='metaslider_pro'>",
  1544. "<p>Get the Pro Addon pack to add support for: <b>Post Feed</b> Slides, <b>YouTube</b> Slides, <b>HTML</b> Slides & <b>Vimeo</b> Slides</p>",
  1545. "<a class='probutton' href='{$link}' target='_blank'>Get <span class='logo'><strong>Meta</strong>Slider</span><span class='super'>Pro</span></a>",
  1546. "<span class='subtext'>Opens in a new window</span>",
  1547. "</div>"
  1548. ));
  1549. }
  1550. /**
  1551. * Adds extra links to the plugin activation page
  1552. */
  1553. public function get_extra_meta_links($meta, $file, $data, $status) {
  1554. if (plugin_basename(__FILE__) == $file) {
  1555. $plugin_page = admin_url('admin.php?page=metaslider');
  1556. $meta[] = "<a href='{$plugin_page}' onclick=\"event.preventDefault();var link = jQuery(this);jQuery.post(ajaxurl, {action: 'reset_tour_status', _wpnonce: metaslider_tour_nonce }, function(data) {window.location = link.attr('href');});\">" . __('Take a tour', 'ml-slider') . "</a>";
  1557. if (metaslider_is_pro_installed()) {
  1558. $upgrade_link = apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade/');
  1559. $meta[] = "<a href='{$upgrade_link}' target='_blank'>" . __('Add-ons', 'ml-slider') . "</a>";
  1560. $meta[] = "<a href='https://wordpress.org/support/plugin/ml-slider/' target='_blank'>" . __('Support', 'ml-slider') . "</a>";
  1561. } else {
  1562. $meta[] = "<a href='https://www.metaslider.com/support/' target='_blank'>" . __('Premium Support', 'ml-slider') . "</a>";
  1563. }
  1564. $meta[] = "<a href='https://www.metaslider.com/documentation/' target='_blank'>" . __('Documentation', 'ml-slider') . "</a>";
  1565. $meta[] = "<a href='https://wordpress.org/support/plugin/ml-slider/reviews#new-post' target='_blank' title='" . __('Leave a review', 'ml-slider') . "'><i class='ml-stars'><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg></i></a>";
  1566. }
  1567. return $meta;
  1568. }
  1569. /**
  1570. * Adds styles to admin head to allow for stars animation and coloring
  1571. */
  1572. public function add_star_styles() {
  1573. if (metaslider_is_on_admin_page('plugins.php')) {?>
  1574. <style>
  1575. .ml-stars{display:inline-block;color:#ffb900;position:relative;top:3px}
  1576. .ml-stars svg{fill:#ffb900}
  1577. .ml-stars svg:hover{fill:#ffb900}
  1578. .ml-stars svg:hover ~ svg{fill:none}
  1579. </style>
  1580. <?php }
  1581. }
  1582. /**
  1583. * Add nonce to activation page
  1584. */
  1585. public function add_tour_nonce_to_activation_page() {
  1586. if (metaslider_is_on_admin_page('plugins.php')) {?>
  1587. <script>
  1588. var metaslider_tour_nonce = "<?php echo wp_create_nonce('metaslider_tour_nonce'); ?>";
  1589. </script>
  1590. <?php }
  1591. }
  1592. /**
  1593. * Upgrade To Pro Button.
  1594. */
  1595. public function upgrade_to_pro_top_button() {
  1596. $text = __('Upgrade Now', "ml-slider");
  1597. $link = metaslider_get_upgrade_link();
  1598. $upgrade_text = __("Get The Pro Pack Today!", "ml-slider");
  1599. return "<a target='_blank' title='{$upgrade_text}' class='ml-has-icon ml-hanging-button' href='{$link}'><i class='brand-color'><svg xmlns='http://www.w3.org/2000/svg' width='17' height='17' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg></i><span>{$text}</span></a>";
  1600. }
  1601. /**
  1602. * Toggle Layout Buttons.
  1603. * TODO: Re work this to allow for a third view style
  1604. */
  1605. public function toggle_layout_button() {
  1606. // Don't show this if there are no slideshows
  1607. if (!count($this->all_meta_sliders())) {
  1608. return '';
  1609. }
  1610. $view = ('tabs' == $this->get_view()) ? 'tabs' : 'dropdown';
  1611. $view_opposite = ('dropdown' == $this->get_view()) ? 'tabs' : 'dropdown';
  1612. $view_text = ($this->get_view() == 'tabs') ? __("Switch to Dropdown view", "ml-slider") : __("Switch to Tab view", "ml-slider");
  1613. return "<a class='ml-has-icon ml-hanging-button' title='" . $view_text . "'
  1614. href='" . admin_url( "admin-post.php?action=metaslider_switch_view&view=".$view_opposite) . "'><i><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-shuffle\"><polyline points=\"16 3 21 3 21 8\"/><line x1=\"4\" y1=\"20\" x2=\"21\" y2=\"3\"/><polyline points=\"21 16 21 21 16 21\"/><line x1=\"15\" y1=\"15\" x2=\"21\" y2=\"21\"/><line x1=\"4\" y1=\"4\" x2=\"9\" y2=\"9\"/></svg></i><span>" . __("Layout", "ml-slider") . "</span></a>";
  1615. }
  1616. /**
  1617. * Support and Docs Button
  1618. */
  1619. public function documentation_button() {
  1620. return "<a class='ml-has-icon ml-hanging-button' target='_blank' title='" . __('View The Documentation', 'ml-slider') . "' href='https://www.metaslider.com/documentation/'><i><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"17\" height=\"17\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-book\"><path d=\"M4 19.5A2.5 2.5 0 0 1 6.5 17H20\"/><path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z\"/></svg></i><span>" . __("Documentation", "ml-slider") . "</span></a>";
  1621. }
  1622. /**
  1623. * Add a 'property=stylesheet' attribute to the MetaSlider CSS links for HTML5 validation
  1624. *
  1625. * @since 3.3.4
  1626. * @param string $tag
  1627. * @param string $handle
  1628. */
  1629. public function add_property_attribute_to_stylesheet_links( $tag, $handle ) {
  1630. if ( strpos( $handle, 'metaslider' ) !== FALSE && strpos( $tag, "property='" ) === FALSE ) {
  1631. // we're only filtering tags with metaslider in the handle, and links which don't already have a property attribute
  1632. $tag = str_replace( "/>", "property='stylesheet' />", $tag );
  1633. }
  1634. return $tag;
  1635. }
  1636. }
  1637. endif;
  1638. add_action( 'plugins_loaded', array( 'MetaSliderPlugin', 'init' ), 10 );