PageRenderTime 58ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-contentold/plugins/simple-lightbox/model.php

https://bitbucket.org/zachisit/zachis.it-m
PHP | 1483 lines | 954 code | 125 blank | 404 comment | 141 complexity | a1b849a11d1e305653c5dfb319a19c75 MD5 | raw file
  1. <?php
  2. require_once 'includes/class.base.php';
  3. require_once 'includes/class.options.php';
  4. /**
  5. * Lightbox functionality class
  6. * @package Simple Lightbox
  7. * @author Archetyped
  8. */
  9. class SLB_Lightbox extends SLB_Base {
  10. /*-** Properties **-*/
  11. /**
  12. * Themes
  13. * @var array
  14. */
  15. var $themes = array();
  16. var $theme_default = 'default';
  17. /**
  18. * Page that plugin options are on
  19. * @var string
  20. */
  21. var $options_admin_page = 'options-media.php';
  22. /**
  23. * Page that processes options
  24. * @var string
  25. */
  26. var $options_admin_form = 'options.php';
  27. /**
  28. * Value to identify activated links
  29. * Formatted on initialization
  30. * @var string
  31. */
  32. var $attr = null;
  33. /**
  34. * Legacy attribute (for backwards compatibility)
  35. * @var string
  36. */
  37. var $attr_legacy = 'lightbox';
  38. /**
  39. * Properties for media attachments in current request
  40. * > Key (string) Attachment URI
  41. * > Value (assoc-array) Attachment properties (url, etc.)
  42. * > source: Source URL
  43. * @var array
  44. */
  45. var $media_attachments = array();
  46. /**
  47. * Raw media items
  48. * Used for populating media object on client-side
  49. * > Key: Item URI
  50. * > Value: Associative array of media properties
  51. * > type: Item type (Default: null)
  52. * > id: Item ID (Default: null)
  53. * @var array
  54. */
  55. var $media_items_raw = array();
  56. /**
  57. * Media types
  58. * @var array
  59. */
  60. var $media_types = array('img' => 'image', 'att' => 'attachment');
  61. /* Widget properties */
  62. /**
  63. * Widget callback key
  64. * @var string
  65. */
  66. var $widget_callback = 'callback';
  67. /**
  68. * Key to use to store original callback
  69. * @var string
  70. */
  71. var $widget_callback_orig = 'callback_orig';
  72. /**
  73. * Used to track if widget is currently being processed or not
  74. * @var bool
  75. */
  76. var $widget_processing = false;
  77. /* Instance members */
  78. /**
  79. * Options instance
  80. * @var SLB_Options
  81. */
  82. var $options = null;
  83. /**
  84. * Base field definitions
  85. * Stores system/user-defined field definitions
  86. * @var SLB_Fields
  87. */
  88. var $fields = null;
  89. var $h_temp = array();
  90. /* Constructor */
  91. function SLB_Lightbox() {
  92. $this->__construct();
  93. }
  94. function __construct() {
  95. parent::__construct();
  96. $this->init();
  97. //Init objects
  98. $this->attr = $this->get_prefix();
  99. $this->fields = new SLB_Fields();
  100. }
  101. /* Init */
  102. function init_env() {
  103. //Localization
  104. $ldir = 'l10n';
  105. $lpath = $this->util->get_plugin_file_path($ldir, array(false, false));
  106. $lpath_abs = $this->util->get_file_path($ldir);
  107. if ( is_dir($lpath_abs) ) {
  108. load_plugin_textdomain($this->util->get_plugin_textdomain(), false, $lpath);
  109. }
  110. //Options
  111. $func_opts = 'init_options';
  112. if ( isset($this) && method_exists($this, $func_opts) ) {
  113. call_user_func($this->m($func_opts));
  114. }
  115. //Context
  116. $func_context = $this->m('set_client_context');
  117. $hook_context = ( is_admin() ) ? 'admin_head' : 'wp_head';
  118. add_action($hook_context, $func_context);
  119. }
  120. /**
  121. * Init options
  122. */
  123. function init_options() {
  124. //Setup options
  125. $p = $this->util->get_plugin_base(true);
  126. $options_config = array (
  127. 'groups' => array (
  128. 'activation' => __('Activation', $p),
  129. 'grouping' => __('Grouping', $p),
  130. 'ui' => __('UI', $p),
  131. 'labels' => __('Labels', $p)
  132. ),
  133. 'items' => array (
  134. 'enabled' => array('title' => __('Enable Lightbox Functionality', $p), 'default' => true, 'group' => 'activation'),
  135. 'enabled_home' => array('title' => __('Enable on Home page', $p), 'default' => true, 'group' => 'activation'),
  136. 'enabled_post' => array('title' => __('Enable on Posts', $p), 'default' => true, 'group' => 'activation'),
  137. 'enabled_page' => array('title' => __('Enable on Pages', $p), 'default' => true, 'group' => 'activation'),
  138. 'enabled_archive' => array('title' => __('Enable on Archive Pages (tags, categories, etc.)', $p), 'default' => true, 'group' => 'activation'),
  139. 'enabled_widget' => array('title' => __('Enable for Widgets', $p), 'default' => false, 'group' => 'activation'),
  140. 'enabled_compat' => array('title' => __('Enable backwards-compatibility with legacy lightbox links', $p), 'default' => false, 'group' => 'activation'),
  141. 'activate_attachments' => array('title' => __('Activate image attachment links', $p), 'default' => true, 'group' => 'activation'),
  142. 'validate_links' => array('title' => __('Validate links', $p), 'default' => false, 'group' => 'activation'),
  143. 'group_links' => array('title' => __('Group image links (for displaying as a slideshow)', $p), 'default' => true, 'group' => 'grouping'),
  144. 'group_post' => array('title' => __('Group image links by Post (e.g. on pages with multiple posts)', $p), 'default' => true, 'group' => 'grouping'),
  145. 'group_gallery' => array('title' => __('Group gallery links separately', $p), 'default' => false, 'group' => 'grouping'),
  146. 'group_widget' => array('title' => __('Group widget links separately', $p), 'default' => false, 'group' => 'grouping'),
  147. 'theme' => array('title' => __('Theme', $p), 'default' => 'default', 'group' => 'ui', 'parent' => 'option_theme'),
  148. 'animate' => array('title' => __('Animate lightbox resizing', $p), 'default' => true, 'group' => 'ui'),
  149. 'autostart' => array('title' => __('Automatically Start Slideshow', $p), 'default' => true, 'group' => 'ui'),
  150. 'duration' => array('title' => __('Slide Duration (Seconds)', $p), 'default' => '6', 'attr' => array('size' => 3, 'maxlength' => 3), 'group' => 'ui'),
  151. 'loop' => array('title' => __('Loop through images', $p), 'default' => true, 'group' => 'ui'),
  152. 'overlay_opacity' => array('title' => __('Overlay Opacity (0 - 1)', $p), 'default' => '0.8', 'attr' => array('size' => 3, 'maxlength' => 3), 'group' => 'ui'),
  153. 'enabled_caption' => array('title' => __('Enable caption', $p), 'default' => true, 'group' => 'ui'),
  154. 'caption_src' => array('title' => __('Use image URI as caption when link title not set', $p), 'default' => true, 'group' => 'ui'),
  155. 'enabled_desc' => array('title' => __('Enable description', $p), 'default' => true, 'group' => 'ui'),
  156. 'txt_closeLink' => array('title' => __('Close link (for accessibility only, image used for button)', $p), 'default' => 'close', 'group' => 'labels'),
  157. 'txt_loadingMsg' => array('title' => __('Loading indicator', $p), 'default' => 'loading', 'group' => 'labels'),
  158. 'txt_nextLink' => array('title' => __('Next Image link', $p), 'default' => 'next &raquo;', 'group' => 'labels'),
  159. 'txt_prevLink' => array('title' => __('Previous Image link', $p), 'default' => '&laquo; prev', 'group' => 'labels'),
  160. 'txt_startSlideshow' => array('title' => __('Start Slideshow link', $p), 'default' => 'start slideshow', 'group' => 'labels'),
  161. 'txt_stopSlideshow' => array('title' => __('Stop Slideshow link', $p), 'default' => 'stop slideshow', 'group' => 'labels'),
  162. 'txt_numDisplayPrefix' => array('title' => __('Image number prefix (e.g. <strong>Image</strong> x of y)', $p), 'default' => 'Image', 'group' => 'labels'),
  163. 'txt_numDisplaySeparator' => array('title' => __('Image number separator (e.g. Image x <strong>of</strong> y)', $p), 'default' => 'of', 'group' => 'labels')
  164. ),
  165. 'legacy' => array (
  166. 'header_activation' => null,
  167. 'header_enabled' => null,
  168. 'header_strings' => null,
  169. 'header_ui' => null,
  170. 'enabled_single' => array('enabled_post', 'enabled_page')
  171. )
  172. );
  173. $opt_theme =& $options_config['items']['theme'];
  174. $opt_theme['default'] = $this->theme_default = $this->add_prefix($this->theme_default);
  175. $opt_theme['options'] = $this->m('get_theme_options');
  176. $this->options = new SLB_Options($options_config);
  177. }
  178. function register_hooks() {
  179. parent::register_hooks();
  180. /* Admin */
  181. //Init lightbox admin
  182. add_action('admin_init', $this->m('admin_settings'));
  183. //Enqueue header files (CSS/JS)
  184. add_action('admin_enqueue_scripts', $this->m('admin_enqueue_files'));
  185. //Reset Settings
  186. add_action('admin_action_' . $this->add_prefix('reset'), $this->m('admin_reset'));
  187. add_action('admin_notices', $this->m('admin_notices'));
  188. //Plugin listing
  189. add_filter('plugin_action_links_' . $this->util->get_plugin_base_name(), $this->m('admin_plugin_action_links'), 10, 4);
  190. add_action('in_plugin_update_message-' . $this->util->get_plugin_base_name(), $this->m('admin_plugin_update_message'), 10, 2);
  191. add_filter('site_transient_update_plugins', $this->m('admin_plugin_update_transient'));
  192. /* Client-side */
  193. //Init lightbox
  194. $priority = 99;
  195. add_action('wp_enqueue_scripts', $this->m('enqueue_files'));
  196. add_action('wp_head', $this->m('client_init'));
  197. add_action('wp_footer', $this->m('client_footer'), $priority);
  198. //Link activation
  199. add_filter('the_content', $this->m('activate_links'), $priority);
  200. //Gallery wrapping
  201. add_filter('the_content', $this->m('gallery_wrap'), 1);
  202. add_filter('the_content', $this->m('gallery_unwrap'), $priority + 1);
  203. /* Themes */
  204. $this->util->add_action('init_themes', $this->m('init_default_themes'));
  205. /* Widgets */
  206. add_filter('sidebars_widgets', $this->m('sidebars_widgets'));
  207. }
  208. /* Methods */
  209. /*-** Request **-*/
  210. /**
  211. * Output current context to client-side
  212. * @uses `wp_head` action as hook
  213. * @uses `admin_head` action as hook
  214. * @return void
  215. */
  216. function set_client_context() {
  217. if ( !$this->is_enabled() )
  218. return false;
  219. $ctx = new stdClass();
  220. $ctx->context = $this->util->get_context();
  221. echo $this->util->build_script_element($this->util->extend_client_object($ctx), 'context');
  222. }
  223. /*-** Helpers **-*/
  224. /**
  225. * Checks whether lightbox is currently enabled/disabled
  226. * @return bool TRUE if lightbox is currently enabled, FALSE otherwise
  227. */
  228. function is_enabled($check_request = true) {
  229. $ret = ( $this->options->get_bool('enabled') && !is_feed() && !is_admin() ) ? true : false;
  230. if ( $ret && $check_request ) {
  231. $opt = '';
  232. //Determine option to check
  233. if ( is_home() )
  234. $opt = 'home';
  235. elseif ( is_singular() ) {
  236. $opt = ( is_page() ) ? 'page' : 'post';
  237. }
  238. elseif ( is_archive() || is_search() )
  239. $opt = 'archive';
  240. //Check option
  241. if ( !empty($opt) && ( $opt = 'enabled_' . $opt ) && $this->options->has($opt) ) {
  242. $ret = $this->options->get_bool($opt);
  243. }
  244. }
  245. return $ret;
  246. }
  247. /*-** Widgets **-*/
  248. /**
  249. * Reroute widget display handlers to internal method
  250. * @param array $sidebar_widgets List of sidebars & their widgets
  251. * @uses WP Hook `sidebars_widgets` to intercept widget list
  252. * @global $wp_registered_widgets to reroute display callback
  253. * @return array Sidebars and widgets (unmodified)
  254. */
  255. function sidebars_widgets($sidebars_widgets) {
  256. global $wp_registered_widgets;
  257. static $widgets_processed = false;
  258. if ( is_admin() || empty($wp_registered_widgets) || $widgets_processed || !is_object($this->options) || !$this->is_enabled() || !$this->options->get_bool('enabled_widget') )
  259. return $sidebars_widgets;
  260. $widgets_processed = true;
  261. //Fetch active widgets from all sidebars
  262. foreach ( $sidebars_widgets as $sb => $ws ) {
  263. //Skip inactive widgets and empty sidebars
  264. if ( 'wp_inactive_widgets' == $sb || empty($ws) || !is_array($ws) )
  265. continue;
  266. foreach ( $ws as $w ) {
  267. if ( isset($wp_registered_widgets[$w]) && isset($wp_registered_widgets[$w][$this->widget_callback]) ) {
  268. $wref =& $wp_registered_widgets[$w];
  269. //Backup original callback
  270. $wref[$this->widget_callback_orig] = $wref[$this->widget_callback];
  271. //Reroute callback
  272. $wref[$this->widget_callback] = $this->m('widget_callback');
  273. unset($wref);
  274. }
  275. }
  276. }
  277. return $sidebars_widgets;
  278. }
  279. /**
  280. * Widget display handler
  281. * Original widget display handler is called inside of an output buffer & links in output are processed before sending to browser
  282. * @param array $args Widget instance properties
  283. * @param int (optional) $widget_args Additional widget args (usually the widget's instance number)
  284. * @see WP_Widget::display_callback() for more information
  285. * @see sidebars_widgets() for callback modification
  286. * @global $wp_registered_widgets
  287. * @uses widget_process_links() to Process links in widget content
  288. * @return void
  289. */
  290. function widget_callback($args, $widget_args = 1) {
  291. global $wp_registered_widgets;
  292. $wid = ( isset($args['widget_id']) ) ? $args['widget_id'] : false;
  293. //Stop processing if widget data invalid
  294. if ( !$wid || !isset($wp_registered_widgets[$wid]) || !($w =& $wp_registered_widgets[$wid]) || !isset($w['id']) || $wid != $w['id'] )
  295. return false;
  296. //Get original callback
  297. if ( !isset($w[$this->widget_callback_orig]) || !($cb = $w[$this->widget_callback_orig]) || !is_callable($cb) )
  298. return false;
  299. $params = func_get_args();
  300. $this->widget_processing = true;
  301. //Start output buffer
  302. ob_start();
  303. //Call original callback
  304. call_user_func_array($cb, $params);
  305. //Flush output buffer
  306. echo $this->widget_process_links(ob_get_clean(), $wid);
  307. $this->widget_processing = false;
  308. }
  309. /**
  310. * Process links in widget content
  311. * @param string $content Widget content
  312. * @return string Processed widget content
  313. * @uses process_links() to process links
  314. */
  315. function widget_process_links($content, $id) {
  316. $id = ( $this->options->get_bool('group_widget') ) ? "widget_$id" : null;
  317. return $this->process_links($content, $id);
  318. }
  319. /*-** Theme **-*/
  320. /**
  321. * Retrieve themes
  322. * @uses do_action() Calls 'slb_init_themes' hook to allow plugins to register themes
  323. * @uses $themes to return registered themes
  324. * @return array Retrieved themes
  325. */
  326. function get_themes() {
  327. static $fetched = false;
  328. if ( !$fetched ) {
  329. $this->themes = array();
  330. $this->util->do_action('init_themes');
  331. $fetched = true;
  332. }
  333. return $this->themes;
  334. }
  335. /**
  336. * Retrieve theme
  337. * @param string $name Name of theme to retrieve
  338. * @uses theme_exists() to check for existence of theme
  339. * @return array Theme data
  340. */
  341. function get_theme($name = '') {
  342. $name = strval($name);
  343. //Default: Get current theme if no theme specified
  344. if ( empty($name) ) {
  345. $name = $this->options->get_value('theme');
  346. }
  347. if ( !$this->theme_exists($name) )
  348. $name = $this->theme_default;
  349. return $this->themes[$name];
  350. }
  351. /**
  352. * Retrieve specific of theme data
  353. * @uses get_theme() to retrieve theme data
  354. * @param string $name Theme name
  355. * @param string $field Theme field to retrieve
  356. * @return mixed Field data
  357. */
  358. function get_theme_data($name = '', $field) {
  359. $theme = $this->get_theme($name);
  360. return ( isset($theme[$field]) ) ? $theme[$field] : '';
  361. }
  362. /**
  363. * Retrieve theme stylesheet URL
  364. * @param string $name Theme name
  365. * @uses get_theme_data() to retrieve theme data
  366. * @return string Stylesheet URL
  367. */
  368. function get_theme_style($name = '') {
  369. return $this->get_theme_data($name, 'stylesheet_url');
  370. }
  371. /**
  372. * Retrieve theme layout
  373. * @uses get_theme_data() to retrieve theme data
  374. * @param string $name Theme name
  375. * @param bool $filter (optional) Filter layout based on user preferences
  376. * @return string Theme layout HTML
  377. */
  378. function get_theme_layout($name = '', $filter = true) {
  379. $l = $this->get_theme_data($name, 'layout');
  380. //Filter
  381. if ( !$this->options->get_bool('enabled_caption') )
  382. $l = str_replace($this->get_theme_placeholder('dataCaption'), '', $l);
  383. if ( !$this->options->get_bool('enabled_desc') )
  384. $l = str_replace($this->get_theme_placeholder('dataDescription'), '', $l);
  385. return $l;
  386. }
  387. /**
  388. * Check whether a theme exists
  389. * @param string $name Theme to look for
  390. * @uses get_themes() to intialize themes if not already performed
  391. * @return bool TRUE if theme exists, FALSE otherwise
  392. */
  393. function theme_exists($name) {
  394. $this->get_themes();
  395. return ( isset($this->themes[trim(strval($name))]) );
  396. }
  397. /**
  398. * Register lightbox theme
  399. * @param string $name Unique theme name
  400. * @param string $title Display name for theme
  401. * @param string $stylesheet_url URL to stylesheet
  402. * @param string $layout Layout HTML
  403. * @uses $themes to store the registered theme
  404. */
  405. function register_theme($name, $title, $stylesheet_url, $layout) {
  406. if ( !is_array($this->themes) ) {
  407. $this->themes = array();
  408. }
  409. //Validate parameters
  410. $name = trim(strval($name));
  411. $title = trim(strval($title));
  412. $stylesheet_url = trim(strval($stylesheet_url));
  413. $layout = $this->format_theme_layout($layout);
  414. $defaults = array(
  415. 'name' => '',
  416. 'title' => '',
  417. 'stylesheet_url' => '',
  418. 'layout' => ''
  419. );
  420. //Add theme to array
  421. $this->themes[$name] = wp_parse_args(compact(array_keys($defaults), $defaults));
  422. }
  423. /**
  424. * Build theme placeholder
  425. * @param string $name Placeholder name
  426. * @return string Placeholder
  427. */
  428. function get_theme_placeholder($name) {
  429. return '{' . $name . '}';
  430. }
  431. /**
  432. * Formats layout for usage in JS
  433. * @param string $layout Layout to format
  434. * @return string Formatted layout
  435. */
  436. function format_theme_layout($layout = '') {
  437. //Remove line breaks
  438. $layout = str_replace(array("\r\n", "\n", "\r", "\t"), '', $layout);
  439. //Escape quotes
  440. $layout = str_replace("'", "\'", $layout);
  441. //Return
  442. return "'" . $layout . "'";
  443. }
  444. /**
  445. * Add default themes
  446. * @uses register_theme() to register the theme(s)
  447. */
  448. function init_default_themes() {
  449. $name = $this->theme_default;
  450. $title = 'Default';
  451. $stylesheet_url = $this->util->get_file_url('css/lightbox.css');
  452. $layout = file_get_contents($this->util->normalize_path($this->util->get_path_base(), 'templates', 'default', 'layout.html'));
  453. $this->register_theme($name, $title, $stylesheet_url, $layout);
  454. //Testing: Additional themes
  455. $this->register_theme('black', 'Black', $this->util->get_file_url('css/lb_black.css'), $layout);
  456. }
  457. /*-** Frontend **-*/
  458. /**
  459. * Builds wrapper for grouping
  460. * @return object Wrapper properties
  461. * > open
  462. * > close
  463. */
  464. function group_get_wrapper() {
  465. static $wrapper = null;
  466. if ( is_null($wrapper) ) {
  467. $start = '<';
  468. $end = '>';
  469. $terminate = '/';
  470. $val = $this->add_prefix('group');
  471. //Build properties
  472. $wrapper = array(
  473. 'open' => $start . $val . $end,
  474. 'close' => $start . $terminate . $val . $end
  475. );
  476. //Convert to object
  477. $wrapper = (object) $wrapper;
  478. }
  479. return $wrapper;
  480. }
  481. /**
  482. * Wraps galleries for grouping
  483. * @uses `the_content` Filter hook
  484. * @uses gallery_wrap_callback to Wrap shortcodes for grouping
  485. * @param string $content Post content
  486. * @return string Modified post content
  487. */
  488. function gallery_wrap($content) {
  489. if ( !$this->is_enabled() )
  490. return $content;
  491. //Stop processing if option not enabled
  492. if ( !$this->options->get_bool('group_gallery') )
  493. return $content;
  494. global $shortcode_tags;
  495. //Save default shortcode handlers to temp variable
  496. $sc_temp = $shortcode_tags;
  497. //Find gallery shortcodes
  498. $shortcodes = array('gallery', 'nggallery');
  499. $m = $this->m('gallery_wrap_callback');
  500. $shortcode_tags = array();
  501. foreach ( $shortcodes as $tag ) {
  502. $shortcode_tags[$tag] = $m;
  503. }
  504. //Wrap gallery shortcodes
  505. $content = do_shortcode($content);
  506. //Restore default shortcode handlers
  507. $shortcode_tags = $sc_temp;
  508. return $content;
  509. }
  510. /**
  511. * Wraps gallery shortcodes for later processing
  512. * @param array $attr Shortcode attributes
  513. * @param string $content Content enclosed in shortcode
  514. * @param string $tag Shortcode name
  515. * @return string Wrapped gallery shortcode
  516. */
  517. function gallery_wrap_callback($attr, $content = null, $tag) {
  518. //Rebuild shortcode
  519. $sc = '[' . $tag . ' ' . $this->util->build_attribute_string($attr) . ']';
  520. if ( !empty($content) )
  521. $sc .= $content . '[/' . $tag .']';
  522. //Wrap shortcode
  523. $w = $this->group_get_wrapper();
  524. $sc = $w->open . $sc . $w->close;
  525. return $sc;
  526. }
  527. /**
  528. * Removes wrapping from galleries
  529. * @uses `the_content` filter hook
  530. * @param $content Post content
  531. * @return string Modified post content
  532. */
  533. function gallery_unwrap($content) {
  534. if ( !$this->is_enabled() )
  535. return $content;
  536. //Stop processing if option not enabled
  537. if ( !$this->options->get_bool('group_gallery') )
  538. return $content;
  539. $w = $this->group_get_wrapper();
  540. if ( strpos($content, $w->open) !== false ) {
  541. $content = str_replace($w->open, '', $content);
  542. $content = str_replace($w->close, '', $content);
  543. }
  544. return $content;
  545. }
  546. /**
  547. * Retrieve supported media types
  548. * @return object Supported media types
  549. */
  550. function get_media_types() {
  551. static $t = null;
  552. if ( is_null($t) )
  553. $t = (object) $this->media_types;
  554. return $t;
  555. }
  556. /**
  557. * Check if media type is supported
  558. * @param string $type Media type
  559. * @return bool If media type is supported
  560. */
  561. function is_media_type_supported($type) {
  562. $ret = false;
  563. $t = $this->get_media_types();
  564. foreach ( $t as $n => $v ) {
  565. if ( $type == $v ) {
  566. $ret = true;
  567. break;
  568. }
  569. }
  570. return $ret;
  571. }
  572. /**
  573. * Scans post content for image links and activates them
  574. *
  575. * Lightbox will not be activated for feeds
  576. * @param $content
  577. * @return string Post content
  578. */
  579. function activate_links($content) {
  580. //Activate links only if enabled
  581. if ( !$this->is_enabled() ) {
  582. return $content;
  583. }
  584. $groups = array();
  585. $w = $this->group_get_wrapper();
  586. $g_ph_f = '[%s]';
  587. //Strip groups
  588. if ( $this->options->get_bool('group_gallery') ) {
  589. $groups = array();
  590. static $g_idx = 1;
  591. $g_end_idx = 0;
  592. //Iterate through galleries
  593. while ( ($g_start_idx = strpos($content, $w->open, $g_end_idx)) && $g_start_idx !== false
  594. && ($g_end_idx = strpos($content, $w->close, $g_start_idx)) && $g_end_idx != false ) {
  595. $g_start_idx += strlen($w->open);
  596. //Extract gallery content & save for processing
  597. $g_len = $g_end_idx - $g_start_idx;
  598. $groups[$g_idx] = substr($content, $g_start_idx, $g_len);
  599. //Replace content with placeholder
  600. $g_ph = sprintf($g_ph_f, $g_idx);
  601. $content = substr_replace($content, $g_ph, $g_start_idx, $g_len);
  602. //Increment gallery count
  603. $g_idx++;
  604. //Update end index
  605. $g_end_idx = $g_start_idx + strlen($w->open);
  606. }
  607. }
  608. //General link processing
  609. $content = $this->process_links($content);
  610. //Reintegrate Groups
  611. foreach ( $groups as $group => $g_content ) {
  612. $g_ph = $w->open . sprintf($g_ph_f, $group) . $w->close;
  613. //Skip group if placeholder does not exist in content
  614. if ( strpos($content, $g_ph) === false ) {
  615. continue;
  616. }
  617. //Replace placeholder with processed content
  618. $content = str_replace($g_ph, $w->open . $this->process_links($g_content, 'gallery_' . $group) . $w->close, $content);
  619. }
  620. return $content;
  621. }
  622. /**
  623. * Retrieve HTML links in content
  624. * @param string $content Content to get links from
  625. * @param bool (optional) $unique Remove duplicates from returned links (Default: FALSE)
  626. * @return array Links in content
  627. */
  628. function get_links($content, $unique = false) {
  629. $rgx = "/\<a[^\>]+href=.*?\>/i";
  630. $links = array();
  631. preg_match_all($rgx, $content, $links);
  632. $links = $links[0];
  633. if ( $unique )
  634. $links = array_unique($links);
  635. return $links;
  636. }
  637. /**
  638. * Process links in content
  639. * @global obj $wpdb DB instance
  640. * @global obj $post Current post
  641. * @param string $content Text containing links
  642. * @param string (optional) $group Group to add links to (Default: none)
  643. * @return string Content with processed links
  644. */
  645. function process_links($content, $group = null) {
  646. //Validate content before processing
  647. if ( !is_string($content) || empty($content) )
  648. return $content;
  649. $links = $this->get_links($content, true);
  650. //Process links
  651. if ( count($links) > 0 ) {
  652. global $wpdb;
  653. global $post;
  654. $types = $this->get_media_types();
  655. $img_types = array('jpg', 'jpeg', 'gif', 'png');
  656. $protocol = array('http://', 'https://');
  657. $domain = str_replace($protocol, '', strtolower(get_bloginfo('url')));
  658. //Format Group
  659. $group_base = ( is_scalar($group) ) ? trim(strval($group)) : '';
  660. if ( !$this->options->get_bool('group_links') ) {
  661. $group_base = null;
  662. }
  663. //Iterate through links & add lightbox if necessary
  664. foreach ( $links as $link ) {
  665. //Init vars
  666. $pid = 0;
  667. $link_new = $link;
  668. $internal = false;
  669. $group = $group_base;
  670. //Parse link attributes
  671. $attr = $this->util->parse_attribute_string($link_new, array('rel' => '', 'href' => ''));
  672. $h =& $attr['href'];
  673. $r =& $attr['rel'];
  674. $attrs_all = $this->get_attributes($r, false);
  675. $attrs = $this->get_attributes($attrs_all);
  676. //Stop processing invalid, disabled, or legacy links
  677. if ( empty($h)
  678. || 0 === strpos($h, '#')
  679. || $this->has_attribute($attrs, $this->make_attribute_disabled())
  680. || $this->has_attribute($attrs_all, $this->attr_legacy, false)
  681. )
  682. continue;
  683. //Check if item links to internal media (attachment)
  684. $hdom = str_replace($protocol, '', strtolower($h));
  685. if ( strpos($hdom, $domain) === 0 ) {
  686. //Save URL for further processing
  687. $internal = true;
  688. }
  689. //Determine link type
  690. $type = false;
  691. //Check if link has already been processed
  692. if ( $internal && $this->media_item_cached($h) ) {
  693. $i = $this->get_cached_media_item($h);
  694. $type = $i['type'];
  695. }
  696. elseif ( $this->util->has_file_extension($h, $img_types) ) {
  697. //Direct Image file
  698. $type = $types->img;
  699. }
  700. elseif ( $internal && is_local_attachment($h) && ( $pid = url_to_postid($h) ) && wp_attachment_is_image($pid) ) {
  701. //Attachment URI
  702. $type = $types->att;
  703. }
  704. //Stop processing if link type not valid
  705. if ( !$type || ( $type == $types->att && !$this->options->get_bool('activate_attachments') ) )
  706. continue;
  707. //Set group (if necessary)
  708. if ( $this->options->get_bool('group_links') ) {
  709. //Normalize group
  710. if ( !is_string($group) )
  711. $group = '';
  712. //Get preset group attribute
  713. $g_name = $this->make_attribute_name('group');
  714. $g = ( $this->has_attribute($attrs, $g_name) ) ? $this->get_attribute($attrs, $g_name) : $this->get_attribute($attrs, $this->attr);
  715. if ( is_string($g) && ($g = trim($g)) && strlen($g) )
  716. $group = $g;
  717. //Group links by post?
  718. if ( !$this->widget_processing && $this->options->get_bool('group_post') ) {
  719. $group = ( strlen($group) ) ? '_' . $group : '';
  720. $group = $post->ID . $group;
  721. }
  722. if ( empty($group) ) {
  723. $group = $this->get_prefix();
  724. }
  725. //Set group attribute
  726. $attrs = $this->set_attribute($attrs, $g_name, $group);
  727. }
  728. //Activate link
  729. $attrs = $this->set_attribute($attrs, $this->attr);
  730. //Process internal links
  731. if ( $internal ) {
  732. //Mark as internal
  733. $attrs = $this->set_attribute($attrs, 'internal');
  734. //Add to media items array
  735. $this->cache_media_item($h, $type, $pid);
  736. }
  737. //Convert rel attribute to string
  738. $r = $this->build_attributes(array_merge($attrs_all, $attrs));
  739. //Update link in content
  740. $link_new = '<a ' . $this->util->build_attribute_string($attr) . '>';
  741. $content = str_replace($link, $link_new, $content);
  742. unset($h, $r);
  743. }
  744. }
  745. return $content;
  746. }
  747. /**
  748. * Generates link attributes from array
  749. * @param array $attrs Link Attributes
  750. * @return string Attribute string
  751. */
  752. function build_attributes($attrs) {
  753. $a = array();
  754. //Validate attributes
  755. $attrs = $this->get_attributes($attrs, false);
  756. //Iterate through attributes and build output array
  757. foreach ( $attrs as $key => $val ) {
  758. //Standard attributes
  759. if ( is_bool($val) && $val ) {
  760. $a[] = $key;
  761. }
  762. //Attributes with values
  763. elseif ( is_string($val) ) {
  764. $a[] = $key . '[' . $val . ']';
  765. }
  766. }
  767. return implode(' ', $a);
  768. }
  769. /**
  770. * Build attribute name
  771. * Makes sure name is only prefixed once
  772. * @return string Formatted attribute name
  773. */
  774. function make_attribute_name($name = '') {
  775. $sep = '_';
  776. $name = trim($name);
  777. //Generate valid name
  778. if ( $name != $this->attr ) {
  779. //Use default name
  780. if ( empty($name) )
  781. $name = $this->attr;
  782. //Add prefix if not yet set
  783. elseif ( strpos($name, $this->attr . $sep) !== 0 )
  784. $name = $this->attr . $sep . $name;
  785. }
  786. return $name;
  787. }
  788. /**
  789. * Create attribute to disable lightbox for current link
  790. * @return string Disabled lightbox attribute
  791. */
  792. function make_attribute_disabled() {
  793. static $ret = null;
  794. if ( is_null($ret) ) {
  795. $ret = $this->make_attribute_name('off');
  796. }
  797. return $ret;
  798. }
  799. /**
  800. * Set attribute to array
  801. * Attribute is added to array if it does not exist
  802. * @param array $attrs Current attribute array
  803. * @param string $name Name of attribute to add
  804. * @param string (optional) $value Attribute value
  805. * @return array Updated attribute array
  806. */
  807. function set_attribute($attrs, $name, $value = null) {
  808. //Validate attribute array
  809. $attrs = $this->get_attributes($attrs, false);
  810. //Build attribute name
  811. $name = $this->make_attribute_name($name);
  812. //Set attribute
  813. $attrs[$name] = true;
  814. if ( !empty($value) && is_string($value) )
  815. $attrs[$name] = $value;
  816. return $attrs;
  817. }
  818. /**
  819. * Convert attribute string into array
  820. * @param string $attr_string Attribute string
  821. * @param bool (optional) $internal Whether only internal attributes should be evaluated (Default: TRUE)
  822. * @return array Attributes as associative array
  823. */
  824. function get_attributes($attr_string, $internal = true) {
  825. $ret = array();
  826. //Protect bracketed values prior to parsing attributes string
  827. if ( is_string($attr_string) ) {
  828. $attr_string = trim($attr_string);
  829. $attr_vals = array();
  830. $attr_keys = array();
  831. $offset = 0;
  832. while ( ($bo = strpos($attr_string,'[', $offset)) && $bo !== false
  833. && ($bc = strpos($attr_string,']', $bo)) && $bc !== false
  834. ) {
  835. //Push all preceding attributes into array
  836. $attr_temp = explode(' ', substr($attr_string, $offset, $bo));
  837. //Get attribute name
  838. $name = array_pop($attr_temp);
  839. $attr_keys = array_merge($attr_keys, $attr_temp);
  840. //Add to values array
  841. $attr_vals[$name] = substr($attr_string, $bo+1, $bc-$bo-1);
  842. //Update offset
  843. $offset = $bc+1;
  844. }
  845. //Parse remaining attributes
  846. $attr_keys = array_merge($attr_keys, array_filter(explode(' ', substr($attr_string, $offset))));
  847. //Set default values for all keys
  848. $attr_keys = array_fill_keys($attr_keys, TRUE);
  849. //Merge attributes with values
  850. $ret = array_merge($attr_keys, $attr_vals);
  851. } elseif ( is_array($attr_string) )
  852. $ret = $attr_string;
  853. //Filter non-internal attributes if necessary
  854. if ( $internal && is_array($ret) ) {
  855. foreach ( array_keys($ret) as $attr ) {
  856. if ( $attr == $this->attr)
  857. continue;
  858. if ( strpos($attr, $this->attr . '_') !== 0 )
  859. unset($ret[$attr]);
  860. }
  861. }
  862. return $ret;
  863. }
  864. /**
  865. * Retrieve attribute value
  866. * @param string|array $attrs Attributes to retrieve attribute value from
  867. * @param string $attr Attribute name to retrieve
  868. * @param bool (optional) $internal Whether only internal attributes should be evaluated (Default: TRUE)
  869. * @return string|bool Attribute value (Default: FALSE)
  870. */
  871. function get_attribute($attrs, $attr, $internal = true) {
  872. $ret = false;
  873. $attrs = $this->get_attributes($attrs, $internal);
  874. //Validate attribute name for internal attributes
  875. if ( $internal )
  876. $attr = $this->make_attribute_name($attr);
  877. if ( isset($attrs[$attr]) ) {
  878. $ret = $attrs[$attr];
  879. }
  880. return $ret;
  881. }
  882. /**
  883. * Checks if attribute exists
  884. * @param string|array $attrs Attributes to retrieve attribute value from
  885. * @param string $attr Attribute name to retrieve
  886. * @param bool (optional) $internal Whether only internal attributes should be evaluated (Default: TRUE)
  887. * @return bool Whether or not attribute exists
  888. */
  889. function has_attribute($attrs, $attr, $internal = true) {
  890. return ( $this->get_attribute($attrs, $attr, $internal) !== false ) ? true : false;
  891. }
  892. /**
  893. * Cache media properties for later processing
  894. * @param string $uri URI for internal media (e.g. direct uri, attachment uri, etc.)
  895. * @param string $type Media type (image, attachment, etc.)
  896. * @param int (optional) $id ID of media item (if available) (Default: NULL)
  897. */
  898. function cache_media_item($uri, $type, $id = null) {
  899. //Cache media item
  900. if ( $this->is_media_type_supported($type) && !$this->media_item_cached($uri) ) {
  901. //Set properties
  902. $i = array('type' => null, 'id' => null, 'source' => null);
  903. //Type
  904. $i['type'] = $type;
  905. $t = $this->get_media_types();
  906. //Source
  907. if ( $type == $t->img )
  908. $i['source'] = $uri;
  909. //ID
  910. if ( is_numeric($id) )
  911. $i['id'] = absint($id);
  912. $this->media_items_raw[$uri] = $i;
  913. }
  914. }
  915. /**
  916. * Checks if media item has already been cached
  917. * @param string $uri URI of media item
  918. * @return boolean Whether media item has been cached
  919. */
  920. function media_item_cached($uri) {
  921. $ret = false;
  922. if ( !$uri || !is_string($uri) )
  923. return $ret;
  924. return ( isset($this->media_items_raw[$uri]) ) ? true : false;
  925. }
  926. /**
  927. * Retrieve cached media item
  928. * @param string $uri Media item URI
  929. * @return array|null Media item properties (NULL if not set)
  930. */
  931. function get_cached_media_item($uri) {
  932. $ret = null;
  933. if ( $this->media_item_cached($uri) ) {
  934. $ret = $this->media_items_raw[$uri];
  935. }
  936. return $ret;
  937. }
  938. /**
  939. * Retrieve cached media items
  940. * @return array Cached media items
  941. */
  942. function &get_cached_media_items() {
  943. return $this->media_items_raw;
  944. }
  945. /**
  946. * Check if media items have been cached
  947. * @return boolean
  948. */
  949. function has_cached_media_items() {
  950. return ( !empty($this->media_items_raw) ) ? true : false;
  951. }
  952. /**
  953. * Enqueue files in template head
  954. */
  955. function enqueue_files() {
  956. if ( ! $this->is_enabled() )
  957. return;
  958. //$lib = 'js/' . ( ( ( defined('WP_DEBUG') && WP_DEBUG ) || isset($_REQUEST[$this->add_prefix('debug')]) ) ? 'dev/lib.dev.js' : 'lib.js' );
  959. $lib = 'js/lib.js';
  960. wp_enqueue_script($this->add_prefix('lib'), $this->util->get_file_url($lib), array('jquery'), $this->util->get_plugin_version());
  961. wp_enqueue_style($this->add_prefix('style'), $this->get_theme_style(), array(), $this->util->get_plugin_version());
  962. }
  963. /**
  964. * Sets options/settings to initialize lightbox functionality on page load
  965. * @return void
  966. */
  967. function client_init() {
  968. if ( ! $this->is_enabled() )
  969. return;
  970. echo '<!-- SLB -->' . PHP_EOL;
  971. $options = array();
  972. $out = array();
  973. $js_code = array();
  974. //Get options
  975. $options = array(
  976. 'validateLinks' => $this->options->get_bool('validate_links'),
  977. 'autoPlay' => $this->options->get_bool('autostart'),
  978. 'slideTime' => $this->options->get_value('duration'),
  979. 'loop' => $this->options->get_bool('loop'),
  980. 'overlayOpacity' => $this->options->get_value('overlay_opacity'),
  981. 'animate' => $this->options->get_bool('animate'),
  982. 'captionEnabled' => $this->options->get_bool('enabled_caption'),
  983. 'captionSrc' => $this->options->get_bool('caption_src'),
  984. 'descEnabled' => $this->options->get_bool('enabled_desc'),
  985. 'trigger' => array($this->get_prefix()),
  986. 'prefix' => $this->get_prefix()
  987. );
  988. //Backwards compatibility
  989. if ( $this->options->get_bool('enabled_compat'))
  990. $options['trigger'][] = $this->attr_legacy;
  991. //Load UI Strings
  992. if ( ($strings = $this->build_labels()) && !empty($strings) )
  993. $options['labels'] = $strings;
  994. //Load Layout
  995. $options['layout'] = $this->get_theme_layout();
  996. //Build client output
  997. echo $this->util->build_script_element($this->util->call_client_method('init', $options), 'init', true, true);
  998. echo PHP_EOL . '<!-- /SLB -->' . PHP_EOL;
  999. }
  1000. /**
  1001. * Output code in footer
  1002. * > Media attachment URLs
  1003. * @uses `_wp_attached_file` to match attachment ID to URI
  1004. * @uses `_wp_attachment_metadata` to retrieve attachment metadata
  1005. */
  1006. function client_footer() {
  1007. echo '<!-- X -->';
  1008. //Stop if not enabled or if there are no media items to process
  1009. if ( !$this->is_enabled() || !$this->has_cached_media_items() )
  1010. return;
  1011. echo '<!-- SLB -->' . PHP_EOL;
  1012. global $wpdb;
  1013. $this->media_attachments = array();
  1014. $props = array('id', 'type', 'desc', 'title', 'source');
  1015. $props = (object) array_combine($props, $props);
  1016. //Separate media into buckets by type
  1017. $m_bucket = array();
  1018. $type = $id = null;
  1019. $m_items =& $this->get_cached_media_items();
  1020. foreach ( $m_items as $uri => $p ) {
  1021. $type = $p[$props->type];
  1022. if ( empty($type) )
  1023. continue;
  1024. if ( !isset($m_bucket[$type]) )
  1025. $m_bucket[$type] = array();
  1026. //Add to bucket for type (by reference)
  1027. $m_bucket[$type][$uri] =& $m_items[$uri];
  1028. }
  1029. //Process links by type
  1030. $t = $this->get_media_types();
  1031. //Direct image links
  1032. if ( isset($m_bucket[$t->img]) ) {
  1033. $b =& $m_bucket[$t->img];
  1034. $uris_base = array();
  1035. $uri_prefix = wp_upload_dir();
  1036. $uri_prefix = $this->util->normalize_path($uri_prefix['baseurl'], true);
  1037. foreach ( array_keys($b) as $uri ) {
  1038. $uris_base[str_replace($uri_prefix, '', $uri)] = $uri;
  1039. }
  1040. //Retrieve attachment IDs
  1041. $uris_flat = "('" . implode("','", array_keys($uris_base)) . "')";
  1042. $q = $wpdb->prepare("SELECT post_id, meta_value FROM $wpdb->postmeta WHERE `meta_key` = %s AND LOWER(`meta_value`) IN $uris_flat LIMIT %d", '_wp_attached_file', count($b));
  1043. $pids_temp = $wpdb->get_results($q);
  1044. //Match IDs with URIs
  1045. if ( $pids_temp ) {
  1046. foreach ( $pids_temp as $pd ) {
  1047. $f = $pd->meta_value;
  1048. if ( is_numeric($pd->post_id) && isset($uris_base[$f]) ) {
  1049. $b[$uris_base[$f]][$props->id] = absint($pd->post_id);
  1050. }
  1051. }
  1052. }
  1053. //Destroy worker vars
  1054. unset($b, $uri, $uris_base, $uris_flat, $q, $pids_temp, $pd);
  1055. }
  1056. //Image attachments
  1057. if ( isset($m_bucket[$t->att]) ) {
  1058. $b =& $m_bucket[$t->att];
  1059. //Attachment source URI
  1060. foreach ( $b as $uri => $p ) {
  1061. $s = wp_get_attachment_url($p[$props->id]);
  1062. if ( !!$s )
  1063. $b[$uri][$props->source] = $s;
  1064. }
  1065. //Destroy worker vars
  1066. unset($b, $uri, $p);
  1067. }
  1068. //Retrieve attachment IDs
  1069. $ids = array();
  1070. foreach ( $m_items as $uri => $p ) {
  1071. //Add post ID to query
  1072. if ( isset($p[$props->id]) ) {
  1073. $id = $p[$props->id];
  1074. //Create array for ID (support multiple URIs per ID)
  1075. if ( !isset($ids[$id]) ) {
  1076. $ids[$id] = array();
  1077. }
  1078. //Add URI to ID
  1079. $ids[$id][] = $uri;
  1080. }
  1081. }
  1082. //Retrieve attachment properties
  1083. if ( !empty($ids) ) {
  1084. $ids_flat = array_keys($ids);
  1085. $atts = get_posts(array('post_type' => 'attachment', 'include' => $ids_flat));
  1086. $ids_flat = "('" . implode("','", $ids_flat) . "')";
  1087. $atts_meta = $wpdb->get_results($wpdb->prepare("SELECT `post_id`,`meta_value` FROM $wpdb->postmeta WHERE `post_id` IN $ids_flat AND `meta_key` = %s LIMIT %d", '_wp_attachment_metadata', count($ids)));
  1088. //Rebuild metadata array
  1089. if ( $atts_meta ) {
  1090. $meta = array();
  1091. foreach ( $atts_meta as $att_meta ) {
  1092. $meta[$att_meta->post_id] = $att_meta->meta_value;
  1093. }
  1094. $atts_meta = $meta;
  1095. unset($meta);
  1096. } else {
  1097. $atts_meta = array();
  1098. }
  1099. //Process attachments
  1100. if ( $atts ) {
  1101. foreach ( $atts as $att ) {
  1102. if ( !isset($ids[$att->ID]) )
  1103. continue;
  1104. //Add attachment
  1105. //Set properties
  1106. $m = array(
  1107. $props->title => $att->post_title,
  1108. $props->desc => $att->post_content,
  1109. );
  1110. //Add metadata
  1111. if ( isset($atts_meta[$att->ID]) && ($a = unserialize($atts_meta[$att->ID])) && is_array($a) ) {
  1112. //Move original size into `sizes` array
  1113. foreach ( array('file', 'width', 'height') as $d ) {
  1114. if ( !isset($a[$d]) )
  1115. continue;
  1116. $a['sizes']['original'][$d] = $a[$d];
  1117. unset($a[$d]);
  1118. }
  1119. //Strip extraneous metadata
  1120. foreach ( array('hwstring_small') as $d ) {
  1121. if ( isset($a[$d]) )
  1122. unset($a[$d]);
  1123. }
  1124. $m = array_merge($a, $m);
  1125. unset($a, $d);
  1126. }
  1127. //Save to object
  1128. foreach ( $ids[$att->ID] as $uri ) {
  1129. if ( isset($m_items[$uri]) )
  1130. $m = array_merge($m_items[$uri], $m);
  1131. $this->media_attachments[$uri] = $m;
  1132. }
  1133. }
  1134. }
  1135. }
  1136. //Media attachments
  1137. if ( !empty($this->media_attachments) ) {
  1138. $obj = 'media';
  1139. $atch_out = $this->util->extend_client_object($obj, $this->media_attachments);
  1140. echo $this->util->build_script_element($atch_out, $obj);
  1141. }
  1142. echo PHP_EOL . '<!-- /SLB -->' . PHP_EOL;
  1143. }
  1144. /**
  1145. * Build JS object of UI strings when initializing lightbox
  1146. * @return array UI strings
  1147. */
  1148. function build_labels() {
  1149. $ret = array();
  1150. //Get all UI options
  1151. $prefix = 'txt_';
  1152. $opt_strings = array_filter(array_keys($this->options->get_items()), create_function('$opt', 'return ( strpos($opt, "' . $prefix . '") === 0 );'));
  1153. if ( count($opt_strings) ) {
  1154. //Build array of UI options
  1155. foreach ( $opt_strings as $key ) {
  1156. $name = substr($key, strlen($prefix));
  1157. $ret[$name] = $this->options->get_value($key);
  1158. }
  1159. }
  1160. return $ret;
  1161. }
  1162. /*-** Admin **-*/
  1163. /**
  1164. * Adds custom links below plugin on plugin listing page
  1165. * @uses `plugin_action_links_$plugin-name` Filter hook
  1166. * @param $actions
  1167. * @param $plugin_file
  1168. * @param $plugin_data
  1169. * @param $context
  1170. */
  1171. function admin_plugin_action_links($actions, $plugin_file, $plugin_data, $context) {
  1172. //Add link to settings (only if active)
  1173. if ( is_plugin_active($this->util->get_plugin_base_name()) ) {
  1174. $settings = __('Settings', $this->get_prefix());
  1175. $reset = __('Reset', $this->get_prefix());
  1176. $reset_confirm = "'" . __('Are you sure you want to reset your settings?', $this->get_prefix()) . "'";
  1177. $action = $this->add_prefix('reset');
  1178. $reset_link = wp_nonce_url(add_query_arg('action', $action, remove_query_arg(array($this->add_prefix('action'), 'action'), $_SERVER['REQUEST_URI'])), $action);
  1179. array_unshift($actions, '<a class="delete" href="options-media.php#' . $this->admin_get_settings_section() . '" title="' . $settings . '">' . $settings . '</a>');
  1180. array_splice($actions, 1, 0, '<a id="' . $this->add_prefix('reset') . '" href="' . $reset_link . '" onclick="return confirm(' . $reset_confirm . ');" title="' . $reset . '">' . $reset . '</a>');
  1181. }
  1182. return $actions;
  1183. }
  1184. /**
  1185. * Adds additional message for plugin updates
  1186. * @uses `in_plugin_update_message-$plugin-name` Action hook
  1187. * @var array $plugin_data Current plugin data
  1188. * @var object $r Update response data
  1189. */
  1190. function admin_plugin_update_message($plugin_data, $r) {
  1191. if ( !isset($r->new_version) )
  1192. return false;
  1193. if ( stripos($r->new_version, 'beta') !== false ) {
  1194. $cls_notice = $this->add_prefix('notice');
  1195. echo '<br />' . $this->admin_plugin_update_get_message($r);
  1196. }
  1197. }
  1198. /**
  1199. * Modify update plugins response data if necessary
  1200. * @uses `site_transient_update_plugins` Filter hook
  1201. * @param obj $transient Transient data
  1202. * @return obj Modified transient data
  1203. */
  1204. function admin_plugin_update_transient($transient) {
  1205. $n = $this->util->get_plugin_base_name();
  1206. if ( isset($transient->response) && isset($transient->response[$n]) && is_object($transient->response[$n]) && !isset($transient->response[$n]->upgrade_notice) ) {
  1207. $r =& $transient->response[$n];
  1208. $r->upgrade_notice = $this->admin_plugin_update_get_message($r);
  1209. }
  1210. return $transient;
  1211. }
  1212. /**
  1213. * Retrieve custom update message
  1214. * @param obj $r Response data from plugin update API
  1215. * @return string Message (Default: empty string)
  1216. */
  1217. function admin_plugin_update_get_message($r) {
  1218. $msg = '';
  1219. $cls_notice = $this->add_prefix('notice');
  1220. if ( !is_object($r) || !isset($r->new_version) )
  1221. return $msg;
  1222. if ( stripos($r->new_version, 'beta') !== false ) {
  1223. $msg = "<strong class=\"$cls_notice\">Notice:</strong> This update is a <strong class=\"$cls_notice\">Beta version</strong>. It is highly recommended that you test the update on a test server before updating the plugin on a production server.";
  1224. }
  1225. return $msg;
  1226. }
  1227. /**
  1228. * Reset plugin settings
  1229. * Redirects to referring page upon completion
  1230. */
  1231. function admin_reset() {
  1232. //Validate user
  1233. if ( ! current_user_can('activate_plugins') || ! check_admin_referer($this->add_prefix('reset')) )
  1234. wp_die(__('You do not have sufficient permissions to manage plugins for this blog.', $this->get_prefix()));
  1235. $action = 'reset';
  1236. if ( isset($_REQUEST['action']) && $this->add_prefix($action) == $_REQUEST['action'] ) {
  1237. //Reset settings
  1238. $this->options->reset(true);
  1239. $uri = remove_query_arg(array('_wpnonce', 'action'), add_query_arg(array($this->add_prefix('action') => $action), $_SERVER['REQUEST_URI']));
  1240. //Redirect user
  1241. wp_redirect($uri);
  1242. exit;
  1243. }
  1244. }
  1245. /**
  1246. * Displays notices for admin operations
  1247. */
  1248. function admin_notices() {
  1249. if ( is_admin() && isset($_REQUEST[$this->add_prefix('action')]) ) {
  1250. $action = $_REQUEST[$this->add_prefix('action')];
  1251. $msg = null;
  1252. if ( $action ) {
  1253. switch ( $action ) {
  1254. case 'reset':
  1255. $msg = "Simple Lightbox's settings have been <strong>reset</strong>";
  1256. break;
  1257. }
  1258. if ( ! is_null($msg) ) {
  1259. ?>
  1260. <div id="message" class="updated fade"><p><?php _e($msg); ?></p></div>
  1261. <?php
  1262. }
  1263. }
  1264. }
  1265. }
  1266. /**
  1267. * Adds settings section for Lightbox functionality
  1268. * Section is added to Settings > Media Admin menu
  1269. * @todo Move appropriate code to options class
  1270. */
  1271. function admin_settings() {
  1272. $page = $this->options_admin_page;
  1273. $form = $this->options_admin_form;
  1274. $curr = basename($_SERVER['SCRIPT_NAME']);
  1275. if ( $curr != $page && $curr != $form ) {
  1276. return;
  1277. }
  1278. $page = 'media';
  1279. $section = $this->get_prefix();
  1280. //Section
  1281. add_settings_section($section, '<div id="' . $this->admin_get_settings_section() . '">' . __('Lightbox Settings', $this->util->get_plugin_textdomain()) . '</div>', $this->m('admin_section'), $page);
  1282. //Register settings container
  1283. register_setting($page, $this->add_prefix('options'), $this->options->m('validate'));
  1284. }
  1285. /**
  1286. * Enqueues header files for admin pages
  1287. * @todo Separate and move options CSS to options class
  1288. */
  1289. function admin_enqueue_files() {
  1290. //Enqueue custom CSS for options page
  1291. if ( is_admin() && ( basename($_SERVER['SCRIPT_NAME']) == $this->options_admin_page || $this->util->is_context('admin_page_plugins')) ) {
  1292. wp_enqueue_style($this->add_prefix('admin'), $this->util->get_file_url('css/admin.css'), array(), $this->util->get_plugin_version());
  1293. }
  1294. }
  1295. /**
  1296. * Get ID of settings section on admin page
  1297. * @return string ID of settings section
  1298. * @todo Eval for moving to options class
  1299. */
  1300. function admin_get_settings_section() {
  1301. return $this->add_prefix('settings');
  1302. }
  1303. /**
  1304. * Placeholder function for lightbox admin settings
  1305. * Required because setting init function requires a callback
  1306. * @todo Evaluate for moving to options class
  1307. */
  1308. function admin_section() {
  1309. $this->options->build();
  1310. }
  1311. /* Custom fields */
  1312. function get_theme_options() {
  1313. //Get themes
  1314. $themes = $this->get_themes();
  1315. //Pop out default theme
  1316. $theme_default = $themes[$this->theme_default];
  1317. unset($themes[$this->theme_default]);
  1318. //Sort themes by title
  1319. uasort($themes, create_function('$a,$b', 'return strcmp($a[\'title\'], $b[\'title\']);'));
  1320. //Insert default theme at top of array
  1321. $themes = array($this->theme_default => $theme_default) + $themes;
  1322. //Build options
  1323. foreach ( $themes as $name => $props ) {
  1324. $themes[$name] = $props['title'];
  1325. }
  1326. return $themes;
  1327. }
  1328. }
  1329. ?>