NextGENDownloadGallery

The NextGEN Download Gallery NextGENDownloadGallery class.

Defined (1)

The class is defined in the following location(s).

/includes/class.NextGENDownloadGallery.php  
  1. class NextGENDownloadGallery { 
  2.  
  3. protected static $taglist = false; // for recording taglist when building gallery for nggtags_ext shortcode 
  4.  
  5. /** 
  6. * hook WordPress to handle script and style fixes 
  7. */ 
  8. public static function run() { 
  9. add_action('init', array(__CLASS__, 'init')); 
  10. add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueueScripts')); 
  11.  
  12. add_action('admin_init', array(__CLASS__, 'adminInit')); 
  13. add_action('admin_menu', array(__CLASS__, 'adminMenu'), 11); 
  14. add_filter('plugin_row_meta', array(__CLASS__, 'addPluginDetailsLinks'), 10, 2); 
  15.  
  16. // custom shortcodes 
  17. add_shortcode('nggtags_ext', array(__CLASS__, 'shortcodeTags')); 
  18.  
  19. // register "AJAX" actions (not really AJAX, just a cheap way into WordPress from the front end) 
  20. add_action('wp_ajax_ngg-download-gallery-zip', array(__CLASS__, 'nggDownloadZip')); 
  21. add_action('wp_ajax_nopriv_ngg-download-gallery-zip', array(__CLASS__, 'nggDownloadZip')); 
  22.  
  23. // register POST actions, for compatibility with custom templates created from v1.4.0 
  24. // NB: see this support post for why this isn't the "official" way to grab a ZIP file: 
  25. // @link https://wordpress.org/support/topic/only-administrator-can-download 
  26. add_action('admin_post_ngg-download-gallery-zip', array(__CLASS__, 'nggDownloadZip')); 
  27. add_action('admin_post_nopriv_ngg-download-gallery-zip', array(__CLASS__, 'nggDownloadZip')); 
  28.  
  29. /** 
  30. * initialise plugin, after other plugins have loaded 
  31. */ 
  32. public static function init() { 
  33. // load gettext domain 
  34. load_plugin_textdomain('nextgen-download-gallery', false, basename(dirname(NGG_DLGALL_PLUGIN_FILE)) . '/languages/'); 
  35.  
  36. // NextGEN Gallery integration 
  37. add_filter('ngg_render_template', array(__CLASS__, 'nggRenderTemplate'), 10, 2); 
  38.  
  39. // work-arounds for NGG2 
  40. if (defined('NEXTGEN_GALLERY_PLUGIN_VERSION')) { 
  41. add_filter('query_vars', array(__CLASS__, 'addNgg2QueryVars')); 
  42.  
  43. // pick up tags when ngg_images uses tags 
  44. add_filter('ngg_gallery_object', array(__CLASS__, 'ngg2GalleryObject')); 
  45.  
  46. // tell NGG2 to look in plugin for legacy templates 
  47. add_filter('ngg_legacy_template_directories', array(__CLASS__, 'ngg2LegacyTemplateFolders')); 
  48.  
  49. /** 
  50. * add back some missing query vars that NextGEN Gallery 2.0 has dropped 
  51. * @param array $query_vars 
  52. * @return array 
  53. */ 
  54. public static function addNgg2QueryVars($query_vars) { 
  55. $query_vars[] = 'gallerytag'; 
  56.  
  57. return $query_vars; 
  58.  
  59. /** 
  60. * enqueue any scripts we need 
  61. */ 
  62. public static function enqueueScripts() { 
  63. $min = SCRIPT_DEBUG ? '' : '.min'; 
  64. $ver = SCRIPT_DEBUG ? time() : NGG_DLGALL_PLUGIN_VERSION; 
  65.  
  66. $options = (array) get_option(NGG_DLGALL_OPTIONS); 
  67.  
  68. wp_register_script('nextgen-download-gallery-form', plugins_url("js/download-form$min.js", NGG_DLGALL_PLUGIN_FILE), array('jquery'), $ver, true); 
  69. wp_localize_script('nextgen-download-gallery-form', 'ngg_dlgallery', array( 
  70. 'canDownloadAll' => !empty($options['enable_all']),  
  71. 'alertNoImages' => __('Please select one or more images to download', 'nextgen-download-gallery'),  
  72. )); 
  73.  
  74. wp_enqueue_style('nextgen-download-gallery', plugins_url('css/style.css', NGG_DLGALL_PLUGIN_FILE), false, $ver); 
  75.  
  76. // FIXME: should be able to enqueue on demand! Find some way to tie script dependencies to NGG2 transient cached galleries 
  77. if (defined('NEXTGEN_GALLERY_PLUGIN_VERSION')) { 
  78. wp_enqueue_script('nextgen-download-gallery-form'); 
  79.  
  80. /** 
  81. * extend the nggtags shortcode to permit template specification 
  82. * @param array $attrs 
  83. * @param string $content 
  84. * @return string 
  85. */ 
  86. public static function shortcodeTags($attrs, $content = '') { 
  87. $template = isset($attrs['template']) ? $attrs['template'] : ''; 
  88. $images = isset($attrs['images']) ? $attrs['images'] : false; 
  89.  
  90. if (!empty($attrs['album'])) { 
  91. $out = self::nggShowAlbumTags($attrs['album'], $template, $images); 
  92. else if (!empty($attrs['gallery'])) { 
  93. $out = self::nggShowGalleryTags($attrs['gallery'], $template, $images); 
  94.  
  95. return $out; 
  96.  
  97. /** 
  98. * nggShowGalleryTags() - create a gallery based on the tags 
  99. * copyright (c) Photocrati Media 2012, modified to permit a template specification 
  100. * @param string $taglist list of tags as csv 
  101. * @param string $template the template to use, if any 
  102. * @param int $images how many images per page, defaults to all 
  103. * @return string 
  104. */ 
  105. protected static function nggShowGalleryTags($taglist, $template, $images = false) { 
  106.  
  107. // $_GET from wp_query 
  108. $pid = get_query_var('pid'); 
  109. $pageid = get_query_var('pageid'); 
  110.  
  111. // record taglist and set filter to override gallery title with taglist 
  112. self::$taglist = $taglist; 
  113. add_filter('ngg_gallery_object', array(__CLASS__, 'nggGalleryObjectTagged')); 
  114.  
  115. // NextGEN Gallery 2 can show gallery of tags with template 
  116. if (defined('NEXTGEN_GALLERY_PLUGIN_VERSION')) { 
  117. $params = array ( 
  118. 'display_type' => 'photocrati-nextgen_basic_thumbnails',  
  119. 'tag_ids' => $taglist,  
  120. 'template' => $template,  
  121. ); 
  122. $registry = C_Component_Registry::get_instance(); 
  123. $renderer = $registry->get_utility('I_Displayed_Gallery_Renderer'); 
  124. $out = $renderer->display_images($params); 
  125.  
  126. // build list of tagged images in NextCellent Gallery 
  127. else { 
  128. // get the related images 
  129. $picturelist = nggTags::find_images_for_tags($taglist , 'ASC'); 
  130.  
  131. // look for ImageBrowser if we have a $_GET('pid') 
  132. if ( $pageid == get_the_ID() || !is_home() ) { 
  133. if (!empty( $pid )) { 
  134. $out = nggCreateImageBrowser($picturelist, $template); 
  135. return $out; 
  136.  
  137. // nothing to see, move along... 
  138. if ( empty($picturelist) ) { 
  139. return; 
  140.  
  141. // show gallery 
  142. if ( is_array($picturelist) ) { 
  143. // process gallery using selected template 
  144. $out = nggCreateGallery($picturelist, false, $template, $images); 
  145.  
  146. // remove filter for gallery title 
  147. remove_filter('ngg_gallery_object', array(__CLASS__, 'nggGalleryObjectTagged')); 
  148.  
  149. $out = apply_filters('ngg_show_gallery_tags_content', $out, $taglist); 
  150. return $out; 
  151.  
  152. /** 
  153. * nggShowAlbumTags() - create a gallery based on the tags 
  154. * copyright (c) Photocrati Media 2012, modified to permit a template specification 
  155. * @param string $taglist list of tags as csv 
  156. * @param string $template the template to use, if any 
  157. * @param int $images how many images per page, defaults to all 
  158. * @return string 
  159. */ 
  160. protected static function nggShowAlbumTags($taglist, $template, $images = false) { 
  161. global $nggRewrite; 
  162.  
  163. // NextGEN Gallery 2.0[.7] defines class nggRewrite but doesn't instantiate it 
  164. if (class_exists('nggRewrite') && !isset($nggRewrite)) { 
  165. $nggRewrite = new nggRewrite(); 
  166.  
  167. // $_GET from wp_query 
  168. $tag = get_query_var('gallerytag'); 
  169. $pageid = get_query_var('pageid'); 
  170.  
  171. // look for gallerytag variable 
  172. if ( $pageid == get_the_ID() || !is_home() ) { 
  173. if (!empty( $tag )) { 
  174. $slug = esc_attr( $tag ); 
  175. $term = get_term_by('name', $slug, 'ngg_tag'); 
  176. $tagname = $term->name; 
  177. $out = sprintf('<div id="albumnav"><span><a href="%1$s" title="%2$s">%2$s</a> | %3$s</span></div>',  
  178. esc_url(get_permalink()), __('Overview', 'nextgen-download-gallery'), esc_html($tagname)); 
  179. $out .= self::nggShowGalleryTags($slug, $template, $images); 
  180. return $out; 
  181.  
  182. // get now the related images 
  183. $picturelist = nggTags::get_album_images($taglist); 
  184.  
  185. // nothing to see, move along... 
  186. if ( empty($picturelist) ) { 
  187. return; 
  188.  
  189. // re-structure the object that we can use the standard template 
  190. foreach ($picturelist as $key => $picture) { 
  191. $picturelist[$key]->previewpic = $picture->pid; 
  192. $picturelist[$key]->previewname = $picture->filename; 
  193. $picturelist[$key]->previewurl = site_url("/{$picture->path}/thumbs/thumbs_{$picture->filename}"); 
  194. $picturelist[$key]->counter = $picture->count; 
  195. $picturelist[$key]->title = $picture->name; 
  196. $picturelist[$key]->pagelink = $nggRewrite->get_permalink(array('gallerytag' => $picture->slug)); 
  197.  
  198. // TODO: Add pagination later 
  199. $navigation = '<div class="ngg-clear"></div>'; 
  200.  
  201. // create the output 
  202. $out = nggGallery::capture('album-compact', array('album' => 0, 'galleries' => $picturelist, 'pagination' => $navigation)); 
  203.  
  204. $out = apply_filters('ngg_show_album_tags_content', $out, $taglist); 
  205.  
  206. return $out; 
  207.  
  208. /** 
  209. * override gallery title with taglist 
  210. * @param stdClass $gallery 
  211. * @return stdClass 
  212. */ 
  213. public static function nggGalleryObjectTagged($gallery) { 
  214. if (self::$taglist) { 
  215. $gallery->title = self::getTitleFromTaglist(self::$taglist); 
  216. $gallery->nggDownloadTaglist = self::$taglist; 
  217.  
  218. return $gallery; 
  219.  
  220. /** 
  221. * confect gallery title from taglist 
  222. * @param string $taglist; 
  223. * @return string 
  224. */ 
  225. public static function getTitleFromTaglist($taglist) { 
  226. /** translators: gallery title when it has been created from image tags */ 
  227. $title = sprintf(__('tagged: %s', 'nextgen-download-gallery'), $taglist); 
  228.  
  229. return apply_filters('ngg_dlgallery_tags_gallery_title', $title, $taglist); 
  230.  
  231. /** 
  232. * handle NextGEN Gallery 2 tag galleries 
  233. * @param stdClass $gallery 
  234. * @return stdClass 
  235. */ 
  236. public static function ngg2GalleryObject($gallery) { 
  237. if ($gallery->displayed_gallery->source == 'tags') { 
  238. self::$taglist = implode(', ', $gallery->displayed_gallery->container_ids); 
  239. $gallery = self::nggGalleryObjectTagged($gallery); 
  240. else { 
  241. self::$taglist = ''; 
  242.  
  243. return $gallery; 
  244.  
  245. /** 
  246. * add this plugin's template folder to NextGEN Gallery 2's list of legacy template folders 
  247. * @param array $folders 
  248. * @return array 
  249. */ 
  250. public static function ngg2LegacyTemplateFolders($folders) { 
  251. $folders[__('NextGEN Download Gallery', 'nextgen-download-gallery')] = NGG_DLGALL_PLUGIN_ROOT . 'templates'; 
  252.  
  253. return $folders; 
  254.  
  255. /** 
  256. * tell NextGEN about our custom template 
  257. * @param string $custom_template the path to the custom template file (or false if not known to us) 
  258. * @param string $template_name name of custom template sought 
  259. * @return string 
  260. */ 
  261. public static function nggRenderTemplate($custom_template, $template_name) { 
  262. if ($template_name == 'gallery-download') { 
  263. // see if theme has customised this template 
  264. $custom_template = locate_template("nggallery/$template_name.php"); 
  265. if (!$custom_template) { 
  266. // no custom template so set to the default 
  267. $custom_template = NGG_DLGALL_PLUGIN_ROOT . "templates/$template_name.php"; 
  268.  
  269. wp_enqueue_style('nextgen-download-gallery'); 
  270. wp_enqueue_script('nextgen-download-gallery-form'); 
  271.  
  272. return $custom_template; 
  273.  
  274. /** 
  275. * @deprecated generate link for downloading everything; templates should now call getDownloadAllId() 
  276. * @param object $gallery 
  277. * @return string|false 
  278. */ 
  279. public static function getDownloadAllUrl($gallery) { 
  280. $args = array( 
  281. 'action' => 'ngg-download-gallery-zip',  
  282. 'all-id' => urlencode(self::getDownloadAllId($gallery)),  
  283. 'download-all' => 1,  
  284. ); 
  285.  
  286. $url = add_query_arg($args, admin_url('admin-ajax.php')); 
  287.  
  288. return $url; 
  289.  
  290. /** 
  291. * get list of expected NGG2 gallery query fields 
  292. * @return array 
  293. */ 
  294. protected static function getNgg2QueryFields() { 
  295. return array('ID', 'container_ids', 'exclusions', 'excluded_container_ids', 'entity_ids', 'returns', 'source'); 
  296.  
  297. /** 
  298. * generate link for downloading everything, if configured 
  299. * @param object $gallery 
  300. * @return string|false 
  301. */ 
  302. public static function getDownloadAllId($gallery) { 
  303. if (defined('NEXTGEN_GALLERY_PLUGIN_VERSION')) { 
  304. // build query for NextGEN Gallery 2 virtual gallery 
  305. $params = $gallery->displayed_gallery->object->get_entity(); 
  306. $query = array(); 
  307. foreach (self::getNgg2QueryFields() as $field) { 
  308. if (!empty($params->$field)) { 
  309. $query[$field] = $params->$field; 
  310.  
  311. // encode to prevent accidental corruption 
  312. $json = json_encode($query); 
  313. $id = base64_encode($json); 
  314. else { 
  315. // legacy plugin 
  316. if (empty($gallery->nggDownloadTaglist)) { 
  317. // just a gallery 
  318. $id = $gallery->ID; 
  319. else { 
  320. // virtual gallery from tags 
  321. $id = md5($gallery->nggDownloadTaglist); 
  322.  
  323. return $id; 
  324.  
  325. /** 
  326. * build download title from NextGEN 2 displayed gallery properties, e.g. selected galleries, taglist, etc. 
  327. * @param C_Displayed_Gallery $displayed_gallery 
  328. * @return string 
  329. */ 
  330. protected static function getNgg2DownloadTitle($displayed_gallery) { 
  331. switch ($displayed_gallery->source) { 
  332.  
  333. case 'galleries': 
  334. $titles = array(); 
  335. foreach ($displayed_gallery->container_ids as $gallery_id) { 
  336. $gallery = nggdb::find_gallery($gallery_id); 
  337. $titles[] = $gallery->title; 
  338. $title = implode(', ', $titles); 
  339. break; 
  340.  
  341. case 'tags': 
  342. $taglist = implode(', ', $displayed_gallery->container_ids); 
  343. $title = self::getTitleFromTaglist($taglist); 
  344. break; 
  345.  
  346. default: 
  347. // allow title to be confected 
  348. // TODO: extend this function to pick up other NGG2 gallery sources 
  349. $title = ''; 
  350. break; 
  351.  
  352.  
  353. // restrict length to 250 characters 
  354. $title = substr($title, 0, 250); 
  355.  
  356. return $title; 
  357.  
  358. /** 
  359. * POST action for downloading a bunch of NextGEN gallery images as a ZIP archive 
  360. */ 
  361. public static function nggDownloadZip() { 
  362. global $nggdb; 
  363.  
  364. // pick up gallery ID and array of image IDs from AJAX request 
  365. $images = isset($_REQUEST['pid']) && is_array($_REQUEST['pid']) ? array_map('intval', $_REQUEST['pid']) : false; 
  366. $gallery = isset($_REQUEST['gallery']) ? trim(wp_unslash($_REQUEST['gallery'])) : ''; 
  367.  
  368. // sanity check 
  369. if (!is_object($nggdb)) { 
  370. wp_die(__('NextGEN Download Gallery requires NextGEN Gallery or NextCellent Gallery', 'nextgen-download-gallery')); 
  371.  
  372. // check for request to download everything 
  373. if (!empty($_REQUEST['download-all']) && !empty($_REQUEST['all-id'])) { 
  374. $allID = wp_unslash($_REQUEST['all-id']); 
  375.  
  376. if (defined('NEXTGEN_GALLERY_PLUGIN_VERSION')) { 
  377. // decode NGG2 encoded query for virtual gallery 
  378. $json = base64_decode($allID); 
  379. $query = $json ? json_decode($json, true) : false; 
  380.  
  381. // reduce query to permitted fields 
  382. $query = $query ? array_intersect_key($query, array_flip(self::getNgg2QueryFields())) : false; 
  383.  
  384. if (!empty($query)) { 
  385. $mapper = C_Displayed_Gallery_Mapper::get_instance(); 
  386. $factory = C_Component_Factory::get_instance(); 
  387. $displayed_gallery = $factory->create('displayed_gallery', $query, $mapper); 
  388.  
  389. $entities = $displayed_gallery->get_entities(false, false, true); 
  390.  
  391. $images = array(); 
  392. foreach ($entities as $image) { 
  393. $images[] = $image->pid; 
  394.  
  395. if (empty($gallery)) { 
  396. $gallery = self::getNgg2DownloadTitle($displayed_gallery); 
  397. else { 
  398. $images = $nggdb->get_ids_from_gallery($allID); 
  399. else if (!empty($_REQUEST['all-tags'])) { 
  400. $picturelist = nggTags::find_images_for_tags(wp_unslash($_REQUEST['all-tags']), 'ASC'); 
  401. $images = array(); 
  402. foreach ($picturelist as $image) { 
  403. $images[] = $image->pid; 
  404.  
  405. // if no gallery name, confect one 
  406. if (empty($gallery)) { 
  407. $gallery = md5(implode(', ', $images)); 
  408.  
  409. if (is_array($images) && count($images) > 0) { 
  410. // allow a long script run for pulling together lots of images 
  411. @set_time_limit(HOUR_IN_SECONDS); 
  412.  
  413. // stop/clear any output buffering 
  414. while (ob_get_level()) { 
  415. ob_end_clean(); 
  416.  
  417. // turn off compression on the server 
  418. if (function_exists('apache_setenv')) 
  419. @apache_setenv('no-gzip', 1); 
  420. @ini_set('zlib.output_compression', 'Off'); 
  421.  
  422. if (!class_exists('PclZip')) { 
  423. require ABSPATH . 'wp-admin/includes/class-pclzip.php'; 
  424.  
  425. $filename = tempnam(get_temp_dir(), 'zip'); 
  426. $zip = new PclZip($filename); 
  427. $files = array(); 
  428.  
  429. foreach ($images as $image) { 
  430. $image = $nggdb->find_image($image); 
  431. if ($image) { 
  432. $files[] = apply_filters('ngg_dlgallery_image_path', $image->imagePath, $image); 
  433.  
  434. if (count($files) > 0) { 
  435. // allow other plugins / themes to preprocess files added to the zip archive 
  436. $preAddCallback = apply_filters('ngg_dlgallery_zip_pre_add', '__return_true'); 
  437.  
  438. // create the Zip archive, without paths or compression (images are generally already compressed) 
  439. $properties = $zip->create($files, PCLZIP_OPT_REMOVE_ALL_PATH, PCLZIP_OPT_NO_COMPRESSION, PCLZIP_CB_PRE_ADD, $preAddCallback); 
  440. if (!is_array($properties)) { 
  441. wp_die($zip->errorInfo(true)); 
  442. unset($zip); 
  443.  
  444. // send the Zip archive to the browser 
  445. $zipName = apply_filters('ngg_dlgallery_zip_filename', sanitize_file_name(strtr($gallery, ', ', '-')) . '.zip', $gallery); 
  446. do_action('ngg_dlgallery_zip_before_send', $zipName, $filename, $images); 
  447. header('Content-Description: File Transfer'); 
  448. header('Content-Type: application/zip'); 
  449. header('Content-Disposition: attachment; filename=' . $zipName); 
  450. header('Content-Transfer-Encoding: binary'); 
  451. header('Expires: 0'); 
  452. header('Cache-Control: must-revalidate'); 
  453. header('Pragma: public'); 
  454. header('Content-Length: ' . filesize($filename)); 
  455.  
  456. $chunksize = 512 * 1024; 
  457. $file = @fopen($filename, 'rb'); 
  458. if ($file !== false) { 
  459. while (!feof($file)) { 
  460. echo @fread($file, $chunksize); 
  461. flush(); 
  462. fclose($file); 
  463.  
  464. // check for bug in some old PHP versions, close a second time! 
  465. if (is_resource($file)) { 
  466. @fclose($file); 
  467.  
  468. do_action('ngg_dlgallery_zip_after_send', $zipName, $filename, $images); 
  469.  
  470. // delete the temporary file 
  471. @unlink($filename); 
  472.  
  473. exit; 
  474.  
  475. // no files, report to user 
  476. wp_die(__('No files found to download', 'nextgen-download-gallery')); 
  477.  
  478. wp_die(__('No images selected for download', 'nextgen-download-gallery')); 
  479.  
  480. /** 
  481. * initialise settings for admin 
  482. */ 
  483. public static function adminInit() { 
  484. add_settings_section(NGG_DLGALL_OPTIONS, false, false, NGG_DLGALL_OPTIONS); 
  485. register_setting(NGG_DLGALL_OPTIONS, NGG_DLGALL_OPTIONS, array(__CLASS__, 'settingsValidate')); 
  486.  
  487. // in_plugin_update_message isn't supported on multisite != blog-1, so just add another row 
  488. if (current_user_can('update_plugins')) { 
  489. add_action('after_plugin_row_' . NGG_DLGALL_PLUGIN_NAME, array(__CLASS__, 'upgradeMessage'), 20, 2); 
  490.  
  491. /** 
  492. * show upgrade messages on Plugins admin page 
  493. * @param string $file 
  494. * @param object $current_meta 
  495. */ 
  496. public static function upgradeMessage($file, $plugin_data) { 
  497. $current = get_site_transient('update_plugins'); 
  498.  
  499. if (isset($current->response[$file])) { 
  500. $r = $current->response[$file]; 
  501.  
  502. if (!empty($r->upgrade_notice)) { 
  503. $wp_list_table = _get_list_table('WP_Plugins_List_Table'); 
  504. $colspan = $wp_list_table->get_column_count(); 
  505. $plugin_name = wp_kses($plugin_data['Name'], 'strip'); 
  506.  
  507. require NGG_DLGALL_PLUGIN_ROOT . 'views/admin-upgrade-message.php'; 
  508.  
  509. /** 
  510. * action hook for adding plugin details links 
  511. */ 
  512. public static function addPluginDetailsLinks($links, $file) { 
  513. if ($file == NGG_DLGALL_PLUGIN_NAME) { 
  514. $links[] = sprintf('<a href="https://wordpress.org/support/plugin/nextgen-download-gallery" target="_blank">%s</a>', _x('Get help', 'plugin details links', 'nextgen-download-gallery')); 
  515. $links[] = sprintf('<a href="https://wordpress.org/plugins/nextgen-download-gallery/" target="_blank">%s</a>', _x('Rating', 'plugin details links', 'nextgen-download-gallery')); 
  516. $links[] = sprintf('<a href="https://translate.wordpress.org/projects/wp-plugins/nextgen-download-gallery" target="_blank">%s</a>', _x('Translate', 'plugin details links', 'nextgen-download-gallery')); 
  517. $links[] = sprintf('<a href="https://shop.webaware.com.au/donations/?donation_for=NextGEN+Download+Gallery" target="_blank">%s</a>', _x('Donate', 'plugin details links', 'nextgen-download-gallery')); 
  518.  
  519. return $links; 
  520.  
  521. /** 
  522. * admin menu items 
  523. */ 
  524. public static function adminMenu() { 
  525. if (!defined('NGGFOLDER')) 
  526. return; 
  527.  
  528. add_submenu_page(NGGFOLDER, 'Download Gallery', 'Download Gallery', 'manage_options', 'ngg-dlgallery', array(__CLASS__, 'settingsPage')); 
  529.  
  530. /** 
  531. * settings admin 
  532. */ 
  533. public static function settingsPage() { 
  534. $options = (array) get_option(NGG_DLGALL_OPTIONS); 
  535.  
  536. if (!isset($options['enable_all'])) { 
  537. $options['enable_all'] = 0; 
  538.  
  539. require NGG_DLGALL_PLUGIN_ROOT . 'views/settings-form.php'; 
  540.  
  541. /** 
  542. * validate settings on save 
  543. * @param array $input 
  544. * @return array 
  545. */ 
  546. public static function settingsValidate($input) { 
  547. $output = array(); 
  548.  
  549. $output['enable_all'] = empty($input['enable_all']) ? 0 : 1; 
  550.  
  551. return $output; 
  552.