PageRenderTime 63ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://gitlab.com/thisishayat/itv-2016
PHP | 1318 lines | 890 code | 260 blank | 168 comment | 73 complexity | 11c006ed092cd409624817813b390427 MD5 | raw file
  1. <?php
  2. /*
  3. * Meta Slider. Slideshow plugin for WordPress.
  4. *
  5. * Plugin Name: Meta Slider
  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.3.6
  9. * Author: Matcha Labs
  10. * Author URI: https://www.metaslider.com
  11. * License: GPL-2.0+
  12. * Copyright: 2014 Matcha Labs 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.3.6';
  31. /**
  32. * @var MetaSlider
  33. */
  34. public $slider = null;
  35. /**
  36. * Init
  37. */
  38. public static function init() {
  39. $metaslider = new self();
  40. }
  41. /**
  42. * Constructor
  43. */
  44. public function __construct() {
  45. $this->define_constants();
  46. $this->includes();
  47. $this->setup_actions();
  48. $this->setup_filters();
  49. $this->setup_shortcode();
  50. $this->register_slide_types();
  51. }
  52. /**
  53. * Define Meta Slider constants
  54. */
  55. private function define_constants() {
  56. define( 'METASLIDER_VERSION', $this->version );
  57. define( 'METASLIDER_BASE_URL', trailingslashit( plugins_url( 'ml-slider' ) ) );
  58. define( 'METASLIDER_ASSETS_URL', trailingslashit( METASLIDER_BASE_URL . 'assets' ) );
  59. define( 'METASLIDER_PATH', plugin_dir_path( __FILE__ ) );
  60. }
  61. /**
  62. * All Meta Slider classes
  63. */
  64. private function plugin_classes() {
  65. return array(
  66. 'metaslider' => METASLIDER_PATH . 'inc/slider/metaslider.class.php',
  67. 'metacoinslider' => METASLIDER_PATH . 'inc/slider/metaslider.coin.class.php',
  68. 'metaflexslider' => METASLIDER_PATH . 'inc/slider/metaslider.flex.class.php',
  69. 'metanivoslider' => METASLIDER_PATH . 'inc/slider/metaslider.nivo.class.php',
  70. 'metaresponsiveslider' => METASLIDER_PATH . 'inc/slider/metaslider.responsive.class.php',
  71. 'metaslide' => METASLIDER_PATH . 'inc/slide/metaslide.class.php',
  72. 'metaimageslide' => METASLIDER_PATH . 'inc/slide/metaslide.image.class.php',
  73. 'metasliderimagehelper' => METASLIDER_PATH . 'inc/metaslider.imagehelper.class.php',
  74. 'metaslidersystemcheck' => METASLIDER_PATH . 'inc/metaslider.systemcheck.class.php',
  75. 'metaslider_widget' => METASLIDER_PATH . 'inc/metaslider.widget.class.php',
  76. 'simple_html_dom' => METASLIDER_PATH . 'inc/simple_html_dom.php'
  77. );
  78. }
  79. /**
  80. * Load required classes
  81. */
  82. private function includes() {
  83. $autoload_is_disabled = defined( 'METASLIDER_AUTOLOAD_CLASSES' ) && METASLIDER_AUTOLOAD_CLASSES === false;
  84. if ( function_exists( "spl_autoload_register" ) && ! ( $autoload_is_disabled ) ) {
  85. // >= PHP 5.2 - Use auto loading
  86. if ( function_exists( "__autoload" ) ) {
  87. spl_autoload_register( "__autoload" );
  88. }
  89. spl_autoload_register( array( $this, 'autoload' ) );
  90. } else {
  91. // < PHP5.2 - Require all classes
  92. foreach ( $this->plugin_classes() as $id => $path ) {
  93. if ( is_readable( $path ) && ! class_exists( $id ) ) {
  94. require_once( $path );
  95. }
  96. }
  97. }
  98. }
  99. /**
  100. * Autoload Meta Slider classes to reduce memory consumption
  101. */
  102. public function autoload( $class ) {
  103. $classes = $this->plugin_classes();
  104. $class_name = strtolower( $class );
  105. if ( isset( $classes[$class_name] ) && is_readable( $classes[$class_name] ) ) {
  106. require_once( $classes[$class_name] );
  107. }
  108. }
  109. /**
  110. * Register the [metaslider] shortcode.
  111. */
  112. private function setup_shortcode() {
  113. add_shortcode( 'metaslider', array( $this, 'register_shortcode' ) );
  114. add_shortcode( 'ml-slider', array( $this, 'register_shortcode' ) ); // backwards compatibility
  115. }
  116. /**
  117. * Hook Meta Slider into WordPress
  118. */
  119. private function setup_actions() {
  120. add_action( 'admin_menu', array( $this, 'register_admin_menu' ), 9553 );
  121. add_action( 'init', array( $this, 'register_post_type' ) );
  122. add_action( 'init', array( $this, 'register_taxonomy' ) );
  123. add_action( 'init', array( $this, 'load_plugin_textdomain' ) );
  124. add_action( 'admin_footer', array( $this, 'admin_footer' ), 11 );
  125. add_action( 'widgets_init', array( $this, 'register_metaslider_widget' ) );
  126. add_action( 'admin_post_metaslider_preview', array( $this, 'do_preview' ) );
  127. add_action( 'admin_post_metaslider_hide_go_pro_page', array( $this, 'hide_go_pro_page' ) );
  128. add_action( 'admin_post_metaslider_switch_view', array( $this, 'switch_view' ) );
  129. add_action( 'admin_post_metaslider_delete_slide', array( $this, 'delete_slide' ) );
  130. add_action( 'admin_post_metaslider_delete_slider', array( $this, 'delete_slider' ) );
  131. add_action( 'admin_post_metaslider_create_slider', array( $this, 'create_slider' ) );
  132. add_action( 'admin_post_metaslider_update_slider', array( $this, 'update_slider' ) );
  133. }
  134. /**
  135. * Hook Meta Slider into WordPress
  136. */
  137. private function setup_filters() {
  138. add_filter( 'media_upload_tabs', array( $this, 'custom_media_upload_tab_name' ), 998 );
  139. add_filter( 'media_view_strings', array( $this, 'custom_media_uploader_tabs' ), 5 );
  140. add_filter( 'media_buttons_context', array( $this, 'insert_metaslider_button' ) );
  141. // add 'go pro' link to plugin options
  142. $plugin = plugin_basename( __FILE__ );
  143. add_filter( "plugin_action_links_{$plugin}", array( $this, 'upgrade_to_pro_link' ) );
  144. // html5 compatibility for stylesheets enqueued within <body>
  145. add_filter( 'style_loader_tag', array( $this, 'add_property_attribute_to_stylesheet_links' ), 11, 2 );
  146. }
  147. /**
  148. * Register Meta Slider widget
  149. */
  150. public function register_metaslider_widget() {
  151. register_widget( 'MetaSlider_Widget' );
  152. }
  153. /**
  154. * Register ML Slider post type
  155. */
  156. public function register_post_type() {
  157. register_post_type( 'ml-slider', array(
  158. 'query_var' => false,
  159. 'rewrite' => false,
  160. 'public' => true,
  161. 'exclude_from_search' => true,
  162. 'publicly_queryable' => false,
  163. 'show_in_nav_menus' => false,
  164. 'show_ui' => false,
  165. 'labels' => array(
  166. 'name' => 'Meta Slider'
  167. )
  168. )
  169. );
  170. }
  171. /**
  172. * Register taxonomy to store slider => slides relationship
  173. */
  174. public function register_taxonomy() {
  175. register_taxonomy( 'ml-slider', 'attachment', array(
  176. 'hierarchical' => true,
  177. 'public' => false,
  178. 'query_var' => false,
  179. 'rewrite' => false
  180. )
  181. );
  182. }
  183. /**
  184. * Register our slide types
  185. */
  186. private function register_slide_types() {
  187. $image = new MetaImageSlide();
  188. }
  189. /**
  190. * Add the menu page
  191. */
  192. public function register_admin_menu() {
  193. global $user_ID;
  194. $title = apply_filters( 'metaslider_menu_title', 'Meta Slider' );
  195. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  196. $page = add_menu_page( $title, $title, $capability, 'metaslider', array(
  197. $this, 'render_admin_page'
  198. ), METASLIDER_ASSETS_URL . 'metaslider/matchalabs.png', 9501 );
  199. // ensure our JavaScript is only loaded on the Meta Slider admin page
  200. add_action( 'admin_print_scripts-' . $page, array( $this, 'register_admin_scripts' ) );
  201. add_action( 'admin_print_styles-' . $page, array( $this, 'register_admin_styles' ) );
  202. add_action( 'load-' . $page, array( $this, 'help_tab' ) );
  203. if ( ! is_plugin_active( 'ml-slider-pro/ml-slider-pro.php' ) && get_user_meta( $user_ID, "metaslider_hide_go_pro", true ) !== 'true' ) {
  204. $page = add_submenu_page(
  205. 'metaslider',
  206. __( 'Go Pro!', 'ml-slider' ),
  207. __( 'Go Pro!', 'ml-slider' ),
  208. $capability,
  209. 'metaslider-go-pro',
  210. array( $this, 'go_pro_page' )
  211. );
  212. add_action( 'admin_print_styles-' . $page, array( $this, 'register_admin_styles' ) );
  213. }
  214. }
  215. /**
  216. * Go Pro page content
  217. */
  218. public function go_pro_page() {
  219. $upgrade_link = esc_url( add_query_arg(
  220. array(
  221. 'utm_source' => 'lite',
  222. 'utm_medium' => 'nag',
  223. 'utm_campaign' => 'pro'
  224. ), 'http://www.metaslider.com/upgrade/' ) );
  225. $link = apply_filters( 'metaslider_hoplink', $upgrade_link );
  226. $hide_link = '<a href="' . admin_url( "admin-post.php?action=metaslider_hide_go_pro_page" ) . '">Hide this page</a>';
  227. $gopro_link = "<a class='button button-primary' href='{$link}' target='_blank'>Find out more</a>";
  228. $support_link = '<a href="https://wordpress.org/support/plugin/ml-slider">Support</a>';
  229. $documentation_link = '<a href="http://www.metaslider.com/documentation/">Documentation</a>';
  230. ?>
  231. <h2>Supercharge Your Sliders with Meta Slider Pro!</h2>
  232. <ul class='metaslider_gopro'>
  233. <li>Create <b>animated HTML slides</b> using the drag &amp; drop layer editor (WYSIWYG)</li>
  234. <li>Insert <b>YouTube</b> and <b>Vimeo</b> videos into your slideshows</li>
  235. <li>Automatically populate your slideshows with your <b>latest blog posts</b> or custom post types</li>
  236. <li>Customize the look of your slideshows with the <b>Theme Editor</b> (25+ settings including custom arrow images, dot colors and caption styling)</li>
  237. <li>Give your slideshows a gallery feel with <b>thumbnail navigation</b></li>
  238. <li>Feature <b>WooCommerce</b> products in your slideshows</li>
  239. <li>Show your latest events from <b>The Events Calendar</b> plugin</li>
  240. <li><b>Easy to install</B> - Meta Slider Pro installs as a seperate plugin alongside Meta Slider and seamlessly adds in the new functionality</li>
  241. <li><b>Easy to update</b> - new updates will be displayed on your plugins page (just like your other plugins!)</li>
  242. <li>Upgrade with confidence with our <b>30 day no questions money back guarantee</b></li>
  243. <li>Meta Slider Pro users receive <b>priority support</b> from our dedicated team, were on hand to help you get the most of Meta Slider</li>
  244. </ul>
  245. <p><?php echo $gopro_link; ?></p>
  246. <p><?php echo $support_link; ?> <?php echo $documentation_link; ?></p>
  247. <p><em>Don't want to see this? <?php echo $hide_link; ?></em></p>
  248. <?php
  249. }
  250. /**
  251. * Store the users preference to hide the go pro page.
  252. */
  253. public function hide_go_pro_page() {
  254. global $user_ID;
  255. if ( ! get_user_meta( $user_ID, "metaslider_hide_go_pro" ) ) {
  256. add_user_meta( $user_ID, "metaslider_hide_go_pro", "true" );
  257. }
  258. wp_redirect( admin_url( "admin.php?page=metaslider" ) );
  259. }
  260. /**
  261. * Shortcode used to display slideshow
  262. *
  263. * @return string HTML output of the shortcode
  264. */
  265. public function register_shortcode( $atts ) {
  266. extract( shortcode_atts( array(
  267. 'id' => false,
  268. 'restrict_to' => false
  269. ), $atts, 'metaslider' ) );
  270. if ( ! $id ) {
  271. return false;
  272. }
  273. // handle [metaslider id=123 restrict_to=home]
  274. if ($restrict_to && $restrict_to == 'home' && ! is_front_page()) {
  275. return;
  276. }
  277. if ($restrict_to && $restrict_to != 'home' && ! is_page( $restrict_to ) ) {
  278. return;
  279. }
  280. // we have an ID to work with
  281. $slider = get_post( $id );
  282. // check the slider is published and the ID is correct
  283. if ( ! $slider || $slider->post_status != 'publish' || $slider->post_type != 'ml-slider' ) {
  284. return "<!-- meta slider {$atts['id']} not found -->";
  285. }
  286. // lets go
  287. $this->set_slider( $id, $atts );
  288. $this->slider->enqueue_scripts();
  289. return $this->slider->render_public_slides();
  290. }
  291. /**
  292. * Initialise translations
  293. */
  294. public function load_plugin_textdomain() {
  295. load_plugin_textdomain( 'ml-slider', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
  296. }
  297. /**
  298. * Add the help tab to the screen.
  299. */
  300. public function help_tab() {
  301. $screen = get_current_screen();
  302. // documentation tab
  303. $screen->add_help_tab( array(
  304. 'id' => 'documentation',
  305. 'title' => __( 'Documentation', 'ml-slider' ),
  306. 'content' => "<p><a href='http://www.metaslider.com/documentation/' target='blank'>Meta Slider Documentation</a></p>",
  307. )
  308. );
  309. }
  310. /**
  311. * Rehister admin styles
  312. */
  313. public function register_admin_styles() {
  314. wp_enqueue_style( 'metaslider-admin-styles', METASLIDER_ASSETS_URL . 'metaslider/admin.css', false, METASLIDER_VERSION );
  315. wp_enqueue_style( 'metaslider-colorbox-styles', METASLIDER_ASSETS_URL . 'colorbox/colorbox.css', false, METASLIDER_VERSION );
  316. wp_enqueue_style( 'metaslider-tipsy-styles', METASLIDER_ASSETS_URL . 'tipsy/tipsy.css', false, METASLIDER_VERSION );
  317. do_action( 'metaslider_register_admin_styles' );
  318. }
  319. /**
  320. * Register admin JavaScript
  321. */
  322. public function register_admin_scripts() {
  323. // media library dependencies
  324. wp_enqueue_media();
  325. // plugin dependencies
  326. wp_enqueue_script( 'jquery-ui-core', array( 'jquery' ) );
  327. wp_enqueue_script( 'jquery-ui-sortable', array( 'jquery', 'jquery-ui-core' ) );
  328. wp_enqueue_script( 'metaslider-colorbox', METASLIDER_ASSETS_URL . 'colorbox/jquery.colorbox-min.js', array( 'jquery' ), METASLIDER_VERSION );
  329. wp_enqueue_script( 'metaslider-tipsy', METASLIDER_ASSETS_URL . 'tipsy/jquery.tipsy.js', array( 'jquery' ), METASLIDER_VERSION );
  330. wp_enqueue_script( 'metaslider-admin-script', METASLIDER_ASSETS_URL . 'metaslider/admin.js', array( 'jquery', 'metaslider-tipsy', 'media-upload' ), METASLIDER_VERSION );
  331. wp_dequeue_script( 'link' ); // WP Posts Filter Fix (Advanced Settings not toggling)
  332. wp_dequeue_script( 'ai1ec_requirejs' ); // All In One Events Calendar Fix (Advanced Settings not toggling)
  333. $this->localize_admin_scripts();
  334. do_action( 'metaslider_register_admin_scripts' );
  335. }
  336. /**
  337. * Localise admin script
  338. */
  339. public function localize_admin_scripts() {
  340. wp_localize_script( 'metaslider-admin-script', 'metaslider', array(
  341. 'url' => __( "URL", "ml-slider" ),
  342. 'caption' => __( "Caption", "ml-slider" ),
  343. 'new_window' => __( "New Window", "ml-slider" ),
  344. 'confirm' => __( "Are you sure?", "ml-slider" ),
  345. 'ajaxurl' => admin_url( 'admin-ajax.php' ),
  346. 'change_image' => __( "Select replacement image", "ml-slider"),
  347. 'resize_nonce' => wp_create_nonce( 'metaslider_resize' ),
  348. 'addslide_nonce' => wp_create_nonce( 'metaslider_addslide' ),
  349. 'changeslide_nonce' => wp_create_nonce( 'metaslider_changeslide' ),
  350. 'iframeurl' => admin_url( 'admin-post.php?action=metaslider_preview' ),
  351. 'useWithCaution' => __( "Caution: This setting is for advanced developers only. If you're unsure, leave it checked.", "ml-slider" )
  352. )
  353. );
  354. }
  355. /**
  356. * Outputs a blank page containing a slideshow preview (for use in the 'Preview' iFrame)
  357. */
  358. public function do_preview() {
  359. remove_action('wp_footer', 'wp_admin_bar_render', 1000);
  360. if ( isset( $_GET['slider_id'] ) && absint( $_GET['slider_id'] ) > 0 ) {
  361. $id = absint( $_GET['slider_id'] );
  362. ?>
  363. <!DOCTYPE html>
  364. <html>
  365. <head>
  366. <style type='text/css'>
  367. body, html {
  368. overflow: hidden;
  369. margin: 0;
  370. padding: 0;
  371. }
  372. </style>
  373. <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
  374. <meta http-equiv="Pragma" content="no-cache" />
  375. <meta http-equiv="Expires" content="0" />
  376. </head>
  377. <body>
  378. <?php echo do_shortcode("[metaslider id={$id}]"); ?>
  379. <?php wp_footer(); ?>
  380. </body>
  381. </html>
  382. <?php
  383. }
  384. die();
  385. }
  386. /**
  387. * Check our WordPress installation is compatible with Meta Slider
  388. */
  389. public function do_system_check() {
  390. $systemCheck = new MetaSliderSystemCheck();
  391. $systemCheck->check();
  392. }
  393. /**
  394. * Update the tab options in the media manager
  395. */
  396. public function custom_media_uploader_tabs( $strings ) {
  397. //update strings
  398. if ( ( isset( $_GET['page'] ) && $_GET['page'] == 'metaslider' ) ) {
  399. $strings['insertMediaTitle'] = __( "Image", "ml-slider" );
  400. $strings['insertIntoPost'] = __( "Add to slider", "ml-slider" );
  401. // remove options
  402. $strings_to_remove = array(
  403. 'createVideoPlaylistTitle',
  404. 'createGalleryTitle',
  405. 'insertFromUrlTitle',
  406. 'createPlaylistTitle'
  407. );
  408. foreach ($strings_to_remove as $string) {
  409. if (isset($strings[$string])) {
  410. unset($strings[$string]);
  411. }
  412. }
  413. }
  414. return $strings;
  415. }
  416. /**
  417. * Add extra tabs to the default wordpress Media Manager iframe
  418. *
  419. * @var array existing media manager tabs
  420. */
  421. public function custom_media_upload_tab_name( $tabs ) {
  422. // restrict our tab changes to the meta slider plugin page
  423. if ( isset( $_GET['page'] ) && $_GET['page'] == 'metaslider' ) {
  424. if ( isset( $tabs['nextgen'] ) ) {
  425. unset( $tabs['nextgen'] );
  426. }
  427. }
  428. return $tabs;
  429. }
  430. /**
  431. * Set the current slider
  432. */
  433. public function set_slider( $id, $shortcode_settings = array() ) {
  434. $type = 'flex';
  435. if ( isset( $shortcode_settings['type'] ) ) {
  436. $type = $shortcode_settings['type'];
  437. } else if ( $settings = get_post_meta( $id, 'ml-slider_settings', true ) ) {
  438. if ( is_array( $settings ) && isset( $settings['type'] ) ) {
  439. $type = $settings['type'];
  440. }
  441. }
  442. if ( ! in_array( $type, array( 'flex', 'coin', 'nivo', 'responsive' ) ) ) {
  443. $type = 'flex';
  444. }
  445. $this->slider = $this->load_slider( $type, $id, $shortcode_settings );
  446. }
  447. /**
  448. * Create a new slider based on the sliders type setting
  449. */
  450. private function load_slider( $type, $id, $shortcode_settings ) {
  451. switch ( $type ) {
  452. case( 'coin' ):
  453. return new MetaCoinSlider( $id, $shortcode_settings );
  454. case( 'flex' ):
  455. return new MetaFlexSlider( $id, $shortcode_settings );
  456. case( 'nivo' ):
  457. return new MetaNivoSlider( $id, $shortcode_settings );
  458. case( 'responsive' ):
  459. return new MetaResponsiveSlider( $id, $shortcode_settings );
  460. default:
  461. return new MetaFlexSlider( $id, $shortcode_settings );
  462. }
  463. }
  464. /**
  465. *
  466. */
  467. public function update_slider() {
  468. check_admin_referer( "metaslider_update_slider" );
  469. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  470. if ( ! current_user_can( $capability ) ) {
  471. return;
  472. }
  473. $slider_id = absint( $_POST['slider_id'] );
  474. if ( ! $slider_id ) {
  475. return;
  476. }
  477. // update settings
  478. if ( isset( $_POST['settings'] ) ) {
  479. $new_settings = $_POST['settings'];
  480. $old_settings = get_post_meta( $slider_id, 'ml-slider_settings', true );
  481. // convert submitted checkbox values from 'on' or 'off' to boolean values
  482. $checkboxes = apply_filters( "metaslider_checkbox_settings", array( 'noConflict', 'fullWidth', 'hoverPause', 'links', 'reverse', 'random', 'printCss', 'printJs', 'smoothHeight', 'center', 'carouselMode', 'autoPlay' ) );
  483. foreach ( $checkboxes as $checkbox ) {
  484. if ( isset( $new_settings[$checkbox] ) && $new_settings[$checkbox] == 'on' ) {
  485. $new_settings[$checkbox] = "true";
  486. } else {
  487. $new_settings[$checkbox] = "false";
  488. }
  489. }
  490. $settings = array_merge( (array)$old_settings, $new_settings );
  491. // update the slider settings
  492. update_post_meta( $slider_id, 'ml-slider_settings', $settings );
  493. }
  494. // update slideshow title
  495. if ( isset( $_POST['title'] ) ) {
  496. $slide = array(
  497. 'ID' => $slider_id,
  498. 'post_title' => esc_html( $_POST['title'] )
  499. );
  500. wp_update_post( $slide );
  501. }
  502. // update individual slides
  503. if ( isset( $_POST['attachment'] ) ) {
  504. foreach ( $_POST['attachment'] as $slide_id => $fields ) {
  505. do_action( "metaslider_save_{$fields['type']}_slide", $slide_id, $slider_id, $fields );
  506. }
  507. }
  508. }
  509. /**
  510. * Delete a slide. This doesn't actually remove the slide from WordPress, simply untags
  511. * it from the slide taxonomy.
  512. */
  513. public function delete_slide() {
  514. // check nonce
  515. check_admin_referer( "metaslider_delete_slide" );
  516. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  517. if ( ! current_user_can( $capability ) ) {
  518. return;
  519. }
  520. $slide_id = absint( $_GET['slide_id'] );
  521. $slider_id = absint( $_GET['slider_id'] );
  522. // Get the existing terms and only keep the ones we don't want removed
  523. $new_terms = array();
  524. $current_terms = wp_get_object_terms( $slide_id, 'ml-slider', array( 'fields' => 'ids' ) );
  525. $term = get_term_by( 'name', $slider_id, 'ml-slider' );
  526. foreach ( $current_terms as $current_term ) {
  527. if ( $current_term != $term->term_id ) {
  528. $new_terms[] = absint( $current_term );
  529. }
  530. }
  531. wp_set_object_terms( $slide_id, $new_terms, 'ml-slider' );
  532. wp_redirect( admin_url( "admin.php?page=metaslider&id={$slider_id}" ) );
  533. }
  534. /**
  535. * Delete a slider (send it to trash)
  536. */
  537. public function delete_slider() {
  538. // check nonce
  539. check_admin_referer( "metaslider_delete_slider" );
  540. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  541. if ( ! current_user_can( $capability ) ) {
  542. return;
  543. }
  544. $slider_id = absint( $_GET['slider_id'] );
  545. // send the post to trash
  546. $id = wp_update_post( array(
  547. 'ID' => $slider_id,
  548. 'post_status' => 'trash'
  549. )
  550. );
  551. $slider_id = $this->find_slider( 'modified', 'DESC' );
  552. wp_redirect( admin_url( "admin.php?page=metaslider&id={$slider_id}" ) );
  553. }
  554. /**
  555. *
  556. */
  557. public function switch_view() {
  558. global $user_ID;
  559. $view = $_GET['view'];
  560. $allowed_views = array('tabs', 'dropdown');
  561. if ( ! in_array( $view, $allowed_views ) ) {
  562. return;
  563. }
  564. delete_user_meta( $user_ID, "metaslider_view" );
  565. if ( $view == 'dropdown' ) {
  566. add_user_meta( $user_ID, "metaslider_view", "dropdown");
  567. }
  568. wp_redirect( admin_url( "admin.php?page=metaslider" ) );
  569. }
  570. /**
  571. * Create a new slider
  572. */
  573. public function create_slider() {
  574. // check nonce
  575. check_admin_referer( "metaslider_create_slider" );
  576. $capability = apply_filters( 'metaslider_capability', 'edit_others_posts' );
  577. if ( ! current_user_can( $capability ) ) {
  578. return;
  579. }
  580. $defaults = array();
  581. // if possible, take a copy of the last edited slider settings in place of default settings
  582. if ( $last_modified = $this->find_slider( 'modified', 'DESC' ) ) {
  583. $defaults = get_post_meta( $last_modified, 'ml-slider_settings', true );
  584. }
  585. // insert the post
  586. $id = wp_insert_post( array(
  587. 'post_title' => __( "New Slider", "ml-slider" ),
  588. 'post_status' => 'publish',
  589. 'post_type' => 'ml-slider'
  590. )
  591. );
  592. // use the default settings if we can't find anything more suitable.
  593. if ( empty( $defaults ) ) {
  594. $slider = new MetaSlider( $id, array() );
  595. $defaults = $slider->get_default_parameters();
  596. }
  597. // insert the post meta
  598. add_post_meta( $id, 'ml-slider_settings', $defaults, true );
  599. // create the taxonomy term, the term is the ID of the slider itself
  600. wp_insert_term( $id, 'ml-slider' );
  601. wp_redirect( admin_url( "admin.php?page=metaslider&id={$id}" ) );
  602. }
  603. /**
  604. * Find a single slider ID. For example, last edited, or first published.
  605. *
  606. * @param string $orderby field to order.
  607. * @param string $order direction (ASC or DESC).
  608. * @return int slider ID.
  609. */
  610. private function find_slider( $orderby, $order ) {
  611. $args = array(
  612. 'force_no_custom_order' => true,
  613. 'post_type' => 'ml-slider',
  614. 'num_posts' => 1,
  615. 'post_status' => 'publish',
  616. 'suppress_filters' => 1, // wpml, ignore language filter
  617. 'orderby' => $orderby,
  618. 'order' => $order
  619. );
  620. $the_query = new WP_Query( $args );
  621. while ( $the_query->have_posts() ) {
  622. $the_query->the_post();
  623. return $the_query->post->ID;
  624. }
  625. wp_reset_query();
  626. return false;
  627. }
  628. /**
  629. * Get sliders. Returns a nicely formatted array of currently
  630. * published sliders.
  631. *
  632. * @param string $sort_key
  633. * @return array all published sliders
  634. */
  635. public function all_meta_sliders( $sort_key = 'date' ) {
  636. $sliders = array();
  637. // list the tabs
  638. $args = array(
  639. 'post_type' => 'ml-slider',
  640. 'post_status' => 'publish',
  641. 'orderby' => $sort_key,
  642. 'suppress_filters' => 1, // wpml, ignore language filter
  643. 'order' => 'ASC',
  644. 'posts_per_page' => -1
  645. );
  646. $args = apply_filters( 'metaslider_all_meta_sliders_args', $args );
  647. // WP_Query causes issues with other plugins using admin_footer to insert scripts
  648. // use get_posts instead
  649. $all_sliders = get_posts( $args );
  650. foreach( $all_sliders as $slideshow ) {
  651. $active = $this->slider && ( $this->slider->id == $slideshow->ID ) ? true : false;
  652. $sliders[] = array(
  653. 'active' => $active,
  654. 'title' => $slideshow->post_title,
  655. 'id' => $slideshow->ID
  656. );
  657. }
  658. return $sliders;
  659. }
  660. /**
  661. * Compare array values
  662. *
  663. * @param array $elem1
  664. * @param array $elem2
  665. * @return bool
  666. */
  667. private function compare_elems( $elem1, $elem2 ) {
  668. return $elem1['priority'] > $elem2['priority'];
  669. }
  670. /**
  671. *
  672. * @param array $aFields - array of field to render
  673. * @return string
  674. */
  675. public function build_settings_rows( $aFields ) {
  676. // order the fields by priority
  677. uasort( $aFields, array( $this, "compare_elems" ) );
  678. $return = "";
  679. // loop through the array and build the settings HTML
  680. foreach ( $aFields as $id => $row ) {
  681. // checkbox input type
  682. if ( $row['type'] == 'checkbox' ) {
  683. $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']} />";
  684. if ( isset( $row['after'] ) ) {
  685. $return .= "<span class='after'>{$row['after']}</span>";
  686. }
  687. $return .= "</td></tr>";
  688. }
  689. // navigation row
  690. if ( $row['type'] == 'navigation' ) {
  691. $navigation_row = "<tr class='{$row['type']}'><td class='tipsy-tooltip' title=\"{$row['helptext']}\">{$row['label']}</td><td><ul>";
  692. foreach ( $row['options'] as $k => $v ) {
  693. if ( $row['value'] === true && $k === 'true' ) {
  694. $checked = checked( true, true, false );
  695. } else if ( $row['value'] === false && $k === 'false' ) {
  696. $checked = checked( true, true, false );
  697. } else {
  698. $checked = checked( $k, $row['value'], false );
  699. }
  700. $disabled = $k == 'thumbnails' ? 'disabled' : '';
  701. $navigation_row .= "<li><label><input type='radio' name='settings[{$id}]' value='{$k}' {$checked} {$disabled}/>{$v['label']}</label></li>";
  702. }
  703. $navigation_row .= "</ul></td></tr>";
  704. $return .= apply_filters( 'metaslider_navigation_options', $navigation_row, $this->slider );
  705. }
  706. // navigation row
  707. if ( $row['type'] == 'radio' ) {
  708. $navigation_row = "<tr class='{$row['type']}'><td class='tipsy-tooltip' title=\"{$row['helptext']}\">{$row['label']}</td><td><ul>";
  709. foreach ( $row['options'] as $k => $v ) {
  710. $checked = checked( $k, $row['value'], false );
  711. $class = isset( $v['class'] ) ? $v['class'] : "";
  712. $navigation_row .= "<li><label><input type='radio' name='settings[{$id}]' value='{$k}' {$checked} class='radio {$class}'/>{$v['label']}</label></li>";
  713. }
  714. $navigation_row .= "</ul></td></tr>";
  715. $return .= apply_filters( 'metaslider_navigation_options', $navigation_row, $this->slider );
  716. }
  717. // header/divider row
  718. if ( $row['type'] == 'divider' ) {
  719. $return .= "<tr class='{$row['type']}'><td colspan='2' class='divider'><b>{$row['value']}</b></td></tr>";
  720. }
  721. // slideshow select row
  722. if ( $row['type'] == 'slider-lib' ) {
  723. $return .= "<tr class='{$row['type']}'><td colspan='2' class='slider-lib-row'>";
  724. foreach ( $row['options'] as $k => $v ) {
  725. $checked = checked( $k, $row['value'], false );
  726. $return .= "<input class='select-slider' id='{$k}' rel='{$k}' type='radio' name='settings[type]' value='{$k}' {$checked} />
  727. <label for='{$k}'>{$v['label']}</label>";
  728. }
  729. $return .= "</td></tr>";
  730. }
  731. // number input type
  732. if ( $row['type'] == 'number' ) {
  733. $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>";
  734. }
  735. // select drop down
  736. if ( $row['type'] == 'select' ) {
  737. $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}]'>";
  738. foreach ( $row['options'] as $k => $v ) {
  739. $selected = selected( $k, $row['value'], false );
  740. $return .= "<option class='{$v['class']}' value='{$k}' {$selected}>{$v['label']}</option>";
  741. }
  742. $return .= "</select></td></tr>";
  743. }
  744. // theme drop down
  745. if ( $row['type'] == 'theme' ) {
  746. $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}]'>";
  747. $themes = "";
  748. foreach ( $row['options'] as $k => $v ) {
  749. $selected = selected( $k, $row['value'], false );
  750. $themes .= "<option class='{$v['class']}' value='{$k}' {$selected}>{$v['label']}</option>";
  751. }
  752. $return .= apply_filters( 'metaslider_get_available_themes', $themes, $this->slider->get_setting( 'theme' ) );
  753. $return .= "</select></td></tr>";
  754. }
  755. // text input type
  756. if ( $row['type'] == 'text' ) {
  757. $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>";
  758. }
  759. // text input type
  760. if ( $row['type'] == 'textarea' ) {
  761. $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>";
  762. }
  763. // text input type
  764. if ( $row['type'] == 'title' ) {
  765. $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>";
  766. }
  767. }
  768. return $return;
  769. }
  770. /**
  771. * Return an indexed array of all easing options
  772. *
  773. * @return array
  774. */
  775. private function get_easing_options() {
  776. $options = array(
  777. 'linear', 'swing', 'jswing', 'easeInQuad', 'easeOutQuad', 'easeInOutQuad',
  778. 'easeInCubic', 'easeOutCubic', 'easeInOutCubic', 'easeInQuart',
  779. 'easeOutQuart', 'easeInOutQuart', 'easeInQuint', 'easeOutQuint',
  780. 'easeInOutQuint', 'easeInSine', 'easeOutSine', 'easeInOutSine',
  781. 'easeInExpo', 'easeOutExpo', 'easeInOutExpo', 'easeInCirc', 'easeOutCirc',
  782. 'easeInOutCirc', 'easeInElastic', 'easeOutElastic', 'easeInOutElastic',
  783. 'easeInBack', 'easeOutBack', 'easeInOutBack', 'easeInBounce', 'easeOutBounce',
  784. 'easeInOutBounce'
  785. );
  786. foreach ( $options as $option ) {
  787. $return[$option] = array(
  788. 'label' => ucfirst( preg_replace( '/(\w+)([A-Z])/U', '\\1 \\2', $option ) ),
  789. 'class' => ''
  790. );
  791. }
  792. return $return;
  793. }
  794. /**
  795. * Output the slideshow selector.
  796. *
  797. * Show tabs or a dropdown list depending on the users saved preference.
  798. */
  799. public function print_slideshow_selector() {
  800. global $user_ID;
  801. $add_url = wp_nonce_url( admin_url( "admin-post.php?action=metaslider_create_slider" ), "metaslider_create_slider" );
  802. if ( $tabs = $this->all_meta_sliders() ) {
  803. if ( $this->get_view() == 'tabs' ) {
  804. echo "<div style='display: none;' id='screen-options-switch-view-wrap'>
  805. <a class='switchview dashicons-before dashicons-randomize tipsy-tooltip' title='" . __("Switch to Dropdown view", "ml-slider") . "' href='" . admin_url( "admin-post.php?action=metaslider_switch_view&view=dropdown") . "'>" . __("Dropdown", "ml-slider") . "</a></div>";
  806. echo "<h3 class='nav-tab-wrapper'>";
  807. foreach ( $tabs as $tab ) {
  808. if ( $tab['active'] ) {
  809. echo "<div class='nav-tab nav-tab-active'><input type='text' name='title' value='" . esc_attr( $tab['title'] ) . "' onfocus='this.style.width = ((this.value.length + 1) * 9) + \"px\"' /></div>";
  810. } else {
  811. echo "<a href='?page=metaslider&amp;id={$tab['id']}' class='nav-tab'>" . esc_html( $tab['title'] ) . "</a>";
  812. }
  813. }
  814. echo "<a href='{$add_url}' id='create_new_tab' class='nav-tab'>+</a>";
  815. echo "</h3>";
  816. } else {
  817. if ( isset( $_GET['add'] ) && $_GET['add'] == 'true' ) {
  818. echo "<div id='message' class='updated'><p>" . __( "New slideshow created. Click 'Add Slide' to get started!", "ml-slider" ) . "</p></div>";
  819. }
  820. echo "<div style='display: none;' id='screen-options-switch-view-wrap'><a class='switchview dashicons-before dashicons-randomize tipsy-tooltip' title='" . __("Switch to Tab view", "ml-slider") . "' href='" . admin_url( "admin-post.php?action=metaslider_switch_view&view=tabs") . "'>" . __("Tabs", "ml-slider") . "</a></div>";
  821. echo "<div class='dropdown_container'><label for='select-slider'>" . __("Select Slider", "ml-slider") . ": </label>";
  822. echo "<select name='select-slider' onchange='if (this.value) window.location.href=this.value'>";
  823. $tabs = $this->all_meta_sliders( 'title' );
  824. foreach ( $tabs as $tab ) {
  825. $selected = $tab['active'] ? " selected" : "";
  826. if ( $tab['active'] ) {
  827. $title = $tab['title'];
  828. }
  829. echo "<option value='?page=metaslider&amp;id={$tab['id']}'{$selected}>{$tab['title']}</option>";
  830. }
  831. echo "</select> " . __( 'or', "ml-slider" ) . " ";
  832. echo "<a href='{$add_url}'>" . __( 'Add New Slideshow', "ml-slider" ) . "</a></div>";
  833. }
  834. } else {
  835. echo "<h3 class='nav-tab-wrapper'>";
  836. echo "<a href='{$add_url}' id='create_new_tab' class='nav-tab'>+</a>";
  837. echo "<div class='bubble'>" . __( "Create your first slideshow", "ml-slider" ) . "</div>";
  838. echo "</h3>";
  839. }
  840. }
  841. /**
  842. * Return the users saved view preference.
  843. */
  844. public function get_view() {
  845. global $user_ID;
  846. if ( get_user_meta( $user_ID, "metaslider_view", true ) ) {
  847. return get_user_meta( $user_ID, "metaslider_view", true );
  848. }
  849. return 'tabs';
  850. }
  851. /**
  852. * Render the admin page (tabs, slides, settings)
  853. */
  854. public function render_admin_page() {
  855. // default to the latest slider
  856. $slider_id = $this->find_slider( 'modified', 'DESC' );
  857. // load a slider by ID
  858. if ( isset( $_REQUEST['id'] ) ) {
  859. $temp_id = absint( $_REQUEST['id'] );
  860. // check valid post ID
  861. if ( get_post( $temp_id ) ) {
  862. $slider_id = $temp_id;
  863. }
  864. }
  865. // finally, set the slider
  866. if ( $slider_id > 0 ) {
  867. $this->set_slider( $slider_id );
  868. }
  869. $this->upgrade_to_pro_cta();
  870. $this->do_system_check();
  871. $slider_id = $this->slider ? $this->slider->id : 0;
  872. ?>
  873. <script type='text/javascript'>
  874. var metaslider_slider_id = <?php echo $slider_id; ?>;
  875. </script>
  876. <div class="wrap metaslider">
  877. <form accept-charset="UTF-8" action="<?php echo admin_url( 'admin-post.php'); ?>" method="post">
  878. <input type="hidden" name="action" value="metaslider_update_slider">
  879. <input type="hidden" name="slider_id" value="<?php echo $slider_id; ?>">
  880. <?php wp_nonce_field( 'metaslider_update_slider' ); ?>
  881. <?php $this->print_slideshow_selector(); ?>
  882. <?php if ( ! $this->slider ) return; ?>
  883. <div id='poststuff'>
  884. <div id='post-body' class='metabox-holder columns-2'>
  885. <div id='post-body-content'>
  886. <div class="left">
  887. <?php do_action( "metaslider_admin_table_before", $this->slider->id ); ?>
  888. <table class="widefat sortable">
  889. <thead>
  890. <tr>
  891. <th style="width: 100px;">
  892. <h3><?php _e( "Slides", "ml-slider" ) ?></h3>
  893. <?php do_action( "metaslider_admin_table_header_left", $this->slider->id ); ?>
  894. </th>
  895. <th>
  896. <a href='#' class='button alignright add-slide' data-editor='content' title='<?php _e( "Add Slide", "ml-slider" ) ?>'>
  897. <span class='wp-media-buttons-icon'></span> <?php _e( "Add Slide", "ml-slider" ) ?>
  898. </a>
  899. <?php do_action( "metaslider_admin_table_header_right", $this->slider->id ); ?>
  900. </th>
  901. </tr>
  902. </thead>
  903. <tbody>
  904. <?php
  905. $this->slider->render_admin_slides();
  906. ?>
  907. </tbody>
  908. </table>
  909. <?php do_action( "metaslider_admin_table_after", $this->slider->id ); ?>
  910. </div>
  911. </div>
  912. <div id="postbox-container-1" class="postbox-container">
  913. <div class='right'>
  914. <div class="ms-postbox" id="metaslider_configuration">
  915. <div class='configuration'>
  916. <input class='alignright button button-primary' type='submit' name='save' id='ms-save' value='<?php _e( "Save", "ml-slider" ) ?>' />
  917. <input class='alignright button button-primary' type='submit' name='preview' id='ms-preview' value='<?php _e( "Save & Preview", "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' ) ?>' />
  918. <span class="spinner"></span>
  919. </div>
  920. <div class="inside">
  921. <table class="settings">
  922. <tbody>
  923. <?php
  924. $aFields = array(
  925. 'type' => array(
  926. 'priority' => 0,
  927. 'type' => 'slider-lib',
  928. 'value' => $this->slider->get_setting( 'type' ),
  929. 'options' => array(
  930. 'flex' => array( 'label' => __( "Flex Slider", "ml-slider" ) ),
  931. 'responsive' => array( 'label' => __( "R. Slides", "ml-slider" ) ),
  932. 'nivo' => array( 'label' => __( "Nivo Slider", "ml-slider" ) ),
  933. 'coin' => array( 'label' => __( "Coin Slider", "ml-slider" ) )
  934. )
  935. ),
  936. 'width' => array(
  937. 'priority' => 10,
  938. 'type' => 'number',
  939. 'size' => 3,
  940. 'min' => 0,
  941. 'max' => 9999,
  942. 'step' => 1,
  943. 'value' => $this->slider->get_setting( 'width' ),
  944. 'label' => __( "Width", "ml-slider" ),
  945. 'class' => 'coin flex responsive nivo',
  946. 'helptext' => __( "Slideshow width", "ml-slider" ),
  947. 'after' => __( "px", "ml-slider" )
  948. ),
  949. 'height' => array(
  950. 'priority' => 20,
  951. 'type' => 'number',
  952. 'size' => 3,
  953. 'min' => 0,
  954. 'max' => 9999,
  955. 'step' => 1,
  956. 'value' => $this->slider->get_setting( 'height' ),
  957. 'label' => __( "Height", "ml-slider" ),
  958. 'class' => 'coin flex responsive nivo',
  959. 'helptext' => __( "Slideshow height", "ml-slider" ),
  960. 'after' => __( "px", "ml-slider" )
  961. ),
  962. 'effect' => array(
  963. 'priority' => 30,
  964. 'type' => 'select',
  965. 'value' => $this->slider->get_setting( 'effect' ),
  966. 'label' => __( "Effect", "ml-slider" ),
  967. 'class' => 'effect coin flex responsive nivo',
  968. 'helptext' => __( "Slide transition effect", "ml-slider" ),
  969. 'options' => array(
  970. 'random' => array( 'class' => 'option coin nivo' , 'label' => __( "Random", "ml-slider" ) ),
  971. 'swirl' => array( 'class' => 'option coin', 'label' => __( "Swirl",