NextGEN Gallery – WordPress Gallery Plugin - Version 2.2.45

Version Description

  • 02.14.2018 =
  • NEW: Partner page for Imagify image optimization
  • Secured: Image property escaping case-sensitive
  • Secured: Vulnerable to CVE-2017-2416 buffer overflows
  • Kudos: Zhouyuan Yang of Fortinet's FortiGuard Labs
  • Fixed: Incorrect CSS class format used in form generator text field
  • Fixed: Clean exit in FastCGI environments
  • Fixed: Use of deprecated functions
Download this release

Release Info

Developer photocrati
Plugin Icon 128x128 NextGEN Gallery – WordPress Gallery Plugin
Version 2.2.45
Comparing to
See all releases

Code changes from version 2.2.33 to 2.2.45

Files changed (55) hide show
  1. changelog.txt +16 -4
  2. composer.json +1 -1
  3. nggallery.php +18 -7
  4. products/photocrati_nextgen/modules/ajax/package.module.ajax.php +1 -1
  5. products/photocrati_nextgen/modules/datamapper/module.datamapper.php +2 -0
  6. products/photocrati_nextgen/modules/datamapper/package.module.datamapper.php +4 -4
  7. products/photocrati_nextgen/modules/dynamic_thumbnails/package.module.dynamic_thumbnails.php +3 -3
  8. products/photocrati_nextgen/modules/i18n/lang/nggallery-sv_SE.po +4 -4
  9. products/photocrati_nextgen/modules/i18n/lang/nggallery.po +3 -3
  10. products/photocrati_nextgen/modules/imagify/lib/class-imagify-partner.php +877 -0
  11. products/photocrati_nextgen/modules/imagify/module.imagify.php +82 -0
  12. products/photocrati_nextgen/modules/imagify/package.module.imagify.php +76 -0
  13. products/photocrati_nextgen/modules/imagify/static/imagify_preview.png +0 -0
  14. products/photocrati_nextgen/modules/imagify/static/style.css +132 -0
  15. products/photocrati_nextgen/modules/imagify/static/style.min.css +1 -0
  16. products/photocrati_nextgen/modules/imagify/templates/admin_page.php +22 -0
  17. products/photocrati_nextgen/modules/lightbox/package.module.lightbox.php +1 -1
  18. products/photocrati_nextgen/modules/mvc/package.module.mvc.php +1 -0
  19. products/photocrati_nextgen/modules/nextgen_admin/module.nextgen_admin.php +0 -8
  20. products/photocrati_nextgen/modules/nextgen_admin/templates/field_generator/nextgen_settings_field_text.php +2 -2
  21. products/photocrati_nextgen/modules/nextgen_basic_album/package.module.nextgen_basic_album.php +2 -2
  22. products/photocrati_nextgen/modules/nextgen_basic_gallery/package.module.nextgen_basic_gallery.php +1 -0
  23. products/photocrati_nextgen/modules/nextgen_basic_imagebrowser/package.module.nextgen_basic_imagebrowser.php +1 -0
  24. products/photocrati_nextgen/modules/nextgen_basic_tagcloud/package.module.nextgen_basic_tagcloud.php +2 -8
  25. products/photocrati_nextgen/modules/nextgen_basic_templates/package.module.nextgen_basic_templates.php +1 -1
  26. products/photocrati_nextgen/modules/nextgen_data/module.nextgen_data.php +173 -82
  27. products/photocrati_nextgen/modules/nextgen_data/package.module.nextgen_data.php +20 -9
  28. products/photocrati_nextgen/modules/nextgen_data/pel-0.9.6/src/PelIfd.php +1 -0
  29. products/photocrati_nextgen/modules/nextgen_data/pel-0.9.6/src/PelWrongComponentCountException.php +1 -1
  30. products/photocrati_nextgen/modules/nextgen_gallery_display/module.nextgen_gallery_display.php +2 -2
  31. products/photocrati_nextgen/modules/nextgen_gallery_display/package.module.nextgen_gallery_display.php +2 -2
  32. products/photocrati_nextgen/modules/nextgen_xmlrpc/package.module.nextgen_xmlrpc.php +3 -0
  33. products/photocrati_nextgen/modules/ngglegacy/admin/album.php +10 -8
  34. products/photocrati_nextgen/modules/ngglegacy/admin/functions.php +5 -2
  35. products/photocrati_nextgen/modules/ngglegacy/admin/manage-galleries.php +1 -2
  36. products/photocrati_nextgen/modules/ngglegacy/admin/manage-images.php +0 -1
  37. products/photocrati_nextgen/modules/ngglegacy/admin/manage-sort.php +1 -1
  38. products/photocrati_nextgen/modules/ngglegacy/admin/manage.php +4 -0
  39. products/photocrati_nextgen/modules/ngglegacy/admin/overview.php +2 -1
  40. products/photocrati_nextgen/modules/ngglegacy/admin/tags.php +0 -1
  41. products/photocrati_nextgen/modules/ngglegacy/lib/class.ngg_serializable.php +10 -1
  42. products/photocrati_nextgen/modules/ngglegacy/lib/core.php +2 -2
  43. products/photocrati_nextgen/modules/ngglegacy/lib/imagemagick.inc.php +3 -3
  44. products/photocrati_nextgen/modules/ngglegacy/lib/meta.php +6 -5
  45. products/photocrati_nextgen/modules/ngglegacy/lib/ngg-db.php +9 -4
  46. products/photocrati_nextgen/modules/ngglegacy/lib/sitemap.php +4 -10
  47. products/photocrati_nextgen/modules/ngglegacy/lib/tags.php +1 -0
  48. products/photocrati_nextgen/modules/ngglegacy/module.ngglegacy.php +1 -1
  49. products/photocrati_nextgen/modules/ngglegacy/nggallery.php +37 -18
  50. products/photocrati_nextgen/modules/{simplehtmldom → simple_html_dom}/module.simple_html_dom.php +0 -0
  51. products/photocrati_nextgen/modules/{simplehtmldom → simple_html_dom}/package.module.simple_html_dom.php +0 -0
  52. products/photocrati_nextgen/modules/{simplehtmldom → simple_html_dom}/simplehtmldom/simple_html_dom.php +8 -8
  53. products/photocrati_nextgen/modules/widget/package.module.widget.php +3 -0
  54. products/photocrati_nextgen/product.photocrati_nextgen.php +3 -1
  55. readme.txt +29 -8
changelog.txt CHANGED
@@ -1,11 +1,23 @@
1
  NextGEN Gallery
2
  by Imagely
3
 
4
- = V2.2.33 - 12.24.2017
5
- * Fixed: Certain image attributes were not being validated correctly
6
-
7
- = V2.2.30 - 12.13.2017
 
 
 
 
 
 
 
 
8
  * Fixed: Segfaults on PHP 7.2, 7.1.12, and 7.0.26.
 
 
 
 
9
 
10
  = V2.2.18 - 12.04.2017 =
11
  * NEW: Include PHP 7.2.0 in the warning created by NextGen Gallery 2.2.16
1
  NextGEN Gallery
2
  by Imagely
3
 
4
+ = V2.2.45 - 02.14.2018 =
5
+ * NEW: Partner page for Imagify image optimization
6
+ * Secured: Image property escaping case-sensitive
7
+ * Secured: Vulnerable to CVE-2017-2416 buffer overflows
8
+ * Kudos: Zhouyuan Yang of Fortinet's FortiGuard Labs
9
+ * Fixed: Incorrect CSS class format used in form generator text field
10
+ * Fixed: Clean exit in FastCGI environments
11
+ * Fixed: Use of deprecated functions
12
+
13
+ = V2.2.33 - 12.24.2017 =
14
+ * Secured: Certain image attributes were not being validated correctly
15
+ = V2.2.30 - 12.13.2017 =
16
  * Fixed: Segfaults on PHP 7.2, 7.1.12, and 7.0.26.
17
+ * Fixed: Wizards initialized too early.
18
+ * Fixed: ImageBrowser display types generating warnings on PHP 7.2
19
+ * Fixed: Widgets causing WSOD on PHP 7.2
20
+ * Fixed: Removed create_function() calls (deprecated in PHP 7.2)
21
 
22
  = V2.2.18 - 12.04.2017 =
23
  * NEW: Include PHP 7.2.0 in the warning created by NextGen Gallery 2.2.16
composer.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "imagely/nextgen-gallery",
3
- "description": "The most popular gallery plugin for WordPress and one of the most popular plugins of all time with over 16.5 million downloads.",
4
  "keywords": ["nextgen", "nextgen gallery", "gallery", "galleries", "image", "images", "image gallery", "photo", "photos", "photo gallery", "picture", "pictures", "picture gallery", "album", "albums", "photo albums", "image album", "media", "media gallery", "thumbnails", "thumbnail gallery", "thumbnail galleries", "slideshow", "slideshows", "slideshow gallery", "slideshow galleries", "fancybox", "lightbox", "responsive", "responsive gallery", "responsive galleries", "singlepic", "watermarks", "watermarking", "photography", "photographer"],
5
  "homepage": "https://www.imagely.com/",
6
  "license": "GPLv2",
1
  {
2
  "name": "imagely/nextgen-gallery",
3
+ "description": "The most popular gallery plugin for WordPress and one of the most popular plugins of all time with over 20 million downloads.",
4
  "keywords": ["nextgen", "nextgen gallery", "gallery", "galleries", "image", "images", "image gallery", "photo", "photos", "photo gallery", "picture", "pictures", "picture gallery", "album", "albums", "photo albums", "image album", "media", "media gallery", "thumbnails", "thumbnail gallery", "thumbnail galleries", "slideshow", "slideshows", "slideshow gallery", "slideshow galleries", "fancybox", "lightbox", "responsive", "responsive gallery", "responsive galleries", "singlepic", "watermarks", "watermarking", "photography", "photographer"],
5
  "homepage": "https://www.imagely.com/",
6
  "license": "GPLv2",
nggallery.php CHANGED
@@ -3,8 +3,8 @@ if(preg_match('#' . basename(__FILE__) . '#', $_SERVER['PHP_SELF'])) { die('You
3
 
4
  /**
5
  * Plugin Name: NextGEN Gallery
6
- * Description: The most popular gallery plugin for WordPress and one of the most popular plugins of all time with over 18 million downloads.
7
- * Version: 2.2.33
8
  * Author: Imagely
9
  * Plugin URI: https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/
10
  * Author URI: https://www.imagely.com
@@ -85,14 +85,25 @@ class C_NextGEN_Bootstrap
85
 
86
  static function shutdown($exception=NULL)
87
  {
88
- if (is_null($exception)) {
89
- throw new E_Clean_Exit;
90
- }
 
 
 
 
 
 
 
 
 
 
 
 
91
  elseif (!($exception instanceof E_Clean_Exit)) {
92
  ob_end_clean();
93
  self::print_exception($exception);
94
  }
95
-
96
  }
97
 
98
  static function print_exception($exception)
@@ -661,7 +672,7 @@ class C_NextGEN_Bootstrap
661
  define('NGG_PRODUCT_URL', path_join(str_replace("\\", '/', NGG_PLUGIN_URL), 'products'));
662
  define('NGG_MODULE_URL', path_join(str_replace("\\", '/', NGG_PRODUCT_URL), 'photocrati_nextgen/modules'));
663
  define('NGG_PLUGIN_STARTED_AT', microtime());
664
- define('NGG_PLUGIN_VERSION', '2.2.33');
665
 
666
  if (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG)
667
  define('NGG_SCRIPT_VERSION', (string)mt_rand(0, mt_getrandmax()));
3
 
4
  /**
5
  * Plugin Name: NextGEN Gallery
6
+ * Description: The most popular gallery plugin for WordPress and one of the most popular plugins of all time with over 20 million downloads.
7
+ * Version: 2.2.45
8
  * Author: Imagely
9
  * Plugin URI: https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/
10
  * Author URI: https://www.imagely.com
85
 
86
  static function shutdown($exception=NULL)
87
  {
88
+ if (is_null($exception))
89
+ {
90
+ $name = php_sapi_name();
91
+ if (FALSE === strpos($name, 'cgi')
92
+ && version_compare(PHP_VERSION, '5.3.3') >= 0)
93
+ {
94
+ $status = session_status();
95
+ if (in_array($status, array(PHP_SESSION_DISABLED, PHP_SESSION_NONE), TRUE))
96
+ session_write_close();
97
+ fastcgi_finish_request();
98
+ }
99
+ else {
100
+ throw new E_Clean_Exit;
101
+ }
102
+ }
103
  elseif (!($exception instanceof E_Clean_Exit)) {
104
  ob_end_clean();
105
  self::print_exception($exception);
106
  }
 
107
  }
108
 
109
  static function print_exception($exception)
672
  define('NGG_PRODUCT_URL', path_join(str_replace("\\", '/', NGG_PLUGIN_URL), 'products'));
673
  define('NGG_MODULE_URL', path_join(str_replace("\\", '/', NGG_PRODUCT_URL), 'photocrati_nextgen/modules'));
674
  define('NGG_PLUGIN_STARTED_AT', microtime());
675
+ define('NGG_PLUGIN_VERSION', '2.2.45');
676
 
677
  if (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG)
678
  define('NGG_SCRIPT_VERSION', (string)mt_rand(0, mt_getrandmax()));
products/photocrati_nextgen/modules/ajax/package.module.ajax.php CHANGED
@@ -11,7 +11,7 @@ class C_Ajax_Controller extends C_MVC_Controller
11
  parent::define($context);
12
  $this->implement('I_Ajax_Controller');
13
  }
14
- function index_action()
15
  {
16
  $retval = NULL;
17
  // Inform the MVC framework what type of content we're returning
11
  parent::define($context);
12
  $this->implement('I_Ajax_Controller');
13
  }
14
+ function index_action($return = FALSE)
15
  {
16
  $retval = NULL;
17
  // Inform the MVC framework what type of content we're returning
products/photocrati_nextgen/modules/datamapper/module.datamapper.php CHANGED
@@ -170,6 +170,8 @@ class M_DataMapper extends C_Base_Module
170
  elseif (($value = $wp_query->get('post_title__like'))) {
171
  $where .= " AND {$wpdb->posts}.post_title LIKE '{$value}'";
172
  }
 
 
173
  }
174
 
175
 
170
  elseif (($value = $wp_query->get('post_title__like'))) {
171
  $where .= " AND {$wpdb->posts}.post_title LIKE '{$value}'";
172
  }
173
+
174
+ return $where;
175
  }
176
 
177
 
products/photocrati_nextgen/modules/datamapper/package.module.datamapper.php CHANGED
@@ -447,7 +447,7 @@ class Mixin_CustomPost_DataMapper_Driver extends Mixin
447
  if ($this->is_select_statement()) {
448
  $this->object->cache($cache_key, $results);
449
  }
450
- remove_action('pre_get_posts', array(&$this, 'set_query_args'), PHP_INT_MAX - 1, 1);
451
  }
452
  // Convert the result
453
  if ($convert_to_entities) {
@@ -1108,11 +1108,11 @@ class C_CustomTable_DataMapper_Driver extends C_DataMapper_Driver_Base
1108
  }
1109
  function initialize($object_name = FALSE)
1110
  {
1111
- parent::initialize($object_name);
1112
  if (!isset($this->_primary_key_column)) {
1113
  $this->_primary_key_column = $this->_lookup_primary_key_column();
1114
  }
1115
- $this->migrate(FALSE);
1116
  }
1117
  /**
1118
  * Returns the database connection object for WordPress
@@ -1578,7 +1578,7 @@ class Mixin_DataMapper_Driver_Base extends Mixin
1578
  * implementation. The implementation should make use of the
1579
  * _set_default_value() method
1580
  */
1581
- function set_defaults()
1582
  {
1583
  }
1584
  function has_default_values($entity)
447
  if ($this->is_select_statement()) {
448
  $this->object->cache($cache_key, $results);
449
  }
450
+ remove_action('pre_get_posts', array(&$this, 'set_query_args'), PHP_INT_MAX - 1);
451
  }
452
  // Convert the result
453
  if ($convert_to_entities) {
1108
  }
1109
  function initialize($object_name = FALSE)
1110
  {
1111
+ parent::initialize();
1112
  if (!isset($this->_primary_key_column)) {
1113
  $this->_primary_key_column = $this->_lookup_primary_key_column();
1114
  }
1115
+ $this->migrate();
1116
  }
1117
  /**
1118
  * Returns the database connection object for WordPress
1578
  * implementation. The implementation should make use of the
1579
  * _set_default_value() method
1580
  */
1581
+ function set_defaults($stdObject)
1582
  {
1583
  }
1584
  function has_default_values($entity)
products/photocrati_nextgen/modules/dynamic_thumbnails/package.module.dynamic_thumbnails.php CHANGED
@@ -114,7 +114,7 @@ class C_Dynamic_Thumbnails_Controller extends C_MVC_Controller
114
  }
115
  return self::$_instances[$context];
116
  }
117
- function index_action()
118
  {
119
  $dynthumbs = C_Dynamic_Thumbnails_Manager::get_instance();
120
  $uri = $_SERVER['REQUEST_URI'];
@@ -321,7 +321,7 @@ class Mixin_Dynamic_Thumbnails_Manager extends Mixin
321
  if ($extension != null) {
322
  $extension = '.' . $extension;
323
  }
324
- $name .= M_I18n::mb_basename($image->filename, $extension);
325
  $name .= '-';
326
  if ($id_in_name) {
327
  $image_id = strval($image->pid);
@@ -389,7 +389,7 @@ class Mixin_Dynamic_Thumbnails_Manager extends Mixin
389
  if ($extension != null) {
390
  $extension = '.' . $extension;
391
  }
392
- $name = M_I18n::mb_basename($name, $extension);
393
  }
394
  $size_index = strrpos($name, $size_prefix);
395
  if ($size_index > 0 || $size_index === 0) {
114
  }
115
  return self::$_instances[$context];
116
  }
117
+ function index_action($return = FALSE)
118
  {
119
  $dynthumbs = C_Dynamic_Thumbnails_Manager::get_instance();
120
  $uri = $_SERVER['REQUEST_URI'];
321
  if ($extension != null) {
322
  $extension = '.' . $extension;
323
  }
324
+ $name .= M_I18n::mb_basename($image->filename);
325
  $name .= '-';
326
  if ($id_in_name) {
327
  $image_id = strval($image->pid);
389
  if ($extension != null) {
390
  $extension = '.' . $extension;
391
  }
392
+ $name = M_I18n::mb_basename($name);
393
  }
394
  $size_index = strrpos($name, $size_prefix);
395
  if ($size_index > 0 || $size_index === 0) {
products/photocrati_nextgen/modules/i18n/lang/nggallery-sv_SE.po CHANGED
@@ -2431,8 +2431,8 @@ msgid "Server Settings"
2431
  msgstr "Serverinställningar"
2432
 
2433
  #: products/photocrati_nextgen/modules/ngglegacy/admin/overview.php:97
2434
- msgid "NextGEN Gallery is one of the most popular WordPress plugins of all time with over 17 million downloads."
2435
- msgstr "NextGEN Gallery är en av de mest populära WordPress-tilläggen genom tiderna med över 17 miljoner nedladdningar."
2436
 
2437
  # Missed by NextGEN, translated string is displayed.
2438
  #: products/photocrati_nextgen/modules/ngglegacy/admin/overview.php:97
@@ -3222,8 +3222,8 @@ msgid "https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/"
3222
  msgstr "https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/"
3223
 
3224
  #. Description of the plugin/theme
3225
- msgid "The most popular gallery plugin for WordPress and one of the most popular plugins of all time with over 12 million downloads."
3226
- msgstr "Det mest populära galleri-tillägget för WordPress och ett av de mest populära tillägg genom tiderna med över 12 miljoner nedladdningar."
3227
 
3228
  #. Author of the plugin/theme
3229
  msgid "Imagely"
2431
  msgstr "Serverinställningar"
2432
 
2433
  #: products/photocrati_nextgen/modules/ngglegacy/admin/overview.php:97
2434
+ msgid "NextGEN Gallery is one of the most popular WordPress plugins of all time with over 20 million downloads."
2435
+ msgstr "NextGEN Gallery är en av de mest populära WordPress-tilläggen genom tiderna med över 20 miljoner nedladdningar."
2436
 
2437
  # Missed by NextGEN, translated string is displayed.
2438
  #: products/photocrati_nextgen/modules/ngglegacy/admin/overview.php:97
3222
  msgstr "https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/"
3223
 
3224
  #. Description of the plugin/theme
3225
+ msgid "The most popular gallery plugin for WordPress and one of the most popular plugins of all time with over 20 million downloads."
3226
+ msgstr "Det mest populära galleri-tillägget för WordPress och ett av de mest populära tillägg genom tiderna med över 20 miljoner nedladdningar."
3227
 
3228
  #. Author of the plugin/theme
3229
  msgid "Imagely"
products/photocrati_nextgen/modules/i18n/lang/nggallery.po CHANGED
@@ -1,5 +1,5 @@
1
  # NextGEN Gallery base (English) .po source
2
- # Copyright (C) 2015 Photocrati Media
3
  # This file is distributed under the same license as the NextGEN Gallery package.
4
  #
5
  #, fuzzy
@@ -2446,7 +2446,7 @@ msgid "Server Settings"
2446
  msgstr ""
2447
 
2448
  #: products/photocrati_nextgen/modules/ngglegacy/admin/overview.php:97
2449
- msgid "NextGEN Gallery is one of the most popular WordPress plugins of all time with over 18 million downloads."
2450
  msgstr ""
2451
 
2452
  #: products/photocrati_nextgen/modules/ngglegacy/admin/overview.php:97
@@ -3231,7 +3231,7 @@ msgid "https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/"
3231
  msgstr ""
3232
 
3233
  #. Description of the plugin/theme
3234
- msgid "The most popular gallery plugin for WordPress and one of the most popular plugins of all time with over 17 million downloads."
3235
  msgstr ""
3236
 
3237
  #. Author of the plugin/theme
1
  # NextGEN Gallery base (English) .po source
2
+ # Copyright (C) 2018 Photocrati Media
3
  # This file is distributed under the same license as the NextGEN Gallery package.
4
  #
5
  #, fuzzy
2446
  msgstr ""
2447
 
2448
  #: products/photocrati_nextgen/modules/ngglegacy/admin/overview.php:97
2449
+ msgid "NextGEN Gallery is one of the most popular WordPress plugins of all time with over 20 million downloads."
2450
  msgstr ""
2451
 
2452
  #: products/photocrati_nextgen/modules/ngglegacy/admin/overview.php:97
3231
  msgstr ""
3232
 
3233
  #. Description of the plugin/theme
3234
+ msgid "The most popular gallery plugin for WordPress and one of the most popular plugins of all time with over 20 million downloads."
3235
  msgstr ""
3236
 
3237
  #. Author of the plugin/theme
products/photocrati_nextgen/modules/imagify/lib/class-imagify-partner.php ADDED
@@ -0,0 +1,877 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Tool allowing 3rd party WordPress plugins to handle partnership with Imagify.
4
+ *
5
+ * @package wp-media/wp-imagify-partner
6
+ */
7
+
8
+ defined( 'ABSPATH' ) || die( 'Cheatin\' uh?' );
9
+
10
+ if ( ! class_exists( 'Imagify_Partner' ) ) :
11
+
12
+ /**
13
+ * Class allowing to download, install, and activate Imagify plugin.
14
+ *
15
+ * @author Grégory Viguier
16
+ */
17
+ class Imagify_Partner {
18
+
19
+ /**
20
+ * Class version.
21
+ *
22
+ * @var string
23
+ */
24
+ const VERSION = '1.0';
25
+
26
+ /**
27
+ * Name of the option that stores the partner identifier.
28
+ *
29
+ * @var string
30
+ */
31
+ const OPTION_NAME = 'imagifyp_id';
32
+
33
+ /**
34
+ * Name of the transient that stores the error messages.
35
+ *
36
+ * @var string
37
+ */
38
+ const ERROR_TRANSIENT_NAME = 'imagifyp_error';
39
+
40
+ /**
41
+ * Name of the URL argument used on success.
42
+ *
43
+ * @var string
44
+ */
45
+ const SUCCESS_ARG = 'imp-success';
46
+
47
+ /**
48
+ * Name of the URL argument used to display an error notice.
49
+ *
50
+ * @var string
51
+ */
52
+ const ERROR_ARG = 'imp-error';
53
+
54
+ /**
55
+ * ID of the nonce used to install Imagify.
56
+ *
57
+ * @var string
58
+ */
59
+ const NONCE_NAME = 'install_imagify_from_partner';
60
+
61
+ /**
62
+ * Message used as fallback in get_message().
63
+ *
64
+ * @var string
65
+ */
66
+ const FALLBACK_MESSAGE = 'Unknown message';
67
+
68
+ /**
69
+ * Partner identifier.
70
+ *
71
+ * @var string
72
+ * @access protected
73
+ */
74
+ protected $partner;
75
+
76
+
77
+ /** ----------------------------------------------------------------------------------------- */
78
+ /** INSTANCE, INIT ========================================================================== */
79
+ /** ----------------------------------------------------------------------------------------- */
80
+
81
+ /**
82
+ * Class constructor: sanitize and set the partner identifier.
83
+ *
84
+ * @since 1.0
85
+ * @access public
86
+ * @author Grégory Viguier
87
+ *
88
+ * @param string $partner Partner identifier.
89
+ */
90
+ public function __construct( $partner ) {
91
+ $this->partner = self::sanitize_partner( $partner );
92
+ }
93
+
94
+ /**
95
+ * Class init.
96
+ *
97
+ * @since 1.0
98
+ * @access public
99
+ * @author Grégory Viguier
100
+ */
101
+ public function init() {
102
+ if ( ! $this->get_partner() ) {
103
+ return;
104
+ }
105
+
106
+ if ( ! is_admin() ) {
107
+ return;
108
+ }
109
+
110
+ if ( ! self::has_imagify_api_key() ) {
111
+ add_action( 'wp_ajax_' . $this->get_post_action(), array( $this, 'post_callback' ) );
112
+ add_action( 'admin_post_' . $this->get_post_action(), array( $this, 'post_callback' ) );
113
+ }
114
+
115
+ if ( self::is_success() || self::is_error() ) {
116
+ add_action( 'all_admin_notices', array( __CLASS__, 'error_notice' ) );
117
+ add_filter( 'removable_query_args', array( __CLASS__, 'add_query_args' ) );
118
+ }
119
+ }
120
+
121
+
122
+ /** ----------------------------------------------------------------------------------------- */
123
+ /** MAIN PUBLIC TOOLS ======================================================================= */
124
+ /** ----------------------------------------------------------------------------------------- */
125
+
126
+ /**
127
+ * Tell if Imagify's API key is set.
128
+ *
129
+ * @since 1.0
130
+ * @access public
131
+ * @author Grégory Viguier
132
+ *
133
+ * @return bool
134
+ */
135
+ public static function has_imagify_api_key() {
136
+ static $has;
137
+
138
+ if ( isset( $has ) ) {
139
+ return $has;
140
+ }
141
+
142
+ if ( function_exists( 'get_imagify_option' ) ) {
143
+ // Imagify is already installed and activated.
144
+ $has = (bool) get_imagify_option( 'api_key' );
145
+ return $has;
146
+ }
147
+
148
+ if ( defined( 'IMAGIFY_API_KEY' ) && IMAGIFY_API_KEY ) {
149
+ // It's defined in wp-config.php.
150
+ $has = true;
151
+ return $has;
152
+ }
153
+
154
+ if ( ! is_multisite() ) {
155
+ // Monosite: grab the value from the options table.
156
+ $options = get_option( 'imagify_settings' );
157
+ $has = ! empty( $options['api_key'] );
158
+ return $has;
159
+ }
160
+
161
+ $options = get_site_option( 'imagify_settings' );
162
+
163
+ if ( ! empty( $options['api_key'] ) ) {
164
+ // Multisite: Imagify was activated in the network.
165
+ $has = true;
166
+ return $has;
167
+ }
168
+
169
+ // Multisite: Imagify was activated for this site.
170
+ $options = get_option( 'imagify_settings' );
171
+ $has = ! empty( $options['api_key'] );
172
+ return $has;
173
+ }
174
+
175
+ /**
176
+ * Tell if Imagify is activated.
177
+ *
178
+ * @since 1.0
179
+ * @access public
180
+ * @author Grégory Viguier
181
+ *
182
+ * @return bool
183
+ */
184
+ public static function is_imagify_activated() {
185
+ return defined( 'IMAGIFY_VERSION' );
186
+ }
187
+
188
+ /**
189
+ * Tell if Imagify is installed.
190
+ *
191
+ * @since 1.0
192
+ * @access public
193
+ * @author Grégory Viguier
194
+ *
195
+ * @return bool
196
+ */
197
+ public static function is_imagify_installed() {
198
+ if ( self::is_imagify_activated() ) {
199
+ return true;
200
+ }
201
+
202
+ return file_exists( self::get_imagify_path() );
203
+ }
204
+
205
+ /**
206
+ * Tell if Imagify has been successfully installed.
207
+ *
208
+ * @since 1.0
209
+ * @access public
210
+ * @author Grégory Viguier
211
+ *
212
+ * @return bool
213
+ */
214
+ public static function is_success() {
215
+ return ! empty( $_GET[ self::SUCCESS_ARG ] ); // WPCS: CSRF ok.
216
+ }
217
+
218
+ /**
219
+ * Tell if Imagify install failed.
220
+ *
221
+ * @since 1.0
222
+ * @access public
223
+ * @author Grégory Viguier
224
+ *
225
+ * @return bool
226
+ */
227
+ public static function is_error() {
228
+ return ! empty( $_GET[ self::ERROR_ARG ] ); // WPCS: CSRF ok.
229
+ }
230
+
231
+ /**
232
+ * Get the URL to install and activate Imagify.
233
+ *
234
+ * @since 1.0
235
+ * @access public
236
+ * @author Grégory Viguier
237
+ *
238
+ * @return string The URL.
239
+ */
240
+ public function get_post_install_url() {
241
+ if ( ! $this->get_partner() || ! self::current_user_can() ) {
242
+ return '';
243
+ }
244
+
245
+ $install_url = admin_url( 'admin-post.php' );
246
+ $args = array(
247
+ 'action' => $this->get_post_action(),
248
+ '_wpnonce' => wp_create_nonce( self::NONCE_NAME ),
249
+ // To make sure we have a referrer.
250
+ '_wp_http_referer' => rawurlencode( self::get_current_url() ),
251
+ );
252
+
253
+ return add_query_arg( $args, $install_url );
254
+ }
255
+
256
+ /**
257
+ * Get the partner identifier.
258
+ *
259
+ * @since 1.0
260
+ * @access public
261
+ * @author Grégory Viguier
262
+ *
263
+ * @return string Partner identifier.
264
+ */
265
+ public function get_partner() {
266
+ return $this->partner;
267
+ }
268
+
269
+
270
+ /** ----------------------------------------------------------------------------------------- */
271
+ /** HOOKS =================================================================================== */
272
+ /** ----------------------------------------------------------------------------------------- */
273
+
274
+ /**
275
+ * Post callback to install and activate Imagify.
276
+ *
277
+ * @since 1.0
278
+ * @access public
279
+ * @author Grégory Viguier
280
+ */
281
+ public function post_callback() {
282
+ if ( ! check_ajax_referer( self::NONCE_NAME, '_wpnonce', false ) ) {
283
+ $this->error_die();
284
+ }
285
+
286
+ if ( ! self::current_user_can() ) {
287
+ $this->error_die( 'cant_install' );
288
+ }
289
+
290
+ /**
291
+ * Store the partner ID before doing anything.
292
+ * If something goes wrong during the plugin installation, the partner ID will still be saved.
293
+ */
294
+ self::store_partner( $this->get_partner() );
295
+
296
+ // Install Imagify.
297
+ $result = $this->install_imagify();
298
+
299
+ if ( is_wp_error( $result ) ) {
300
+ // Install failed.
301
+ if ( self::doing_ajax() ) {
302
+ $this->send_json_error( $result );
303
+ }
304
+ // Redirect to the plugins search page.
305
+ $this->error_redirect( $result );
306
+ }
307
+
308
+ // Activate Imagify.
309
+ $result = $this->activate_imagify();
310
+
311
+ if ( is_wp_error( $result ) ) {
312
+ // Activation failed.
313
+ if ( self::doing_ajax() ) {
314
+ $this->send_json_error( $result );
315
+ }
316
+ // Redirect to the plugins search page.
317
+ $this->error_redirect( $result );
318
+ }
319
+
320
+ if ( self::doing_ajax() ) {
321
+ $this->send_json_success();
322
+ }
323
+ // Redirect to the partner's page.
324
+ $this->success_redirect();
325
+ }
326
+
327
+ /**
328
+ * Maybe print an error notice on the plugins install page.
329
+ * We add the query argument we use to display an error message.
330
+ *
331
+ * @since 1.0
332
+ * @access public
333
+ * @author Grégory Viguier
334
+ */
335
+ public static function error_notice() {
336
+ if ( ! self::is_error() ) {
337
+ // No URL argument.
338
+ return;
339
+ }
340
+
341
+ $screen = get_current_screen();
342
+
343
+ if ( ! $screen || 'plugin-install' !== $screen->id ) {
344
+ // Not the good page.
345
+ return;
346
+ }
347
+
348
+ $partner = self::get_stored_partner();
349
+
350
+ if ( ! $partner ) {
351
+ // No partner stored in the database.
352
+ return;
353
+ }
354
+
355
+ $errors = get_transient( self::ERROR_TRANSIENT_NAME );
356
+
357
+ if ( ! $errors ) {
358
+ // No error messages.
359
+ return;
360
+ }
361
+
362
+ if ( ! is_wp_error( $errors ) ) {
363
+ // Invalid value.
364
+ delete_transient( self::ERROR_TRANSIENT_NAME );
365
+ return;
366
+ }
367
+
368
+ $errors = $errors->get_error_messages();
369
+
370
+ if ( $errors ) {
371
+ foreach ( $errors as $i => $error ) {
372
+ if ( self::FALLBACK_MESSAGE === $error ) {
373
+ unset( $errors[ $i ] );
374
+ }
375
+ }
376
+ }
377
+
378
+ if ( ! $errors ) {
379
+ // Add a generic message.
380
+ $instance = new self( $partner );
381
+ $errors[] = $instance->get_message( 'process_failed' );
382
+ }
383
+
384
+ echo '<div class="error notice is-dismissible"><p>' . implode( '<br/>', $errors ) . '</p></div>';
385
+ }
386
+
387
+ /**
388
+ * Filter the list of query variables to remove from admin area URLs.
389
+ * We add the query arguments we use on success or error.
390
+ *
391
+ * @since 1.0
392
+ * @access public
393
+ * @see wp_removable_query_args()
394
+ * @author Grégory Viguier
395
+ *
396
+ * @param array $removable_query_args An array of query variables to remove from a URL.
397
+ * @return array
398
+ */
399
+ public static function add_query_args( $removable_query_args ) {
400
+ $removable_query_args[] = self::SUCCESS_ARG;
401
+ $removable_query_args[] = self::ERROR_ARG;
402
+ return $removable_query_args;
403
+ }
404
+
405
+
406
+ /** ----------------------------------------------------------------------------------------- */
407
+ /** INFOS, INSTALL, ACTIVATE ================================================================ */
408
+ /** ----------------------------------------------------------------------------------------- */
409
+
410
+ /**
411
+ * Get Imagify infos from the repository.
412
+ *
413
+ * @since 1.0
414
+ * @access protected
415
+ * @author Grégory Viguier
416
+ *
417
+ * @return object The plugin infos on success. A WP_Error object on failure.
418
+ */
419
+ protected function get_imagify_infos() {
420
+ static $infos;
421
+
422
+ if ( isset( $infos ) ) {
423
+ return $infos;
424
+ }
425
+
426
+ require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
427
+
428
+ // Get Plugin Infos.
429
+ $infos = plugins_api( 'plugin_information', array(
430
+ 'slug' => 'imagify',
431
+ 'fields' => array(
432
+ 'short_description' => false,
433
+ 'sections' => false,
434
+ 'rating' => false,
435
+ 'ratings' => false,
436
+ 'downloaded' => false,
437
+ 'last_updated' => false,
438
+ 'added' => false,
439
+ 'tags' => false,
440
+ 'homepage' => false,
441
+ 'donate_link' => false,
442
+ ),
443
+ ) );
444
+
445
+ return $infos;
446
+ }
447
+
448
+ /**
449
+ * Get the URL to download Imagify.
450
+ *
451
+ * @since 1.0
452
+ * @access protected
453
+ * @author Grégory Viguier
454
+ *
455
+ * @return string The URL. An empty string on error.
456
+ */
457
+ protected function get_download_url() {
458
+ $infos = $this->get_imagify_infos();
459
+ return ! empty( $infos->download_link ) ? $infos->download_link : '';
460
+ }
461
+
462
+ /**
463
+ * Install Imagify.
464
+ *
465
+ * @since 1.0
466
+ * @access protected
467
+ * @author Grégory Viguier
468
+ *
469
+ * @return object|null A WP_Object on failure, null on success.
470
+ */
471
+ protected function install_imagify() {
472
+ if ( self::is_imagify_installed() ) {
473
+ // Imagify is already installed.
474
+ return null;
475
+ }
476
+
477
+ $infos = $this->get_imagify_infos();
478
+
479
+ if ( is_wp_error( $infos ) ) {
480
+ return $infos;
481
+ }
482
+
483
+ ob_start();
484
+ @set_time_limit( 0 );
485
+
486
+ require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
487
+
488
+ $upgrader = new Plugin_Upgrader( new Automatic_Upgrader_Skin() );
489
+ $result = $upgrader->install( $this->get_download_url() );
490
+
491
+ ob_end_clean();
492
+
493
+ if ( is_wp_error( $result ) ) {
494
+ return $result;
495
+ }
496
+
497
+ clearstatcache();
498
+
499
+ if ( ! self::is_imagify_installed() ) {
500
+ return new WP_Error( 'process_failed', $this->get_message( 'process_failed' ) );
501
+ }
502
+
503
+ return null;
504
+ }
505
+
506
+ /**
507
+ * Activate Imagify.
508
+ *
509
+ * @since 1.0
510
+ * @access protected
511
+ * @author Grégory Viguier
512
+ *
513
+ * @return object|null A WP_Object on failure, null on success.
514
+ */
515
+ protected function activate_imagify() {
516
+ return activate_plugin( self::get_imagify_path(), false, is_multisite() );
517
+ }
518
+
519
+ /**
520
+ * Get a message used by the class.
521
+ *
522
+ * @since 1.0
523
+ * @access protected
524
+ * @author Grégory Viguier
525
+ *
526
+ * @param string $message_id A message ID.
527
+ * @return string A message.
528
+ */
529
+ protected function get_message( $message_id ) {
530
+ $messages = array(
531
+ 'success' => __( 'Plugin installed successfully.' ),
532
+ 'cant_install' => __( 'Sorry, you are not allowed to install plugins on this site.' ),
533
+ 'not_allowed' => __( 'Sorry, you are not allowed to do that.' ),
534
+ 'process_failed' => __( 'Plugin install failed.' ),
535
+ 'go_back' => __( 'Go back' ),
536
+ );
537
+
538
+ /**
539
+ * Filter messages used everywhere in the class.
540
+ * Default messages are already translated by WordPress.
541
+ *
542
+ * @since 1.0
543
+ * @author Grégory Viguier
544
+ *
545
+ * @param array $messages Messages.
546
+ */
547
+ $messages = apply_filters( 'imagify_partner_messages_' . $this->get_partner(), $messages );
548
+
549
+ return ! empty( $messages[ $message_id ] ) ? $messages[ $message_id ] : self::FALLBACK_MESSAGE;
550
+ }
551
+
552
+
553
+ /** ----------------------------------------------------------------------------------------- */
554
+ /** HANDLE SUCCESS ========================================================================== */
555
+ /** ----------------------------------------------------------------------------------------- */
556
+
557
+ /**
558
+ * Send a JSON response back to an Ajax request, indicating success.
559
+ *
560
+ * @since 1.0
561
+ * @access protected
562
+ * @author Grégory Viguier
563
+ */
564
+ protected function send_json_success() {
565
+ delete_transient( self::ERROR_TRANSIENT_NAME );
566
+
567
+ wp_send_json_success( $this->get_message( 'success' ) );
568
+ }
569
+
570
+ /**
571
+ * Redirect the user after Imagify is successfully installed and activated.
572
+ *
573
+ * @since 1.0
574
+ * @access protected
575
+ * @author Grégory Viguier
576
+ */
577
+ protected function success_redirect() {
578
+ delete_transient( self::ERROR_TRANSIENT_NAME );
579
+
580
+ wp_safe_redirect( esc_url_raw( $this->get_success_redirection_url() ) );
581
+ die();
582
+ }
583
+
584
+ /**
585
+ * Get the URL to redirect the user to after Imagify is successfully installed and activated: the referrer (partner's page URL).
586
+ * A "success" argument is added.
587
+ *
588
+ * @since 1.0
589
+ * @access public
590
+ * @author Grégory Viguier
591
+ *
592
+ * @return string
593
+ */
594
+ public function get_success_redirection_url() {
595
+ $success_url = add_query_arg( array(
596
+ self::SUCCESS_ARG => 1,
597
+ self::ERROR_ARG => false,
598
+ ), wp_get_referer() );
599
+
600
+ /**
601
+ * Filter the URL to redirect the user to after Imagify is successfully installed and activated.
602
+ * Default is the partner's page URL.
603
+ *
604
+ * @since 1.0
605
+ * @author Grégory Viguier
606
+ *
607
+ * @param string $success_url The URL.
608
+ */
609
+ return apply_filters( 'imagify_partner_success_url_' . $this->get_partner(), $success_url );
610
+ }
611
+
612
+
613
+ /** ----------------------------------------------------------------------------------------- */
614
+ /** HANDLE ERROR ============================================================================ */
615
+ /** ----------------------------------------------------------------------------------------- */
616
+
617
+ /**
618
+ * Die on error.
619
+ *
620
+ * @since 1.0
621
+ * @access protected
622
+ * @author Grégory Viguier
623
+ *
624
+ * @param string $message_id An error message ID.
625
+ */
626
+ protected function error_die( $message_id = 'not_allowed' ) {
627
+ $message = $this->get_message( $message_id );
628
+
629
+ if ( self::doing_ajax() ) {
630
+ $message = new WP_Error( $message_id, $message );
631
+ $this->send_json_error( $message );
632
+ }
633
+
634
+ if ( wp_get_referer() ) {
635
+ $message .= '</p><p>';
636
+ $message .= sprintf( '<a href="%s">%s</a>',
637
+ esc_url( remove_query_arg( 'updated', wp_get_referer() ) ),
638
+ $this->get_message( 'go_back' )
639
+ );
640
+ }
641
+
642
+ wp_die( $message, '', 403 );
643
+ }
644
+
645
+ /**
646
+ * Send a JSON response back to an Ajax request, indicating failure.
647
+ * This is a backward compatible version of wp_send_json_error(): WP_Error object handling was introduced in WP 4.1.
648
+ *
649
+ * @since 1.0
650
+ * @access protected
651
+ * @author Grégory Viguier
652
+ *
653
+ * @param mixed $data Data to encode as JSON, then print and die.
654
+ */
655
+ protected function send_json_error( $data ) {
656
+ if ( is_wp_error( $data ) ) {
657
+ $result = array();
658
+ foreach ( $data->errors as $code => $messages ) {
659
+ foreach ( $messages as $message ) {
660
+ $result[] = array(
661
+ 'code' => $code,
662
+ 'message' => $message,
663
+ );
664
+ }
665
+ }
666
+ } else {
667
+ $result = $data;
668
+ }
669
+
670
+ wp_send_json_error( $result );
671
+ }
672
+
673
+ /**
674
+ * Store an error message in a transient then redirect the user.
675
+ *
676
+ * @since 1.0
677
+ * @access protected
678
+ * @author Grégory Viguier
679
+ *
680
+ * @param object $error A WP_Error object.
681
+ */
682
+ protected function error_redirect( $error ) {
683
+ set_transient( self::ERROR_TRANSIENT_NAME, $error, 30 );
684
+
685
+ wp_safe_redirect( esc_url_raw( $this->get_error_redirection_url() ) );
686
+ die();
687
+ }
688
+
689
+ /**
690
+ * Get the URL to redirect the user to after Imagify installation failure: the plugins search page URL, searching for Imagify.
691
+ * An "error" argument is added, to display an error notice.
692
+ *
693
+ * @since 1.0
694
+ * @access public
695
+ * @author Grégory Viguier
696
+ *
697
+ * @return string
698
+ */
699
+ public function get_error_redirection_url() {
700
+ $error_url = 'plugin-install.php?s=imagify&tab=search&type=term&' . self::ERROR_ARG . '=1';
701
+ $error_url = is_multisite() ? network_admin_url( $error_url ) : admin_url( $error_url );
702
+
703
+ /**
704
+ * Filter the URL to redirect the user to after Imagify installation failure.
705
+ * Default is the plugins search page URL.
706
+ *
707
+ * @since 1.0
708
+ * @author Grégory Viguier
709
+ *
710
+ * @param string $error_url The URL.
711
+ */
712
+ return apply_filters( 'imagify_partner_error_url_' . $this->get_partner(), $error_url );
713
+ }
714
+
715
+
716
+ /** ----------------------------------------------------------------------------------------- */
717
+ /** STORING THE PARTNER ID IN DATABASE ====================================================== */
718
+ /** ----------------------------------------------------------------------------------------- */
719
+
720
+ /**
721
+ * Get the partner identifier stored in the Database.
722
+ *
723
+ * @since 1.0
724
+ * @access public
725
+ * @author Grégory Viguier
726
+ *
727
+ * @return string|bool The partner identifier, or false if none is stored.
728
+ */
729
+ public static function get_stored_partner() {
730
+ $partner = get_option( self::OPTION_NAME );
731
+
732
+ if ( $partner && is_string( $partner ) ) {
733
+ $partner = self::sanitize_partner( $partner );
734
+ }
735
+
736
+ return $partner ? $partner : false;
737
+ }
738
+
739
+ /**
740
+ * Delete the partner identifier stored in the Database.
741
+ *
742
+ * @since 1.0
743
+ * @access public
744
+ * @author Grégory Viguier
745
+ */
746
+ public static function delete_stored_partner() {
747
+ if ( false !== get_option( self::OPTION_NAME ) ) {
748
+ delete_option( self::OPTION_NAME );
749
+ }
750
+ }
751
+
752
+ /**
753
+ * Store the partner identifier in Database.
754
+ *
755
+ * @since 1.0
756
+ * @access protected
757
+ * @author Grégory Viguier
758
+ *
759
+ * @param string $partner The partner identifier to store.
760
+ */
761
+ protected static function store_partner( $partner ) {
762
+ if ( false === get_option( self::OPTION_NAME ) ) {
763
+ add_option( self::OPTION_NAME, $partner );
764
+ } else {
765
+ update_option( self::OPTION_NAME, $partner );
766
+ }
767
+ }
768
+
769
+ /**
770
+ * Sanitize a partner ID.
771
+ *
772
+ * @since 1.0
773
+ * @access protected
774
+ * @author Grégory Viguier
775
+ *
776
+ * @param string $partner Partner identifier.
777
+ * @return string
778
+ */
779
+ protected static function sanitize_partner( $partner ) {
780
+ return preg_replace( '@[^a-z0-9_-]@', '', strtolower( (string) $partner ) );
781
+ }
782
+
783
+
784
+ /** ----------------------------------------------------------------------------------------- */
785
+ /** VARIOUS TOOLS =========================================================================== */
786
+ /** ----------------------------------------------------------------------------------------- */
787
+
788
+ /**
789
+ * Get the action.
790
+ *
791
+ * @since 1.0
792
+ * @access public
793
+ * @author Grégory Viguier
794
+ *
795
+ * @return string Partner identifier.
796
+ */
797
+ public function get_post_action() {
798
+ return 'install_imagify_from_partner_' . $this->get_partner();
799
+ }
800
+
801
+ /**
802
+ * Determines whether the current request is a WordPress Ajax request.
803
+ * This is a clone of wp_doing_ajax(), intriduced in WP 4.7.
804
+ *
805
+ * @since 1.0
806
+ * @access public
807
+ * @author Grégory Viguier
808
+ *
809
+ * @return bool True if it's a WordPress Ajax request, false otherwise.
810
+ */
811
+ public static function doing_ajax() {
812
+ /**
813
+ * Filters whether the current request is a WordPress Ajax request.
814
+ *
815
+ * @since 1.0
816
+ *
817
+ * @param bool $wp_doing_ajax Whether the current request is a WordPress Ajax request.
818
+ */
819
+ return apply_filters( 'wp_doing_ajax', defined( 'DOING_AJAX' ) && DOING_AJAX );
820
+ }
821
+
822
+ /**
823
+ * Get Imagify's file path.
824
+ *
825
+ * @since 1.0
826
+ * @access public
827
+ * @author Grégory Viguier
828
+ *
829
+ * @return string The file path.
830
+ */
831
+ public static function get_imagify_path() {
832
+ if ( defined( 'IMAGIFY_FILE' ) ) {
833
+ return IMAGIFY_FILE;
834
+ }
835
+
836
+ return WP_PLUGIN_DIR . '/imagify/imagify.php';
837
+ }
838
+
839
+ /**
840
+ * Tell if the current user can install and activate Imagify.
841
+ *
842
+ * @since 1.0
843
+ * @access public
844
+ * @author Grégory Viguier
845
+ *
846
+ * @return bool
847
+ */
848
+ public static function current_user_can() {
849
+ static $can;
850
+
851
+ if ( ! isset( $can ) ) {
852
+ $can = is_multisite() ? 'manage_network_plugins' : 'install_plugins';
853
+ $can = current_user_can( $can );
854
+ }
855
+
856
+ return $can;
857
+ }
858
+
859
+ /**
860
+ * Get the current URL.
861
+ *
862
+ * @since 1.0
863
+ * @access public
864
+ * @author Grégory Viguier
865
+ *
866
+ * @return string
867
+ */
868
+ public static function get_current_url() {
869
+ $port = (int) $_SERVER['SERVER_PORT'];
870
+ $port = 80 !== $port && 443 !== $port ? ( ':' . $port ) : '';
871
+ $url = ! empty( $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] ) ? $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI'] : ( ! empty( $_SERVER['REQUEST_URI'] ) ? $_SERVER['REQUEST_URI'] : '' );
872
+
873
+ return 'http' . ( is_ssl() ? 's' : '' ) . '://' . $_SERVER['HTTP_HOST'] . $port . $url;
874
+ }
875
+ }
876
+
877
+ endif;
products/photocrati_nextgen/modules/imagify/module.imagify.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ {
4
+ Module: photocrati-imagify,
5
+ Depends: { photocrati-nextgen_admin }
6
+ }
7
+ */
8
+
9
+ define('IMAGELY_IMAGIFY_PARTNER_ID' , 'nextgen-gallery');
10
+
11
+ require_once('lib' . DIRECTORY_SEPARATOR . 'class-imagify-partner.php');
12
+
13
+ class M_Imagify extends C_Base_Module
14
+ {
15
+ protected static $_imagify_client = NULL;
16
+
17
+ function define($id = 'pope-module',
18
+ $name = 'Pope Module',
19
+ $description = '',
20
+ $version = '',
21
+ $uri = '',
22
+ $author = '',
23
+ $author_uri = '',
24
+ $context = FALSE)
25
+ {
26
+ parent::define(
27
+ 'photocrati-imagify',
28
+ 'NextGEN Imagify Integration',
29
+ 'NextGen Gallery / Imagify Integration',
30
+ '0.4',
31
+ 'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
32
+ 'Imagely',
33
+ 'https://www.imagely.com'
34
+ );
35
+ }
36
+
37
+ static function get_imagify_client()
38
+ {
39
+ if (!self::$_imagify_client) {
40
+ self::$_imagify_client = new Imagify_Partner(IMAGELY_IMAGIFY_PARTNER_ID);
41
+ self::$_imagify_client->init();
42
+ }
43
+ return self::$_imagify_client;
44
+ }
45
+
46
+ function _register_adapters()
47
+ {
48
+ // TODO: check for PHP 5.2
49
+ if (is_admin())
50
+ {
51
+ $this->get_registry()
52
+ ->add_adapter('I_Page_Manager', 'A_Imagify_Admin_Page');
53
+ $this->get_registry()
54
+ ->add_adapter('I_NextGen_Admin_Page', 'A_Imagify_Admin_Page_Controller', 'ngg_imagify');
55
+ }
56
+ }
57
+
58
+ function _register_hooks()
59
+ {
60
+ if (($client = self::get_imagify_client())) {
61
+ add_filter(
62
+ 'imagify_partner_success_url_' . $client->get_partner(),
63
+ array($this, 'set_imagify_success_redirect_url')
64
+ );
65
+ }
66
+ }
67
+
68
+ function set_imagify_success_redirect_url($url)
69
+ {
70
+ return get_admin_url(NULL, 'admin.php?page=imagify-ngg-bulk-optimization');
71
+ }
72
+
73
+ function get_type_list()
74
+ {
75
+ return array(
76
+ 'A_Imagify_Admin_Page_Controller' => 'adapter.imagify_admin_page_controller.php',
77
+ 'A_Imagify_Admin_Page' => 'adapter.imagify_admin_page.php'
78
+ );
79
+ }
80
+ }
81
+
82
+ new M_Imagify;
products/photocrati_nextgen/modules/imagify/package.module.imagify.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class A_Imagify_Admin_Page extends Mixin
3
+ {
4
+ function setup()
5
+ {
6
+ // This hides the imagify page from the menu while still allowing it to display
7
+ if (defined('IMAGIFY_VERSION')) {
8
+ $parent = NULL;
9
+ } else {
10
+ $parent = NGGFOLDER;
11
+ }
12
+ $this->object->add('ngg_imagify', array('adapter' => 'A_Imagify_Admin_Page_Controller', 'parent' => $parent));
13
+ return $this->call_parent('setup');
14
+ }
15
+ }
16
+ class A_Imagify_Admin_Page_Controller extends Mixin
17
+ {
18
+ function enqueue_backend_resources()
19
+ {
20
+ $this->call_parent('enqueue_backend_resources');
21
+ wp_enqueue_style('imagify_upgrade_page', $this->get_static_url('photocrati-imagify#style.css'), FALSE, NGG_SCRIPT_VERSION);
22
+ }
23
+ function get_page_title()
24
+ {
25
+ return __('Image Optimization', 'nggallery');
26
+ }
27
+ function get_required_permission()
28
+ {
29
+ // TODO: must be able to install plugins
30
+ return 'NextGEN Change options';
31
+ }
32
+ function get_i18n_strings()
33
+ {
34
+ $i18n = new stdClass();
35
+ $i18n->title = __('Image Optimization');
36
+ $i18n->message = __('NextGEN Gallery partners with Imagify for best-in-class image optimization. Compress images to make galleries faster, all while maintaining image quality.', 'nggallery');
37
+ $i18n->confirmation = '';
38
+ $i18n->button = '';
39
+ $i18n->third_party_message = __('Note: Imagify is a third party plugin. It is not built or supported by NextGEN Gallery.', 'nggallery');
40
+ // $i18n->review_message = __( 'For more on why we recommend compressing images and why we recommend Imagify, check out our ', 'nggallery' );
41
+ $i18n->more_message = __('More on Imagify:', 'nggallery');
42
+ $i18n->review_message = __('More on why we recommend Imagify:', 'nggallery');
43
+ $i18n->imagify_plugin_link = __('Imagify Plugin Page', 'nggallery');
44
+ $i18n->imagify_website_link = __('Imagify Website', 'nggallery');
45
+ $i18n->imagify_review_link = __('Our Review of Image Compression Plugins', 'nggallery');
46
+ if (Imagify_Partner::is_imagify_activated()) {
47
+ if (Imagify_Partner::is_success()) {
48
+ $i18n->confirmation = __('Imagify has been successfully activated', 'nggallery');
49
+ } else {
50
+ $i18n->confirmation = __('Imagify is already activated', 'nggallery');
51
+ }
52
+ } else {
53
+ if (Imagify_Partner::is_imagify_installed()) {
54
+ $i18n->button = __('Activate Imagify', 'nggallery');
55
+ } else {
56
+ $i18n->button = __('Install and activate Imagify', 'nggallery');
57
+ }
58
+ }
59
+ return $i18n;
60
+ }
61
+ function index_action()
62
+ {
63
+ $this->object->enqueue_backend_resources();
64
+ $key = C_Photocrati_Transient_Manager::create_key('ngg_imagify_page', 'html');
65
+ if ($html = C_Photocrati_Transient_Manager::fetch($key, FALSE)) {
66
+ echo $html;
67
+ } else {
68
+ $imagify_install_url = NULL;
69
+ if ($client = M_Imagify::get_imagify_client()) {
70
+ $imagify_install_url = $client->get_post_install_url();
71
+ }
72
+ print $this->render_view('photocrati-imagify#admin_page', array('i18n' => $this->get_i18n_strings(), 'is_imagify_activated' => Imagify_Partner::is_imagify_activated(), 'imagify_install_url' => $imagify_install_url, 'imagify_plugin_url' => 'https://wordpress.org/plugins/imagify/', 'imagify_website_url' => 'https://imagify.io/?utm_source=nextgen-gallery&utm_campaign=plugin_partner&utm_medium=partnership', 'imagify_review_url' => 'https://www.imagely.com/image-optimization-plugin-comparison/'), TRUE);
73
+ C_Photocrati_Transient_Manager::update($key, $html);
74
+ }
75
+ }
76
+ }
products/photocrati_nextgen/modules/imagify/static/imagify_preview.png ADDED
Binary file
products/photocrati_nextgen/modules/imagify/static/style.css ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ .gallery_page_ngg_imagify_ad #update-nag,
3
+ .gallery_page_ngg_imagify_ad .update-nag {
4
+ display:none;
5
+ }
6
+
7
+ #imagify_upgrade_page {
8
+ max-width: none;
9
+ }
10
+
11
+ #imagify_upgrade_page h1 {
12
+ margin: 40px 0 20px;
13
+ }
14
+
15
+ #imagify_upgrade_page .about-text {
16
+ margin-right: 100px;
17
+ }
18
+
19
+ #imagify_upgrade_page p {
20
+ min-height: auto;
21
+ margin: 5px 0;
22
+ max-width: none;
23
+ color: #999;
24
+ width: 30%;
25
+ /*float: left;*/
26
+ max-width: 400px;
27
+ box-sizing: border-box;
28
+ font-size: 22px;
29
+ }
30
+
31
+ #imagify_upgrade_page .imagify-information {
32
+ font-size: 15px;
33
+ color: black;
34
+ color: #000;
35
+ margin: 5px 0 10px;
36
+ }
37
+
38
+ #imagify_upgrade_page .imagify-information.imagify-third-party {
39
+ font-weight: bold;
40
+ }
41
+
42
+ #imagify_upgrade_page .imagify-information a {
43
+ color: #76a934;
44
+ text-decoration: none;
45
+ }
46
+
47
+ #imagify_upgrade_page .feature-section {
48
+ float: right;
49
+ width: 62%;
50
+ max-width: 800px;
51
+ /*margin-top: 15px;*/
52
+ box-sizing: border-box;
53
+ margin-left: 8%;
54
+ padding: 0;
55
+ border: 1px solid #eee;
56
+ margin-top: -70px;
57
+ }
58
+
59
+ #imagify_upgrade_page img {
60
+ width: 800px;
61
+ max-width: 100%;
62
+ }
63
+
64
+ #imagify_upgrade_page a.button-primary {
65
+ font-size: 14px;
66
+ background-color: #76a934;
67
+ border: none;
68
+ box-shadow: none;
69
+ text-transform: uppercase;
70
+ height: 50px;
71
+ width: 300px;
72
+ max-width: 100%;
73
+ padding: 12px 22px;
74
+ text-shadow: none;
75
+ text-align: center;
76
+ margin: 40px 0 30px;
77
+ font-weight: bold;
78
+ }
79
+
80
+ #imagify_upgrade_page .ngg-imagify-third-party {
81
+ font-weight: bold;
82
+ }
83
+
84
+ @media (min-width: 1920px) {
85
+ #imagify_upgrade_page .feature-section {
86
+ margin-left: 50px;
87
+ }
88
+ }
89
+
90
+ @media (max-width: 1350px) {
91
+ #imagify_upgrade_page .feature-section {
92
+ margin-top: 20px;
93
+ }
94
+ }
95
+
96
+ @media (max-width: 1300px) {
97
+ #imagify_upgrade_page p {
98
+ width: 33%;
99
+ }
100
+ #imagify_upgrade_page .feature-section {
101
+ width: 59%;
102
+ }
103
+ #imagify_upgrade_page .about-text {
104
+ margin-right: 50px;
105
+ }
106
+ }
107
+
108
+ @media (max-width: 1150px) {
109
+ #imagify_upgrade_page p {
110
+ width: 100%;
111
+ max-width: 100%;
112
+ float: none;
113
+ }
114
+ #imagify_upgrade_page .feature-section {
115
+ float: none;
116
+ width: 100%;
117
+ margin-left: 0;
118
+ margin-top: 0;
119
+ }
120
+ #imagify_upgrade_page a.button-primary {
121
+ margin: 40px 0 30px;
122
+ }
123
+ }
124
+
125
+ @media (max-width: 600px) {
126
+ #imagify_upgrade_page h1 {
127
+ font-size: 2.2em;
128
+ }
129
+ #imagify_upgrade_page .about-text {
130
+ margin-right: 20px;
131
+ }
132
+ }
products/photocrati_nextgen/modules/imagify/static/style.min.css ADDED
@@ -0,0 +1 @@
 
1
+ #imagify_upgrade_page .imagify-information.imagify-third-party,#imagify_upgrade_page .ngg-imagify-third-party{font-weight:700}.gallery_page_ngg_imagify_ad #update-nag,.gallery_page_ngg_imagify_ad .update-nag{display:none}#imagify_upgrade_page{max-width:none}#imagify_upgrade_page h1{margin:40px 0 20px}#imagify_upgrade_page .about-text{margin-right:100px}#imagify_upgrade_page p{min-height:auto;margin:5px 0;color:#999;width:30%;max-width:400px;box-sizing:border-box;font-size:22px}#imagify_upgrade_page .imagify-information{font-size:15px;color:#000;margin:5px 0 10px}#imagify_upgrade_page .imagify-information a{color:#76a934;text-decoration:none}#imagify_upgrade_page .feature-section{float:right;width:62%;max-width:800px;box-sizing:border-box;margin-left:8%;padding:0;border:1px solid #eee;margin-top:-70px}#imagify_upgrade_page img{width:800px;max-width:100%}#imagify_upgrade_page a.button-primary{font-size:14px;background-color:#76a934;border:none;box-shadow:none;text-transform:uppercase;height:50px;width:300px;max-width:100%;padding:12px 22px;text-shadow:none;text-align:center;margin:40px 0 30px;font-weight:700}@media (min-width:1920px){#imagify_upgrade_page .feature-section{margin-left:50px}}@media (max-width:1350px){#imagify_upgrade_page .feature-section{margin-top:20px}}@media (max-width:1300px){#imagify_upgrade_page p{width:33%}#imagify_upgrade_page .feature-section{width:59%}#imagify_upgrade_page .about-text{margin-right:50px}}@media (max-width:1150px){#imagify_upgrade_page p{width:100%;max-width:100%;float:none}#imagify_upgrade_page .feature-section{float:none;width:100%;margin-left:0;margin-top:0}#imagify_upgrade_page a.button-primary{margin:40px 0 30px}}@media (max-width:600px){#imagify_upgrade_page h1{font-size:2.2em}#imagify_upgrade_page .about-text{margin-right:20px}}
products/photocrati_nextgen/modules/imagify/templates/admin_page.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div id='imagify_upgrade_page' class="wrap about-wrap nextgen_plus">
2
+ <h1><?php esc_html_e($i18n->title); ?></h1>
3
+ <div class="about-text">
4
+ <?php if ($is_imagify_activated): ?>
5
+ <?php esc_html_e($i18n->confirmation); ?>
6
+ <?php elseif ($imagify_install_url): ?>
7
+ <div class="feature-section">
8
+ <img src="https://f001.backblazeb2.com/file/nextgen-gallery/imagify_preview.png"></iframe>
9
+ </div>
10
+ <p class="imagify-main-message"><?php esc_html_e($i18n->message); ?></p>
11
+ <p><?php print '<a class="button-primary" href="' . $imagify_install_url . '">' . $i18n->button . '</a>'; ?></p>
12
+ <p class="imagify-information imagify-third-party"><?php esc_html_e($i18n->third_party_message); ?></p>
13
+ <p class="imagify-information"><?php esc_html_e($i18n->more_message); ?><br>
14
+ <?php print '<a target="_blank" href="' . $imagify_plugin_url . '">' . $i18n->imagify_plugin_link . '</a>'; ?><br>
15
+ <?php print '<a target="_blank" href="' . $imagify_website_url . '">' . $i18n->imagify_website_link . '</a>'; ?><br>
16
+ </p>
17
+ <p class="imagify-information"><?php esc_html_e($i18n->review_message); ?><br>
18
+ <?php print '<a target="_blank" href="' . $imagify_review_url . '">' . $i18n->imagify_review_link . '</a>'; ?>
19
+ </p>
20
+ <?php endif ?>
21
+ </div>
22
+ </div>
products/photocrati_nextgen/modules/lightbox/package.module.lightbox.php CHANGED
@@ -318,7 +318,7 @@ class C_NGG_Lightbox extends C_Component
318
  }
319
  function initialize($name = '', $properties = array())
320
  {
321
- parent::initialize($name);
322
  $properties['name'] = $name;
323
  foreach ($properties as $k => $v) {
324
  $this->{$k} = $v;
318
  }
319
  function initialize($name = '', $properties = array())
320
  {
321
+ parent::initialize();
322
  $properties['name'] = $name;
323
  foreach ($properties as $k => $v) {
324
  $this->{$k} = $v;
products/photocrati_nextgen/modules/mvc/package.module.mvc.php CHANGED
@@ -612,6 +612,7 @@ class Mixin_Mvc_View_Instance_Methods extends Mixin
612
  $this->end_element();
613
  }
614
  }
 
615
  }
616
  /**
617
  * Gets the absolute path of an MVC template file
612
  $this->end_element();
613
  }
614
  }
615
+ return NULL;
616
  }
617
  /**
618
  * Gets the absolute path of an MVC template file
products/photocrati_nextgen/modules/nextgen_admin/module.nextgen_admin.php CHANGED
@@ -84,14 +84,6 @@ class M_NextGen_Admin extends C_Base_Module
84
  'I_MVC_Controller',
85
  'A_MVC_Validation'
86
  );
87
-
88
- if (is_admin()) {
89
- $this->get_registry('I_NextGen_Admin_Page', 'A_Fs_Access_Page', NGG_FS_ACCESS_SLUG);
90
- $this->get_registry()->add_adapter(
91
- 'I_Page_Manager',
92
- 'A_NextGen_Admin_Default_Pages'
93
- );
94
- }
95
  }
96
 
97
  /**
84
  'I_MVC_Controller',
85
  'A_MVC_Validation'
86
  );
 
 
 
 
 
 
 
 
87
  }
88
 
89
  /**
products/photocrati_nextgen/modules/nextgen_admin/templates/field_generator/nextgen_settings_field_text.php CHANGED
@@ -10,8 +10,8 @@
10
  <input type='text'
11
  id='<?php print esc_attr("{$display_type_name}_{$name}"); ?>'
12
  name='<?php print esc_attr("{$display_type_name}[{$name}]"); ?>'
13
- class='<?php print esc_attr("{$display_type_name}[{$name}]"); ?>'
14
  <?php if (!empty($placeholder)) { ?>placeholder='<?php print esc_attr($placeholder); ?>'<?php } ?>
15
  value='<?php print esc_attr($value); ?>'/>
16
  </td>
17
- </tr>
10
  <input type='text'
11
  id='<?php print esc_attr("{$display_type_name}_{$name}"); ?>'
12
  name='<?php print esc_attr("{$display_type_name}[{$name}]"); ?>'
13
+ class='<?php print esc_attr("{$display_type_name}_{$name}"); ?>'
14
  <?php if (!empty($placeholder)) { ?>placeholder='<?php print esc_attr($placeholder); ?>'<?php } ?>
15
  value='<?php print esc_attr($value); ?>'/>
16
  </td>
17
+ </tr>
products/photocrati_nextgen/modules/nextgen_basic_album/package.module.nextgen_basic_album.php CHANGED
@@ -91,7 +91,7 @@ class A_NextGen_Album_Breadcrumbs extends Mixin
91
  $found[] = $album;
92
  break;
93
  } else {
94
- $found = $this->find_gallery_parent($gallery_id, $album->sortorder, $found);
95
  if ($found) {
96
  $found[] = $album;
97
  break;
@@ -433,7 +433,7 @@ class A_NextGen_Basic_Album_Controller extends Mixin_NextGen_Basic_Pagination
433
  if ($gallery && strpos($gallery, 'nggpage--') !== 0) {
434
  // basic albums only support one per post
435
  if (isset($GLOBALS['nggShowGallery'])) {
436
- return;
437
  }
438
  $GLOBALS['nggShowGallery'] = TRUE;
439
  // Try finding the gallery by slug first. If nothing is found, we assume that
91
  $found[] = $album;
92
  break;
93
  } else {
94
+ $found = $this->find_gallery_parent($gallery_id, $album->sortorder);
95
  if ($found) {
96
  $found[] = $album;
97
  break;
433
  if ($gallery && strpos($gallery, 'nggpage--') !== 0) {
434
  // basic albums only support one per post
435
  if (isset($GLOBALS['nggShowGallery'])) {
436
+ return '';
437
  }
438
  $GLOBALS['nggShowGallery'] = TRUE;
439
  // Try finding the gallery by slug first. If nothing is found, we assume that
products/photocrati_nextgen/modules/nextgen_basic_gallery/package.module.nextgen_basic_gallery.php CHANGED
@@ -542,6 +542,7 @@ class A_NextGen_Basic_Thumbnails_Controller extends Mixin
542
  return $this->object->render_partial("photocrati-nextgen_gallery_display#no_images_found", array(), $return);
543
  }
544
  }
 
545
  }
546
  /**
547
  * Enqueues all static resources required by this display type
542
  return $this->object->render_partial("photocrati-nextgen_gallery_display#no_images_found", array(), $return);
543
  }
544
  }
545
+ return '';
546
  }
547
  /**
548
  * Enqueues all static resources required by this display type
products/photocrati_nextgen/modules/nextgen_basic_imagebrowser/package.module.nextgen_basic_imagebrowser.php CHANGED
@@ -41,6 +41,7 @@ class A_NextGen_Basic_ImageBrowser_Controller extends Mixin
41
  } else {
42
  return $this->object->render_partial('photocrati-nextgen_gallery_display#no_images_found', array(), $return);
43
  }
 
44
  }
45
  /**
46
  * Returns the rendered template of an image browser display
41
  } else {
42
  return $this->object->render_partial('photocrati-nextgen_gallery_display#no_images_found', array(), $return);
43
  }
44
+ return '';
45
  }
46
  /**
47
  * Returns the rendered template of an image browser display
products/photocrati_nextgen/modules/nextgen_basic_tagcloud/package.module.nextgen_basic_tagcloud.php CHANGED
@@ -212,13 +212,7 @@ class C_Taxonomy_Controller extends C_MVC_Controller
212
  parent::define($context);
213
  $this->implement('I_Taxonomy_Controller');
214
  }
215
- /**
216
- * Returns the rendered HTML of a gallery based on the provided tag
217
- *
218
- * @param string $tag
219
- * @return string
220
- */
221
- function index_action($tag)
222
  {
223
  $mapper = C_Display_Type_Mapper::get_instance();
224
  // Respect the global display type setting
@@ -279,7 +273,7 @@ class C_Taxonomy_Controller extends C_MVC_Controller
279
  $post->post_name = 'ngg_tag';
280
  $post->guid = get_bloginfo('wpurl') . '/' . 'ngg_tag';
281
  $post->post_title = $title;
282
- $post->post_content = $this->index_action($tag);
283
  $post->ID = FALSE;
284
  $post->post_type = 'page';
285
  $post->post_status = 'publish';
212
  parent::define($context);
213
  $this->implement('I_Taxonomy_Controller');
214
  }
215
+ function render_tag($tag)
 
 
 
 
 
 
216
  {
217
  $mapper = C_Display_Type_Mapper::get_instance();
218
  // Respect the global display type setting
273
  $post->post_name = 'ngg_tag';
274
  $post->guid = get_bloginfo('wpurl') . '/' . 'ngg_tag';
275
  $post->post_title = $title;
276
+ $post->post_content = $this->render_tag($tag);
277
  $post->ID = FALSE;
278
  $post->post_type = 'page';
279
  $post->post_status = 'publish';
products/photocrati_nextgen/modules/nextgen_basic_templates/package.module.nextgen_basic_templates.php CHANGED
@@ -236,7 +236,7 @@ class Mixin_Legacy_Template_Locator extends Mixin
236
  function get_templates_from_dir($dir, $prefix = FALSE)
237
  {
238
  if (!is_dir($dir)) {
239
- return;
240
  }
241
  $dir = new RecursiveDirectoryIterator($dir);
242
  $iterator = new RecursiveIteratorIterator($dir);
236
  function get_templates_from_dir($dir, $prefix = FALSE)
237
  {
238
  if (!is_dir($dir)) {
239
+ return array();
240
  }
241
  $dir = new RecursiveDirectoryIterator($dir);
242
  $iterator = new RecursiveIteratorIterator($dir);
products/photocrati_nextgen/modules/nextgen_data/module.nextgen_data.php CHANGED
@@ -2,85 +2,85 @@
2
 
3
  /***
4
  {
5
- Module: photocrati-nextgen-data,
6
- Depends: { photocrati-datamapper }
7
  }
8
- ***/
9
 
10
  class M_NextGen_Data extends C_Base_Module
11
  {
12
- function define($id = 'pope-module',
13
- $name = 'Pope Module',
14
- $description = '',
15
- $version = '',
16
- $uri = '',
17
- $author = '',
18
- $author_uri = '',
19
- $context = FALSE)
20
- {
21
- parent::define(
22
- 'photocrati-nextgen-data',
23
- 'NextGEN Data Tier',
24
- "Provides a data tier for NextGEN gallery based on the DataMapper module",
25
- '0.15',
26
- 'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
27
- 'Imagely',
28
- 'https://www.imagely.com'
29
- );
30
 
31
  C_Photocrati_Installer::add_handler($this->module_id, 'C_NextGen_Data_Installer');
32
- }
33
 
34
- function _register_adapters()
35
- {
36
- $this->get_registry()->add_adapter('I_Component_Factory', 'A_NextGen_Data_Factory');
37
  #$this->get_registry()->add_adapter('I_CustomPost_DataMapper', 'A_Attachment_DataMapper', 'attachment');
38
- $this->get_registry()->add_adapter('I_Installer', 'A_NextGen_Data_Installer');
39
- }
40
 
41
 
42
- function _register_utilities()
43
- {
44
  $this->get_registry()->add_utility('I_Gallery_Mapper', 'C_Gallery_Mapper');
45
  $this->get_registry()->add_utility('I_Image_Mapper', 'C_Image_Mapper');
46
- $this->get_registry()->add_utility('I_Album_Mapper', 'C_Album_Mapper');
47
- $this->get_registry()->add_utility('I_Gallery_Storage', 'C_Gallery_Storage');
48
- }
49
-
50
- function get_type_list()
51
- {
52
- return array(
53
- 'C_Exif_Writer_Wrapper' => 'class.exif_writer_wrapper.php',
54
- 'A_Attachment_Datamapper' => 'adapter.attachment_datamapper.php',
55
- 'A_Customtable_Sorting_Datamapper' => 'adapter.customtable_sorting_datamapper.php',
56
- 'A_Nextgen_Data_Factory' => 'adapter.nextgen_data_factory.php',
57
- 'C_NextGen_Data_Installer' => 'class.nextgen_data_installer.php',
58
- 'A_Parse_Image_Metadata' => 'adapter.parse_image_metadata.php',
59
- 'C_Album' => 'class.album.php',
60
- 'C_Gallery' => 'class.gallery.php',
61
- 'C_Image' => 'class.image.php',
62
- 'C_Album_Mapper' => 'class.album_mapper.php',
63
- 'C_Gallerystorage_Base' => 'class.gallerystorage_base.php',
64
- 'C_Gallerystorage_Driver_Base' => 'class.gallerystorage_driver_base.php',
65
- 'C_Gallery_Mapper' => 'class.gallery_mapper.php',
66
- 'C_Gallery_Storage' => 'class.gallery_storage.php',
67
- 'C_Image_Mapper' => 'class.image_mapper.php',
68
- 'C_Image_Wrapper' => 'class.image_wrapper.php',
69
- 'C_Image_Wrapper_Collection' => 'class.image_wrapper_collection.php',
70
- 'C_Nextgen_Metadata' => 'class.nextgen_metadata.php',
71
  'Mixin_NextGen_Table_Extras' => 'mixin.nextgen_table_extras.php',
72
- 'C_Ngglegacy_Gallerystorage_Driver' => 'class.ngglegacy_gallerystorage_driver.php',
73
- 'C_Ngglegacy_Thumbnail' => 'class.ngglegacy_thumbnail.php',
74
- 'C_Wordpress_Gallerystorage_Driver' => 'class.wordpress_gallerystorage_driver.php'
75
- );
76
- }
77
-
78
-
79
- function _register_hooks()
80
- {
81
  add_action('init', array(&$this, 'register_custom_post_types'));
82
- add_filter('posts_orderby', array($this, 'wp_query_order_by'), 10, 2);
83
- }
84
 
85
  function register_custom_post_types()
86
  {
@@ -98,33 +98,124 @@ class M_NextGen_Data extends C_Base_Module
98
  ));
99
  }
100
  }
101
-
102
- function wp_query_order_by($order_by, $wp_query)
103
- {
104
- if ($wp_query->get('datamapper_attachment'))
105
- {
106
- $order_parts = explode(' ', $order_by);
107
- $order_name = array_shift($order_parts);
108
-
109
- $order_by = 'ABS(' . $order_name . ') ' . implode(' ', $order_parts) . ', ' . $order_by;
110
- }
111
-
112
- return $order_by;
113
- }
114
 
115
  static function strip_html($data, $just_scripts=FALSE)
116
  {
117
  $retval = $data;
118
 
119
  if (!$just_scripts)
 
 
120
  $retval = wp_strip_all_tags($retval, TRUE);
 
121
  else {
122
- $retval = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $retval );
123
- $retval= preg_replace('/[\r\n\t ]+/', ' ', $retval);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  }
125
- $retval = preg_replace("/(\\s)?on[^\\s=]+=/", '', $retval);
126
 
127
  return $retval;
128
  }
129
  }
130
- new M_NextGen_Data();
2
 
3
  /***
4
  {
5
+ Module: photocrati-nextgen-data,
6
+ Depends: { photocrati-datamapper }
7
  }
8
+ ***/
9
 
10
  class M_NextGen_Data extends C_Base_Module
11
  {
12
+ function define($id = 'pope-module',
13
+ $name = 'Pope Module',
14
+ $description = '',
15
+ $version = '',
16
+ $uri = '',
17
+ $author = '',
18
+ $author_uri = '',
19
+ $context = FALSE)
20
+ {
21
+ parent::define(
22
+ 'photocrati-nextgen-data',
23
+ 'NextGEN Data Tier',
24
+ "Provides a data tier for NextGEN gallery based on the DataMapper module",
25
+ '0.16',
26
+ 'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
27
+ 'Imagely',
28
+ 'https://www.imagely.com'
29
+ );
30
 
31
  C_Photocrati_Installer::add_handler($this->module_id, 'C_NextGen_Data_Installer');
32
+ }
33
 
34
+ function _register_adapters()
35
+ {
36
+ $this->get_registry()->add_adapter('I_Component_Factory', 'A_NextGen_Data_Factory');
37
  #$this->get_registry()->add_adapter('I_CustomPost_DataMapper', 'A_Attachment_DataMapper', 'attachment');
38
+ $this->get_registry()->add_adapter('I_Installer', 'A_NextGen_Data_Installer');
39
+ }
40
 
41
 
42
+ function _register_utilities()
43
+ {
44
  $this->get_registry()->add_utility('I_Gallery_Mapper', 'C_Gallery_Mapper');
45
  $this->get_registry()->add_utility('I_Image_Mapper', 'C_Image_Mapper');
46
+ $this->get_registry()->add_utility('I_Album_Mapper', 'C_Album_Mapper');
47
+ $this->get_registry()->add_utility('I_Gallery_Storage', 'C_Gallery_Storage');
48
+ }
49
+
50
+ function get_type_list()
51
+ {
52
+ return array(
53
+ 'C_Exif_Writer_Wrapper' => 'class.exif_writer_wrapper.php',
54
+ 'A_Attachment_Datamapper' => 'adapter.attachment_datamapper.php',
55
+ 'A_Customtable_Sorting_Datamapper' => 'adapter.customtable_sorting_datamapper.php',
56
+ 'A_Nextgen_Data_Factory' => 'adapter.nextgen_data_factory.php',
57
+ 'C_NextGen_Data_Installer' => 'class.nextgen_data_installer.php',
58
+ 'A_Parse_Image_Metadata' => 'adapter.parse_image_metadata.php',
59
+ 'C_Album' => 'class.album.php',
60
+ 'C_Gallery' => 'class.gallery.php',
61
+ 'C_Image' => 'class.image.php',
62
+ 'C_Album_Mapper' => 'class.album_mapper.php',
63
+ 'C_Gallerystorage_Base' => 'class.gallerystorage_base.php',
64
+ 'C_Gallerystorage_Driver_Base' => 'class.gallerystorage_driver_base.php',
65
+ 'C_Gallery_Mapper' => 'class.gallery_mapper.php',
66
+ 'C_Gallery_Storage' => 'class.gallery_storage.php',
67
+ 'C_Image_Mapper' => 'class.image_mapper.php',
68
+ 'C_Image_Wrapper' => 'class.image_wrapper.php',
69
+ 'C_Image_Wrapper_Collection' => 'class.image_wrapper_collection.php',
70
+ 'C_Nextgen_Metadata' => 'class.nextgen_metadata.php',
71
  'Mixin_NextGen_Table_Extras' => 'mixin.nextgen_table_extras.php',
72
+ 'C_Ngglegacy_Gallerystorage_Driver' => 'class.ngglegacy_gallerystorage_driver.php',
73
+ 'C_Ngglegacy_Thumbnail' => 'class.ngglegacy_thumbnail.php',
74
+ 'C_Wordpress_Gallerystorage_Driver' => 'class.wordpress_gallerystorage_driver.php'
75
+ );
76
+ }
77
+
78
+
79
+ function _register_hooks()
80
+ {
81
  add_action('init', array(&$this, 'register_custom_post_types'));
82
+ add_filter('posts_orderby', array($this, 'wp_query_order_by'), 10, 2);
83
+ }
84
 
85
  function register_custom_post_types()
86
  {
98
  ));
99
  }
100
  }
101
+
102
+ function wp_query_order_by($order_by, $wp_query)
103
+ {
104
+ if ($wp_query->get('datamapper_attachment'))
105
+ {
106
+ $order_parts = explode(' ', $order_by);
107
+ $order_name = array_shift($order_parts);
108
+
109
+ $order_by = 'ABS(' . $order_name . ') ' . implode(' ', $order_parts) . ', ' . $order_by;
110
+ }
111
+
112
+ return $order_by;
113
+ }
114
 
115
  static function strip_html($data, $just_scripts=FALSE)
116
  {
117
  $retval = $data;
118
 
119
  if (!$just_scripts)
120
+ {
121
+ // Remove *ALL* HTML and tag contents
122
  $retval = wp_strip_all_tags($retval, TRUE);
123
+ }
124
  else {
125
+ // Allows HTML to remain but we strip nearly all attributes, strip all
126
+ // <script> tags, and sanitize hrefs to prevent javascript.
127
+ //
128
+ // This can generate a *lot* of warnings when given improper texts
129
+ libxml_use_internal_errors(true);
130
+ libxml_clear_errors();
131
+
132
+ $allowed_attributes = array('id', 'class', 'href', 'name', 'title', 'rel', 'style');
133
+
134
+ if (is_object($data))
135
+ {
136
+ // First... recurse to the deepest elements and work back & upwards
137
+ if ($data->hasChildNodes())
138
+ {
139
+ foreach (range($data->childNodes->length - 1, 0) as $i) {
140
+ self::strip_html($data->childNodes->item($i), TRUE);
141
+ }
142
+ }
143
+
144
+ // Remove disallowed elements and content
145
+ if ($data instanceof DOMElement) {
146
+ foreach ($data->getElementsByTagName('script') as $deleteme) {
147
+ $data->removeChild($deleteme);
148
+ }
149
+ }
150
+
151
+ // Strip (nearly) all attributes
152
+ if (!empty($data->attributes))
153
+ {
154
+ // DOMDocument reindexes as soon as any changes are made so we
155
+ // must loop through attributes backwards
156
+ for ($i = $data->attributes->length - 1; $i >= 0; --$i) {
157
+ $item = $data->attributes->item($i);
158
+ $name = $item->nodeName;
159
+
160
+ // We only allow these three attributes
161
+ if (!in_array($name, $allowed_attributes))
162
+ $data->removeAttribute($name);
163
+
164
+ // DO NOT EVER allow href="javascript:...."
165
+ if ($name === 'href')
166
+ {
167
+ if (strpos($item->nodeValue, 'javascript:') === 0)
168
+ $item->nodeValue = '#';
169
+ }
170
+ }
171
+ }
172
+ }
173
+ else {
174
+ $dom = new DOMDocument();
175
+
176
+ if (!empty($data))
177
+ {
178
+ // Because DOMDocument wraps saveHTML() with HTML headers & tags we use
179
+ // this placeholder to retrieve *just* the original given text
180
+ $id = 'ngg_data_strip_html_placeholder';
181
+ $start = "<div id=\"{$id}\">";
182
+ $end = '</div>';
183
+ $start_length = strlen($start);
184
+ $end_length = strlen($end);
185
+
186
+ // This forces DOMDocument to treat the HTML as UTF-8
187
+ $meta = '<meta http-equiv="Content-Type" content="charset=utf-8"/>';
188
+ $data = $meta . $start . $data . $end;
189
+
190
+ $dom->loadHTML($data);
191
+
192
+ // Invoke the actual work
193
+ self::strip_html($dom->documentElement, TRUE);
194
+
195
+ // Export back to text
196
+ //
197
+ // TODO: When PHP 5.2 support is dropped we can use the target parameter
198
+ // of the following saveHTML and rid ourselves of some of the nonsense
199
+ // workarounds to the fact that DOMDocument used to force the output to
200
+ // include full HTML/XML doctype and root elements.
201
+ $retval = $dom->saveXML();
202
+
203
+ // saveXML includes the full doctype and <html><body></body></html> wrappers
204
+ // so we first drop everything generated up to our wrapper and chop off the
205
+ // added end wrappers
206
+ $position = strpos($retval, $start);
207
+ $retval = substr($retval, $position, -15);
208
+
209
+ // Lastly remove our wrapper
210
+ $retval = substr($retval, $start_length, -$end_length);
211
+ }
212
+ else {
213
+ $retval = '';
214
+ }
215
+ }
216
  }
 
217
 
218
  return $retval;
219
  }
220
  }
221
+ new M_NextGen_Data();
products/photocrati_nextgen/modules/nextgen_data/package.module.nextgen_data.php CHANGED
@@ -245,7 +245,7 @@ class C_Exif_Writer_Wrapper
245
  return;
246
  }
247
  require_once __DIR__ . DIRECTORY_SEPARATOR . 'pel-0.9.6' . DIRECTORY_SEPARATOR . 'class.exif_writer.php';
248
- C_Exif_Writer::copy_metadata($old_file, $new_file);
249
  }
250
  }
251
  class Mixin_NextGen_Gallery_Validation
@@ -1224,6 +1224,13 @@ class Mixin_GalleryStorage_Driver_Base extends Mixin
1224
  $fp = fopen($abs_filename, 'wb');
1225
  fwrite($fp, $this->maybe_base64_decode($data));
1226
  fclose($fp);
 
 
 
 
 
 
 
1227
  // Save the image
1228
  $image_id = $this->object->_image_mapper->save($image);
1229
  if (!$image_id) {
@@ -1258,6 +1265,8 @@ class Mixin_GalleryStorage_Driver_Base extends Mixin
1258
  delete_transient('dirsize_cache');
1259
  // Seems redundant to above hook. Maintaining for legacy purposes
1260
  do_action('ngg_after_new_images_added', $gallery_id, array($image->{$image_key}));
 
 
1261
  } catch (E_No_Image_Library_Exception $ex) {
1262
  throw $ex;
1263
  } catch (E_Clean_Exit $ex) {
@@ -1437,8 +1446,8 @@ class Mixin_GalleryStorage_Driver_Base extends Mixin
1437
  if ($clone_extension != null) {
1438
  $clone_extension_str = '.' . $clone_extension;
1439
  }
1440
- $image_basename = M_I18n::mb_basename($image_path, $image_extension_str);
1441
- $clone_basename = M_I18n::mb_basename($clone_path, $clone_extension_str);
1442
  // We use a default suffix as passing in null as the suffix will make WordPress use a default
1443
  $clone_suffix = null;
1444
  $format_list = $this->object->get_image_format_list();
@@ -1796,7 +1805,7 @@ class Mixin_GalleryStorage_Driver_Base extends Mixin
1796
  }
1797
  $thumbnail = apply_filters('ngg_before_save_thumbnail', $thumbnail);
1798
  $thumbnail->save($destpath, $quality);
1799
- C_Exif_Writer_Wrapper::copy_metadata($image_path, $destpath);
1800
  }
1801
  }
1802
  return $thumbnail;
@@ -2706,7 +2715,7 @@ class C_NextGen_Metadata extends C_Component
2706
  }
2707
  // on request sanitize the output
2708
  if ($this->sanitize == true) {
2709
- array_walk($meta, create_function('&$value', '$value = esc_html($value);'));
2710
  }
2711
  return $meta;
2712
  }
@@ -2802,7 +2811,7 @@ class C_NextGen_Metadata extends C_Component
2802
  }
2803
  // on request sanitize the output
2804
  if ($this->sanitize == true) {
2805
- array_walk($this->exif_array, create_function('&$value', '$value = esc_html($value);'));
2806
  }
2807
  return $this->exif_array;
2808
  }
@@ -2854,7 +2863,7 @@ class C_NextGen_Metadata extends C_Component
2854
  }
2855
  // on request sanitize the output
2856
  if ($this->sanitize == true) {
2857
- array_walk($this->iptc_array, create_function('&$value', '$value = esc_html($value);'));
2858
  }
2859
  return $this->iptc_array;
2860
  }
@@ -2981,7 +2990,7 @@ class C_NextGen_Metadata extends C_Component
2981
  }
2982
  // on request sanitize the output
2983
  if ($this->sanitize == true) {
2984
- array_walk($this->xmp_array, create_function('&$value', '$value = esc_html($value);'));
2985
  }
2986
  return $this->xmp_array;
2987
  }
@@ -2994,6 +3003,7 @@ class C_NextGen_Metadata extends C_Component
2994
  } else {
2995
  $array = $value;
2996
  }
 
2997
  }
2998
  /**
2999
  * nggMeta::get_META() - return a meta value form the available list
@@ -3062,7 +3072,7 @@ class C_NextGen_Metadata extends C_Component
3062
  * Reason : GD manipulation removes that options
3063
  *
3064
  * @since V1.4.0
3065
- * @return void
3066
  */
3067
  function get_common_meta()
3068
  {
@@ -4061,6 +4071,7 @@ class C_NggLegacy_Thumbnail
4061
  }
4062
  //if there are no errors, determine the file format
4063
  if ($this->error == false) {
 
4064
  @ini_set('memory_limit', -1);
4065
  $data = @getimagesize($this->fileName);
4066
  if (isset($data) && is_array($data)) {
245
  return;
246
  }
247
  require_once __DIR__ . DIRECTORY_SEPARATOR . 'pel-0.9.6' . DIRECTORY_SEPARATOR . 'class.exif_writer.php';
248
+ @C_Exif_Writer::copy_metadata($old_file, $new_file);
249
  }
250
  }
251
  class Mixin_NextGen_Gallery_Validation
1224
  $fp = fopen($abs_filename, 'wb');
1225
  fwrite($fp, $this->maybe_base64_decode($data));
1226
  fclose($fp);
1227
+ // Ensure that we're not vulerable to CVE-2017-2416 exploit
1228
+ if (($dimensions = getimagesize($abs_filename)) !== FALSE) {
1229
+ if (isset($dimensions[0]) && intval($dimensions[0]) > 30000 || isset($dimensions[1]) && intval($dimensions[1]) > 30000) {
1230
+ unlink($abs_filename);
1231
+ throw new E_UploadException(__('Image file too large. Maximum image dimensions supported are 30k x 30k.'));
1232
+ }
1233
+ }
1234
  // Save the image
1235
  $image_id = $this->object->_image_mapper->save($image);
1236
  if (!$image_id) {
1265
  delete_transient('dirsize_cache');
1266
  // Seems redundant to above hook. Maintaining for legacy purposes
1267
  do_action('ngg_after_new_images_added', $gallery_id, array($image->{$image_key}));
1268
+ } catch (E_UploadException $ex) {
1269
+ throw $ex;
1270
  } catch (E_No_Image_Library_Exception $ex) {
1271
  throw $ex;
1272
  } catch (E_Clean_Exit $ex) {
1446
  if ($clone_extension != null) {
1447
  $clone_extension_str = '.' . $clone_extension;
1448
  }
1449
+ $image_basename = M_I18n::mb_basename($image_path);
1450
+ $clone_basename = M_I18n::mb_basename($clone_path);
1451
  // We use a default suffix as passing in null as the suffix will make WordPress use a default
1452
  $clone_suffix = null;
1453
  $format_list = $this->object->get_image_format_list();
1805
  }
1806
  $thumbnail = apply_filters('ngg_before_save_thumbnail', $thumbnail);
1807
  $thumbnail->save($destpath, $quality);
1808
+ @C_Exif_Writer_Wrapper::copy_metadata($image_path, $destpath);
1809
  }
1810
  }
1811
  return $thumbnail;
2715
  }
2716
  // on request sanitize the output
2717
  if ($this->sanitize == true) {
2718
+ array_walk($meta, 'esc_html');
2719
  }
2720
  return $meta;
2721
  }
2811
  }
2812
  // on request sanitize the output
2813
  if ($this->sanitize == true) {
2814
+ array_walk($this->exif_array, 'esc_html');
2815
  }
2816
  return $this->exif_array;
2817
  }
2863
  }
2864
  // on request sanitize the output
2865
  if ($this->sanitize == true) {
2866
+ array_walk($this->iptc_array, 'esc_html');
2867
  }
2868
  return $this->iptc_array;
2869
  }
2990
  }
2991
  // on request sanitize the output
2992
  if ($this->sanitize == true) {
2993
+ array_walk($this->xmp_array, 'esc_html');
2994
  }
2995
  return $this->xmp_array;
2996
  }
3003
  } else {
3004
  $array = $value;
3005
  }
3006
+ return $array;
3007
  }
3008
  /**
3009
  * nggMeta::get_META() - return a meta value form the available list
3072
  * Reason : GD manipulation removes that options
3073
  *
3074
  * @since V1.4.0
3075
+ * @return array|false
3076
  */
3077
  function get_common_meta()
3078
  {
4071
  }
4072
  //if there are no errors, determine the file format
4073
  if ($this->error == false) {
4074
+ // set_time_limit(30);
4075
  @ini_set('memory_limit', -1);
4076
  $data = @getimagesize($this->fileName);
4077
  if (isset($data) && is_array($data)) {
products/photocrati_nextgen/modules/nextgen_data/pel-0.9.6/src/PelIfd.php CHANGED
@@ -755,6 +755,7 @@ class PelIfd implements \IteratorAggregate, \ArrayAccess
755
  * PelTag::CFA_REPEAT_PATTERN_DIM,
756
  */
757
  }
 
758
  }
759
 
760
  /**
755
  * PelTag::CFA_REPEAT_PATTERN_DIM,
756
  */
757
  }
758
+ return array();
759
  }
760
 
761
  /**
products/photocrati_nextgen/modules/nextgen_data/pel-0.9.6/src/PelWrongComponentCountException.php CHANGED
@@ -53,7 +53,7 @@ use lsolesen\pel\PelTag;
53
  * @package PEL
54
  * @subpackage Exception
55
  */
56
- class PelWrongComponentCountException extends \lsolesen\pel\PelEntryException
57
  {
58
 
59
  /**
53
  * @package PEL
54
  * @subpackage Exception
55
  */
56
+ class PelWrongComponentCountException extends PelEntryException
57
  {
58
 
59
  /**
products/photocrati_nextgen/modules/nextgen_gallery_display/module.nextgen_gallery_display.php CHANGED
@@ -249,7 +249,7 @@ class M_Gallery_Display extends C_Base_Module
249
  /**
250
  * Gets the src url for the registered fontawesome handler
251
  * @param bool $ngg_provided_only
252
- * @return null|string|void
253
  */
254
  static function get_fontawesome_url($ngg_provided_only=FALSE)
255
  {
@@ -322,7 +322,7 @@ class M_Gallery_Display extends C_Base_Module
322
  $taglist = implode(',', $sluglist);
323
 
324
  if ($taglist === 'uncategorized' || empty($taglist))
325
- return;
326
 
327
  $renderer = C_Displayed_Gallery_Renderer::get_instance();
328
  $view = C_Component_Factory::get_instance()->create('mvc_view', '');
249
  /**
250
  * Gets the src url for the registered fontawesome handler
251
  * @param bool $ngg_provided_only
252
+ * @return null|string
253
  */
254
  static function get_fontawesome_url($ngg_provided_only=FALSE)
255
  {
322
  $taglist = implode(',', $sluglist);
323
 
324
  if ($taglist === 'uncategorized' || empty($taglist))
325
+ return '';
326
 
327
  $renderer = C_Displayed_Gallery_Renderer::get_instance();
328
  $view = C_Component_Factory::get_instance()->create('mvc_view', '');
products/photocrati_nextgen/modules/nextgen_gallery_display/package.module.nextgen_gallery_display.php CHANGED
@@ -591,7 +591,7 @@ class C_Display_Type_Mapper extends C_CustomPost_DataMapper_Driver
591
  }
592
  function initialize($context = FALSE)
593
  {
594
- parent::initialize('display_type');
595
  }
596
  /**
597
  * Gets a singleton of the mapper
@@ -1482,7 +1482,7 @@ class C_Displayed_Gallery_Mapper extends C_CustomPost_DataMapper_Driver
1482
  */
1483
  function initialize()
1484
  {
1485
- parent::initialize('displayed_gallery');
1486
  }
1487
  /**
1488
  * Gets a singleton of the mapper
591
  }
592
  function initialize($context = FALSE)
593
  {
594
+ parent::initialize();
595
  }
596
  /**
597
  * Gets a singleton of the mapper
1482
  */
1483
  function initialize()
1484
  {
1485
+ parent::initialize();
1486
  }
1487
  /**
1488
  * Gets a singleton of the mapper
products/photocrati_nextgen/modules/nextgen_xmlrpc/package.module.nextgen_xmlrpc.php CHANGED
@@ -590,6 +590,9 @@ class C_NextGen_API extends C_Component
590
  $error = null;
591
  if ($gallery != null) {
592
  if ($task_type == 'gallery_remove') {
 
 
 
593
  if (!$mapper->destroy($gallery, true)) {
594
  $error = __('Failed to remove gallery (%1$s).', 'nggallery');
595
  }
590
  $error = null;
591
  if ($gallery != null) {
592
  if ($task_type == 'gallery_remove') {
593
+ /**
594
+ * @var $mapper Mixin_Gallery_Mapper
595
+ */
596
  if (!$mapper->destroy($gallery, true)) {
597
  $error = __('Failed to remove gallery (%1$s).', 'nggallery');
598
  }
products/photocrati_nextgen/modules/ngglegacy/admin/album.php CHANGED
@@ -314,7 +314,7 @@ jQuery(document).ready(
314
 
315
  // Refresh when a new gallery has been added
316
  Frame_Event_Publisher.listen_for('attach_to_post:manage_galleries attach_to_post:new_gallery', function(){
317
- window.location.href = window.location.href;
318
  });
319
 
320
  // Updates the thumbnail image when a previewpic has been modified
@@ -437,7 +437,6 @@ function showDialog() {
437
  </script>
438
 
439
  <div class="wrap album" id="wrap" >
440
- <?php screen_icon( 'nextgen-gallery' ); ?>
441
  <h2><?php esc_html_e('Manage Albums', 'nggallery') ?></h2>
442
  <form id="selectalbum" method="POST" onsubmit="ngg_serialize()" accept-charset="utf-8">
443
  <?php wp_nonce_field('ngg_album') ?>
@@ -462,7 +461,7 @@ function showDialog() {
462
  <input class="button-secondary" type="submit" name="showThickbox" value="<?php esc_attr_e( 'Edit Album', 'nggallery'); ?>" onclick="showDialog(); return false;" />
463
  <?php } ?>
464
  <?php if(nggGallery::current_user_can( 'NextGEN Add/Delete album' )) { ?>
465
- <input class="button-secondary action "type="submit" name="delete" value="<?php esc_attr_e('Delete', 'nggallery'); ?>" onclick="javascript:check=confirm('<?php echo esc_js('Delete album ?','nggallery'); ?>');if(check==false) return false;"/>
466
  <?php } ?>
467
  <?php } else { ?>
468
  <?php if(nggGallery::current_user_can( 'NextGEN Add/Delete album' )) { ?>
@@ -603,7 +602,7 @@ function showDialog() {
603
  'echo' => TRUE,
604
  'name' => 'pageid',
605
  'selected' => $album->pageid,
606
- 'show_option_none' => esc_html('Not linked', 'nggallery'),
607
  'option_none_value' => 0
608
  ));
609
  $dropdown = ob_get_contents();
@@ -642,11 +641,12 @@ function showDialog() {
642
  *
643
  * @param integer $id (the prefix 'a' indidcates that you look for a album
644
  * @param bool $used (object will be hidden)
645
- * @return $output
646
  */
647
  function get_container($id = 0, $used = false) {
648
  global $wpdb, $nggdb;
649
 
 
650
  $obj = array();
651
  $preview_image = '';
652
  $class = '';
@@ -655,7 +655,7 @@ function showDialog() {
655
  if (substr( $id, 0, 1) == 'a') {
656
 
657
  if ( !$album = $this->_get_album(substr( $id, 1)))
658
- return;
659
 
660
  $obj['id'] = $album->id;
661
  $obj['name'] = $obj['title'] = $album->name;
@@ -681,7 +681,7 @@ function showDialog() {
681
 
682
  } else {
683
  if ( !$gallery = $nggdb->find_gallery( $id ) )
684
- return;
685
 
686
  $obj['id'] = $gallery->gid;
687
  $obj['name'] = $gallery->name;
@@ -709,7 +709,7 @@ function showDialog() {
709
  // add class if it's in use in other albums
710
  $used = $used ? ' inUse' : '';
711
 
712
- echo '<div id="gid-' . $prefix . $obj['id'] . '" class="groupItem' . $used . '">
713
  <div class="innerhandle">
714
  <div class="item_top ' . $class . '">
715
  <a href="#" class="min" title="close">[-]</a>
@@ -724,6 +724,8 @@ function showDialog() {
724
  </div>
725
  </div>
726
  </div>';
 
 
727
  }
728
 
729
  /**
314
 
315
  // Refresh when a new gallery has been added
316
  Frame_Event_Publisher.listen_for('attach_to_post:manage_galleries attach_to_post:new_gallery', function(){
317
+ window.location.href = window.location.href.toString();
318
  });
319
 
320
  // Updates the thumbnail image when a previewpic has been modified
437
  </script>
438
 
439
  <div class="wrap album" id="wrap" >
 
440
  <h2><?php esc_html_e('Manage Albums', 'nggallery') ?></h2>
441
  <form id="selectalbum" method="POST" onsubmit="ngg_serialize()" accept-charset="utf-8">
442
  <?php wp_nonce_field('ngg_album') ?>
461
  <input class="button-secondary" type="submit" name="showThickbox" value="<?php esc_attr_e( 'Edit Album', 'nggallery'); ?>" onclick="showDialog(); return false;" />
462
  <?php } ?>
463
  <?php if(nggGallery::current_user_can( 'NextGEN Add/Delete album' )) { ?>
464
+ <input class="button-secondary action "type="submit" name="delete" value="<?php esc_attr_e('Delete', 'nggallery'); ?>" onclick="javascript:check=confirm('<?php echo esc_js(__('Delete album ?','nggallery')); ?>');if(check==false) return false;"/>
465
  <?php } ?>
466
  <?php } else { ?>
467
  <?php if(nggGallery::current_user_can( 'NextGEN Add/Delete album' )) { ?>
602
  'echo' => TRUE,
603
  'name' => 'pageid',
604
  'selected' => $album->pageid,
605
+ 'show_option_none' => esc_html_('Not linked', 'nggallery'),
606
  'option_none_value' => 0
607
  ));
608
  $dropdown = ob_get_contents();
641
  *
642
  * @param integer $id (the prefix 'a' indidcates that you look for a album
643
  * @param bool $used (object will be hidden)
644
+ * @return string
645
  */
646
  function get_container($id = 0, $used = false) {
647
  global $wpdb, $nggdb;
648
 
649
+ $retval = NULL;
650
  $obj = array();
651
  $preview_image = '';
652
  $class = '';
655
  if (substr( $id, 0, 1) == 'a') {
656
 
657
  if ( !$album = $this->_get_album(substr( $id, 1)))
658
+ return $retval;
659
 
660
  $obj['id'] = $album->id;
661
  $obj['name'] = $obj['title'] = $album->name;
681
 
682
  } else {
683
  if ( !$gallery = $nggdb->find_gallery( $id ) )
684
+ return $retval;
685
 
686
  $obj['id'] = $gallery->gid;
687
  $obj['name'] = $gallery->name;
709
  // add class if it's in use in other albums
710
  $used = $used ? ' inUse' : '';
711
 
712
+ $retval = '<div id="gid-' . $prefix . $obj['id'] . '" class="groupItem' . $used . '">
713
  <div class="innerhandle">
714
  <div class="item_top ' . $class . '">
715
  <a href="#" class="min" title="close">[-]</a>
724
  </div>
725
  </div>
726
  </div>';
727
+ echo $retval;
728
+ return $retval;
729
  }
730
 
731
  /**
products/photocrati_nextgen/modules/ngglegacy/admin/functions.php CHANGED
@@ -710,11 +710,12 @@ class nggAdmin{
710
  static function do_ajax_operation( $operation, $image_array, $title = '' ) {
711
 
712
  if ( !is_array($image_array) || empty($image_array) )
713
- return;
714
 
715
  $js_array = implode('","', $image_array);
716
 
717
  // send out some JavaScript, which initate the ajax operation
 
718
  ?>
719
  <script type="text/javascript">
720
 
@@ -732,8 +733,10 @@ class nggAdmin{
732
  nggAjax.init( nggAjaxOptions );
733
  } );
734
  </script>
735
-
736
  <?php
 
 
 
737
  }
738
 
739
  /**
710
  static function do_ajax_operation( $operation, $image_array, $title = '' ) {
711
 
712
  if ( !is_array($image_array) || empty($image_array) )
713
+ return '';
714
 
715
  $js_array = implode('","', $image_array);
716
 
717
  // send out some JavaScript, which initate the ajax operation
718
+ ob_start();
719
  ?>
720
  <script type="text/javascript">
721
 
733
  nggAjax.init( nggAjaxOptions );
734
  } );
735
  </script>
 
736
  <?php
737
+ $script = ob_get_clean();
738
+ echo $script;
739
+ return $script;
740
  }
741
 
742
  /**
products/photocrati_nextgen/modules/ngglegacy/admin/manage-galleries.php CHANGED
@@ -53,7 +53,7 @@ function nggallery_manage_gallery_main() {
53
 
54
  // If a new gallery is added, refresh the page
55
  Frame_Event_Publisher.listen_for('attach_to_post:new_gallery attach_to_post:manage_images attach_to_post:images_added',function(){
56
- window.location.href = window.location.href;
57
  });
58
  }
59
 
@@ -170,7 +170,6 @@ function nggallery_manage_gallery_main() {
170
  //-->
171
  </script>
172
  <div class="wrap">
173
- <?php screen_icon( 'nextgen-gallery' ); ?>
174
  <h2><?php echo _n( 'Manage Galleries', 'Manage Galleries', 2, 'nggallery'); ?></h2>
175
  <form class="search-form" action="" method="get">
176
  <p class="search-box">
53
 
54
  // If a new gallery is added, refresh the page
55
  Frame_Event_Publisher.listen_for('attach_to_post:new_gallery attach_to_post:manage_images attach_to_post:images_added',function(){
56
+ window.location.href = window.location.href.toString();
57
  });
58
  }
59
 
170
  //-->
171
  </script>
172
  <div class="wrap">
 
173
  <h2><?php echo _n( 'Manage Galleries', 'Manage Galleries', 2, 'nggallery'); ?></h2>
174
  <form class="search-form" action="" method="get">
175
  <p class="search-box">
products/photocrati_nextgen/modules/ngglegacy/admin/manage-images.php CHANGED
@@ -301,7 +301,6 @@ jQuery(document).ready( function($) {
301
  //-->
302
  </script>
303
  <div class="wrap">
304
- <?php screen_icon( 'nextgen-gallery' ); ?>
305
  <?php if ($is_search) :?>
306
  <h2><?php printf( __('Search results for &#8220;%s&#8221;', 'nggallery'), esc_html( get_search_query() ) ); ?></h2>
307
  <form class="search-form" action="" method="get">
301
  //-->
302
  </script>
303
  <div class="wrap">
 
304
  <?php if ($is_search) :?>
305
  <h2><?php printf( __('Search results for &#8220;%s&#8221;', 'nggallery'), esc_html( get_search_query() ) ); ?></h2>
306
  <form class="search-form" action="" method="get">
products/photocrati_nextgen/modules/ngglegacy/admin/manage-sort.php CHANGED
@@ -77,7 +77,7 @@ function nggallery_sortorder($galleryID = 0){
77
  // Listen for events in other frames
78
  if (window.Frame_Event_Publisher) {
79
  Frame_Event_Publisher.listen_for('attach_to_post:manage_galleries attach_to_post:manage_images', function(){
80
- window.location.href = window.location.href;
81
  });
82
  }
83
 
77
  // Listen for events in other frames
78
  if (window.Frame_Event_Publisher) {
79
  Frame_Event_Publisher.listen_for('attach_to_post:manage_galleries attach_to_post:manage_images', function(){
80
+ window.location.href = window.location.href.toString();
81
  });
82
  }
83
 
products/photocrati_nextgen/modules/ngglegacy/admin/manage.php CHANGED
@@ -592,6 +592,9 @@ class nggManageGallery {
592
  nggGallery::show_message(sprintf(__('One or more "../" in Gallery paths could be unsafe and NextGen Gallery will not delete gallery %s automatically', 'nggallery'), $gallery->{$gallery->id_field}));
593
  }
594
  else {
 
 
 
595
  if ($mapper->destroy($id, TRUE))
596
  $deleted = TRUE;
597
  }
@@ -1117,6 +1120,7 @@ class nggManageGallery {
1117
  $pagination = "<div class='tablenav-pages{$page_class}'>$output</div>";
1118
 
1119
  echo $pagination;
 
1120
  }
1121
 
1122
  }
592
  nggGallery::show_message(sprintf(__('One or more "../" in Gallery paths could be unsafe and NextGen Gallery will not delete gallery %s automatically', 'nggallery'), $gallery->{$gallery->id_field}));
593
  }
594
  else {
595
+ /**
596
+ * @var $mapper Mixin_Gallery_Mapper
597
+ */
598
  if ($mapper->destroy($id, TRUE))
599
  $deleted = TRUE;
600
  }
1120
  $pagination = "<div class='tablenav-pages{$page_class}'>$output</div>";
1121
 
1122
  echo $pagination;
1123
+ return $pagination;
1124
  }
1125
 
1126
  }
products/photocrati_nextgen/modules/ngglegacy/admin/overview.php CHANGED
@@ -152,7 +152,7 @@ class C_NGG_Admin_Overview
152
  * nggallery_admin_overview()
153
  *
154
  * Add the admin overview the dashboard style
155
- * @return mixed content
156
  */
157
  function nggallery_admin_overview()
158
  {
@@ -397,4 +397,5 @@ function nggallery_admin_overview()
397
  </div>
398
 
399
  <?php
 
400
  }
152
  * nggallery_admin_overview()
153
  *
154
  * Add the admin overview the dashboard style
155
+ * @return NULL
156
  */
157
  function nggallery_admin_overview()
158
  {
397
  </div>
398
 
399
  <?php
400
+ return NULL;
401
  }
products/photocrati_nextgen/modules/ngglegacy/admin/tags.php CHANGED
@@ -95,7 +95,6 @@ if ($nb_tags < $tag_count && $offset>0) {
95
  </style>
96
 
97
  <div class="wrap ngg_wrap">
98
- <?php screen_icon( 'nextgen-gallery' ); ?>
99
  <h2><?php _e('Manage image tags', 'nggallery'); ?></h2>
100
 
101
  <?php if ($action_status['message']!='') : ?>
95
  </style>
96
 
97
  <div class="wrap ngg_wrap">
 
98
  <h2><?php _e('Manage image tags', 'nggallery'); ?></h2>
99
 
100
  <?php if ($action_status['message']!='') : ?>
products/photocrati_nextgen/modules/ngglegacy/lib/class.ngg_serializable.php CHANGED
@@ -9,8 +9,17 @@ class Ngg_Serializable
9
  */
10
  function serialize($value)
11
  {
 
 
 
 
 
 
 
 
 
12
  //Using json_encode here because PHP's serialize is not Unicode safe
13
- return base64_encode(json_encode($value));
14
  }
15
 
16
 
9
  */
10
  function serialize($value)
11
  {
12
+ // Try encoding using JSON. It's usually Unicode safe but still, sometimes trips over
13
+ // things
14
+ $serialized = @json_encode($value);
15
+
16
+ if (!$serialized) {
17
+ $serialized = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/u', '', $value);
18
+ $serialized = @json_encode($serialized);
19
+ }
20
+
21
  //Using json_encode here because PHP's serialize is not Unicode safe
22
+ return base64_encode($serialized);
23
  }
24
 
25
 
products/photocrati_nextgen/modules/ngglegacy/lib/core.php CHANGED
@@ -129,7 +129,7 @@ class nggGallery {
129
  * @param string $template_name Name of the template file (without extension)
130
  * @param string $vars Array of variable name=>value that is available to the display code (optional)
131
  * @deprecated Use C_Displayed_Gallery_Renderer class
132
- * @return void
133
  **/
134
  static function capture ($template_name, $vars = array ())
135
  {
@@ -216,7 +216,7 @@ class nggGallery {
216
  }
217
  }
218
  }
219
- return;
220
  }
221
 
222
  /**
129
  * @param string $template_name Name of the template file (without extension)
130
  * @param string $vars Array of variable name=>value that is available to the display code (optional)
131
  * @deprecated Use C_Displayed_Gallery_Renderer class
132
+ * @return string
133
  **/
134
  static function capture ($template_name, $vars = array ())
135
  {
216
  }
217
  }
218
  }
219
+ return '';
220
  }
221
 
222
  /**
products/photocrati_nextgen/modules/ngglegacy/lib/imagemagick.inc.php CHANGED
@@ -188,13 +188,13 @@ var $imageMagickBefore;
188
  * @param string $cmd an ImageMagick command (eg. "convert")
189
  * @param string $args the arguments which should be passed
190
  * @param bool �passthru(optional) output the result to the webserver instead
191
- * @return void | if passthru return the image
192
  */
193
  function execute( $cmd, $args, $passthru = false) {
194
 
195
  // in error case we do not continue
196
  if($this->error == true)
197
- return;
198
 
199
  //if path is not empty
200
  if ($this->imageMagickDir != '') {
@@ -218,7 +218,7 @@ var $imageMagickBefore;
218
  // for single pic we need the direct output
219
  header('Content-type: image/jpeg');
220
  $this->errmsg = "{$this->imageMagickDir}{$cmd} {$args}";
221
- passthru( "{$this->imageMagickDir}{$cmd} {$args}" );
222
  }
223
 
224
 
188
  * @param string $cmd an ImageMagick command (eg. "convert")
189
  * @param string $args the arguments which should be passed
190
  * @param bool �passthru(optional) output the result to the webserver instead
191
+ * @return string
192
  */
193
  function execute( $cmd, $args, $passthru = false) {
194
 
195
  // in error case we do not continue
196
  if($this->error == true)
197
+ return '';
198
 
199
  //if path is not empty
200
  if ($this->imageMagickDir != '') {
218
  // for single pic we need the direct output
219
  header('Content-type: image/jpeg');
220
  $this->errmsg = "{$this->imageMagickDir}{$cmd} {$args}";
221
+ return passthru( "{$this->imageMagickDir}{$cmd} {$args}" );
222
  }
223
 
224
 
products/photocrati_nextgen/modules/ngglegacy/lib/meta.php CHANGED
@@ -99,7 +99,7 @@ class nggMeta{
99
 
100
  // on request sanitize the output
101
  if ( $this->sanitize == true )
102
- array_walk( $meta , create_function('&$value', '$value = esc_html($value);'));
103
 
104
  return $meta;
105
  }
@@ -187,7 +187,7 @@ class nggMeta{
187
 
188
  // on request sanitize the output
189
  if ( $this->sanitize == true )
190
- array_walk( $this->exif_array , create_function('&$value', '$value = esc_html($value);'));
191
 
192
  return $this->exif_array;
193
 
@@ -266,7 +266,7 @@ class nggMeta{
266
 
267
  // on request sanitize the output
268
  if ( $this->sanitize == true )
269
- array_walk( $this->iptc_array , create_function('&$value', '$value = esc_html($value);'));
270
 
271
  return $this->iptc_array;
272
  }
@@ -408,7 +408,7 @@ class nggMeta{
408
 
409
  // on request sanitize the output
410
  if ( $this->sanitize == true )
411
- array_walk( $this->xmp_array , create_function('&$value', '$value = esc_html($value);'));
412
 
413
  return $this->xmp_array;
414
  }
@@ -421,6 +421,7 @@ class nggMeta{
421
  } else {
422
  $array = $value;
423
  }
 
424
  }
425
 
426
  /**
@@ -530,7 +531,7 @@ class nggMeta{
530
  * Reason : GD manipulation removes that options
531
  *
532
  * @since V1.4.0
533
- * @return void
534
  */
535
  function get_common_meta() {
536
  global $wpdb;
99
 
100
  // on request sanitize the output
101
  if ( $this->sanitize == true )
102
+ array_walk( $meta , 'esc_html');
103
 
104
  return $meta;
105
  }
187
 
188
  // on request sanitize the output
189
  if ( $this->sanitize == true )
190
+ array_walk( $this->exif_array , 'esc_html');
191
 
192
  return $this->exif_array;
193
 
266
 
267
  // on request sanitize the output
268
  if ( $this->sanitize == true )
269
+ array_walk( $this->iptc_array , 'esc_html');
270
 
271
  return $this->iptc_array;
272
  }
408
 
409
  // on request sanitize the output
410
  if ( $this->sanitize == true )
411
+ array_walk( $this->xmp_array , 'esc_html');
412
 
413
  return $this->xmp_array;
414
  }
421
  } else {
422
  $array = $value;
423
  }
424
+ return $array;
425
  }
426
 
427
  /**
531
  * Reason : GD manipulation removes that options
532
  *
533
  * @since V1.4.0
534
+ * @return array
535
  */
536
  function get_common_meta() {
537
  global $wpdb;
products/photocrati_nextgen/modules/ngglegacy/lib/ngg-db.php CHANGED
@@ -209,7 +209,7 @@ class nggdb
209
  * @param bool $exclude
210
  * @return An array containing the nggImage objects representing the images in the gallery.
211
  */
212
- function get_ids_from_gallery($id, $order_by = 'sortorder', $order_dir = 'ASC', $exclude = true) {
213
 
214
  global $wpdb;
215
 
@@ -738,7 +738,7 @@ class nggdb
738
 
739
  // split the words it a array if seperated by a space or comma
740
  preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $request, $matches);
741
- $search_terms = array_map(create_function('$a', 'return trim($a, "\\"\'\\n\\r ");'), $matches[0]);
742
 
743
  $n = '%';
744
  $searchand = '';
@@ -783,6 +783,11 @@ class nggdb
783
  return null;
784
  }
785
 
 
 
 
 
 
786
  /**
787
  * search for galleries and return the result
788
  *
@@ -801,7 +806,7 @@ class nggdb
801
 
802
  // split the words it a array if seperated by a space or comma
803
  preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $request, $matches);
804
- $search_terms = array_map(create_function('$a', 'return trim($a, "\\"\'\\n\\r ");'), $matches[0]);
805
 
806
  $n = '%';
807
  $searchand = '';
@@ -849,7 +854,7 @@ class nggdb
849
 
850
  // split the words it a array if seperated by a space or comma
851
  preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $request, $matches);
852
- $search_terms = array_map(create_function('$a', 'return trim($a, "\\"\'\\n\\r ");'), $matches[0]);
853
 
854
  $n = '%';
855
  $searchand = '';
209
  * @param bool $exclude
210
  * @return An array containing the nggImage objects representing the images in the gallery.
211
  */
212
+ static function get_ids_from_gallery($id, $order_by = 'sortorder', $order_dir = 'ASC', $exclude = true) {
213
 
214
  global $wpdb;
215
 
738
 
739
  // split the words it a array if seperated by a space or comma
740
  preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $request, $matches);
741
+ $search_terms = array_map(array($this, 'trim_quotes_and_whitespace'), $matches[0]);
742
 
743
  $n = '%';
744
  $searchand = '';
783
  return null;
784
  }
785
 
786
+ function trim_quotes_and_whitespace($str)
787
+ {
788
+ return trim($str, "\"'\n\r");
789
+ }
790
+
791
  /**
792
  * search for galleries and return the result
793
  *
806
 
807
  // split the words it a array if seperated by a space or comma
808
  preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $request, $matches);
809
+ $search_terms = array_map(array($this, 'trim_quotes_and_whitespace'), $matches[0]);
810
 
811
  $n = '%';
812
  $searchand = '';
854
 
855
  // split the words it a array if seperated by a space or comma
856
  preg_match_all('/".*?("|$)|((?<=[\\s",+])|^)[^\\s",+]+/', $request, $matches);
857
+ $search_terms = array_map(array($this, 'trim_quotes_and_whitespace'), $matches[0]);
858
 
859
  $n = '%';
860
  $searchand = '';
products/photocrati_nextgen/modules/ngglegacy/lib/sitemap.php CHANGED
@@ -11,15 +11,9 @@ class nggSitemaps {
11
 
12
  var $images = array();
13
 
14
- /**
15
- * nggSitemaps::__construct()
16
- *
17
- * @return
18
- */
19
- function __construct() {
20
-
21
  add_filter('wpseo_sitemap_urlimages', array( &$this, 'add_wpseo_xml_sitemap_images'), 10, 2);
22
-
23
  }
24
 
25
  /**
@@ -97,7 +91,7 @@ class nggSitemaps {
97
  * Parse the single image shortcode and return all images into an array
98
  *
99
  * @param array $atts
100
- * @return
101
  */
102
  function add_images( $atts ) {
103
 
@@ -110,7 +104,7 @@ class nggSitemaps {
110
 
111
  // Some error checks
112
  if ( count($pids) == 0 )
113
- return;
114
 
115
  $images = nggdb::find_images_in_list( $pids );
116
 
11
 
12
  var $images = array();
13
 
14
+ function __construct()
15
+ {
 
 
 
 
 
16
  add_filter('wpseo_sitemap_urlimages', array( &$this, 'add_wpseo_xml_sitemap_images'), 10, 2);
 
17
  }
18
 
19
  /**
91
  * Parse the single image shortcode and return all images into an array
92
  *
93
  * @param array $atts
94
+ * @return string
95
  */
96
  function add_images( $atts ) {
97
 
104
 
105
  // Some error checks
106
  if ( count($pids) == 0 )
107
+ return '';
108
 
109
  $images = nggdb::find_images_in_list( $pids );
110
 
products/photocrati_nextgen/modules/ngglegacy/lib/tags.php CHANGED
@@ -394,5 +394,6 @@ if (!function_exists('nggtags_delete_empty_element')) {
394
  if ( !empty($element) ) {
395
  return $element;
396
  }
 
397
  }
398
  }
394
  if ( !empty($element) ) {
395
  return $element;
396
  }
397
+ return NULL;
398
  }
399
  }
products/photocrati_nextgen/modules/ngglegacy/module.ngglegacy.php CHANGED
@@ -23,7 +23,7 @@ class M_NggLegacy extends C_Base_Module
23
  'photocrati-nextgen-legacy',
24
  'NextGEN Legacy',
25
  'Embeds the original version of NextGEN 1.9.3 by Alex Rabe',
26
- '0.21',
27
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
28
  'Imagely',
29
  'https://www.imagely.com'
23
  'photocrati-nextgen-legacy',
24
  'NextGEN Legacy',
25
  'Embeds the original version of NextGEN 1.9.3 by Alex Rabe',
26
+ '0.22',
27
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
28
  'Imagely',
29
  'https://www.imagely.com'
products/photocrati_nextgen/modules/ngglegacy/nggallery.php CHANGED
@@ -66,7 +66,7 @@ class nggLoader
66
 
67
  // Pass the init check or show a message
68
  if (get_option( 'ngg_init_check' ) != false )
69
- add_action( 'admin_notices', create_function('', 'echo \'<div id="message" class="error"><p><strong>' . get_option( "ngg_init_check" ) . '</strong></p></div>\';') );
70
 
71
  } else {
72
 
@@ -77,6 +77,11 @@ class nggLoader
77
  }
78
  }
79
 
 
 
 
 
 
80
  function required_version() {
81
 
82
  global $wp_version;
@@ -87,10 +92,7 @@ class nggLoader
87
  if ( ($wp_ok == FALSE) ) {
88
  add_action(
89
  'admin_notices',
90
- create_function(
91
- '',
92
- 'global $ngg; printf (\'<div id="message" class="error"><p><strong>\' . __(\'Sorry, NextGEN Gallery works only under WordPress %s or higher\', "nggallery" ) . \'</strong></p></div>\', $ngg->minimum_WP );'
93
- )
94
  );
95
  return false;
96
  }
@@ -99,6 +101,14 @@ class nggLoader
99
 
100
  }
101
 
 
 
 
 
 
 
 
 
102
  function check_memory_limit() {
103
 
104
  // get the real memory limit before some increase it
@@ -113,13 +123,10 @@ class nggLoader
113
  $this->memory_limit = (int) substr( $this->memory_limit, 0, -1);
114
 
115
  //This works only with enough memory, 16MB is silly, wordpress requires already 16MB :-)
116
- if ( ($this->memory_limit != 0) && ($this->memory_limit < 16 ) ) {
117
  add_action(
118
  'admin_notices',
119
- create_function(
120
- '',
121
- 'echo \'<div id="message" class="error"><p><strong>' . __('Sorry, NextGEN Gallery works only with a Memory Limit of 16 MB or higher', 'nggallery') . '</strong></p></div>\';'
122
- )
123
  );
124
  return false;
125
  }
@@ -129,6 +136,14 @@ class nggLoader
129
 
130
  }
131
 
 
 
 
 
 
 
 
 
132
  function define_tables() {
133
  global $wpdb;
134
 
@@ -261,12 +276,6 @@ class nggLoader
261
  if( isset($option->response[ $this->plugin_name ]) ){
262
  //Clear it''s download link
263
  $option->response[ $this->plugin_name ]->package = '';
264
-
265
- //Add a notice message
266
- if ($this->add_PHP5_notice == false){
267
- add_action( "in_plugin_update_message-$this->plugin_name", create_function('', 'echo \'<br /><span style="color:red">Please update to PHP5.2 as soon as possible, the plugin is not tested under PHP4 anymore</span>\';') );
268
- $this->add_PHP5_notice = true;
269
- }
270
  }
271
  return $option;
272
  }
@@ -286,11 +295,21 @@ class nggLoader
286
 
287
  // If test-head query var exists hook into wp_head
288
  if ( isset( $_GET['test-head'] ) )
289
- add_action( 'wp_head', create_function('', 'echo \'<!--wp_head-->\';'), 99999 );
290
 
291
  // If test-footer query var exists hook into wp_footer
292
  if ( isset( $_GET['test-footer'] ) )
293
- add_action( 'wp_footer', create_function('', 'echo \'<!--wp_footer-->\';'), 99999 );
 
 
 
 
 
 
 
 
 
 
294
  }
295
  }
296
 
66
 
67
  // Pass the init check or show a message
68
  if (get_option( 'ngg_init_check' ) != false )
69
+ add_action( 'admin_notices', array($this, 'output_init_check_error'));
70
 
71
  } else {
72
 
77
  }
78
  }
79
 
80
+ function output_init_check_error()
81
+ {
82
+ echo sprintf("<div id='message' class='error'><p><strong>%s</strong></p></div>", esc_html(get_option('ngg_init_check')));
83
+ }
84
+
85
  function required_version() {
86
 
87
  global $wp_version;
92
  if ( ($wp_ok == FALSE) ) {
93
  add_action(
94
  'admin_notices',
95
+ array($this, 'output_minimum_wp_version_error')
 
 
 
96
  );
97
  return false;
98
  }
101
 
102
  }
103
 
104
+ function output_minimum_wp_version_error()
105
+ {
106
+ echo sprintf(
107
+ "<div id='message' class='error'><p><strong>%s</strong></p></div>",
108
+ sprintf(__("Sorry, NextGEN Gallery works only under WordPress %s or higher.", 'nggallery'), $this->minimum_WP)
109
+ );
110
+ }
111
+
112
  function check_memory_limit() {
113
 
114
  // get the real memory limit before some increase it
123
  $this->memory_limit = (int) substr( $this->memory_limit, 0, -1);
124
 
125
  //This works only with enough memory, 16MB is silly, wordpress requires already 16MB :-)
126
+ if ( ($this->memory_limit != 0) && ($this->memory_limit < 32 ) ) {
127
  add_action(
128
  'admin_notices',
129
+ array($this, 'output_memory_limit_error')
 
 
 
130
  );
131
  return false;
132
  }
136
 
137
  }
138
 
139
+ function output_memory_limit_error()
140
+ {
141
+ echo sprintf(
142
+ "<div id='message' class='error'><p><strong>%s</strong></p>",
143
+ __("Sorry, NextGEN Gallery works only with a memory limit of 32MB or higher")
144
+ );
145
+ }
146
+
147
  function define_tables() {
148
  global $wpdb;
149
 
276
  if( isset($option->response[ $this->plugin_name ]) ){
277
  //Clear it''s download link
278
  $option->response[ $this->plugin_name ]->package = '';
 
 
 
 
 
 
279
  }
280
  return $option;
281
  }
295
 
296
  // If test-head query var exists hook into wp_head
297
  if ( isset( $_GET['test-head'] ) )
298
+ add_action( 'wp_head', array($this, 'output_wp_head_comment'), 99999 );
299
 
300
  // If test-footer query var exists hook into wp_footer
301
  if ( isset( $_GET['test-footer'] ) )
302
+ add_action( 'wp_footer', array($this, 'output_wp_footer_comment'), 99999 );
303
+ }
304
+
305
+ function output_wp_head_comment()
306
+ {
307
+ echo "<!--wp_user-->";
308
+ }
309
+
310
+ function output_wp_footer_comment()
311
+ {
312
+ echo "<!--wp_footer-->";
313
  }
314
  }
315
 
products/photocrati_nextgen/modules/{simplehtmldom → simple_html_dom}/module.simple_html_dom.php RENAMED
File without changes
products/photocrati_nextgen/modules/{simplehtmldom → simple_html_dom}/package.module.simple_html_dom.php RENAMED
File without changes
products/photocrati_nextgen/modules/{simplehtmldom → simple_html_dom}/simplehtmldom/simple_html_dom.php RENAMED
@@ -232,12 +232,8 @@ class simple_html_dom_node
232
  if ($echo)
233
  {
234
  echo $string;
235
- return;
236
- }
237
- else
238
- {
239
- return $string;
240
  }
 
241
  }
242
 
243
  // returns the parent of node
@@ -757,6 +753,8 @@ class simple_html_dom_node
757
  $this->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE;
758
  }
759
  $this->attr[$name] = $value;
 
 
760
  }
761
 
762
  function __isset($name)
@@ -1100,6 +1098,7 @@ class simple_html_dom
1100
  $this->clear();
1101
  return false;
1102
  }
 
1103
  }
1104
 
1105
  // set callback function
@@ -1629,6 +1628,7 @@ class simple_html_dom
1629
  $this->pos = $pos;
1630
  return substr($this->doc, $pos_old, $pos-$pos_old);
1631
  }
 
1632
  }
1633
 
1634
  // remove noise from html content
@@ -1703,6 +1703,7 @@ class simple_html_dom
1703
  return $noiseElement;
1704
  }
1705
  }
 
1706
  }
1707
  function __toString()
1708
  {
@@ -1724,6 +1725,7 @@ class simple_html_dom
1724
  case 'target_charset':
1725
  return $this->_target_charset;
1726
  }
 
1727
  }
1728
 
1729
  // camel naming conventions
@@ -1737,6 +1739,4 @@ class simple_html_dom
1737
  function getElementByTagName($name) {return $this->find($name, 0);}
1738
  function getElementsByTagName($name, $idx=-1) {return $this->find($name, $idx);}
1739
  function loadFile() {$args = func_get_args();$this->load_file($args);}
1740
- }
1741
-
1742
- ?>
232
  if ($echo)
233
  {
234
  echo $string;
 
 
 
 
 
235
  }
236
+ return $string;
237
  }
238
 
239
  // returns the parent of node
753
  $this->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE;
754
  }
755
  $this->attr[$name] = $value;
756
+
757
+ return $value;
758
  }
759
 
760
  function __isset($name)
1098
  $this->clear();
1099
  return false;
1100
  }
1101
+ return $this;
1102
  }
1103
 
1104
  // set callback function
1628
  $this->pos = $pos;
1629
  return substr($this->doc, $pos_old, $pos-$pos_old);
1630
  }
1631
+ return '';
1632
  }
1633
 
1634
  // remove noise from html content
1703
  return $noiseElement;
1704
  }
1705
  }
1706
+ return NULL;
1707
  }
1708
  function __toString()
1709
  {
1725
  case 'target_charset':
1726
  return $this->_target_charset;
1727
  }
1728
+ return '';
1729
  }
1730
 
1731
  // camel naming conventions
1739
  function getElementByTagName($name) {return $this->find($name, 0);}
1740
  function getElementsByTagName($name, $idx=-1) {return $this->find($name, $idx);}
1741
  function loadFile() {$args = func_get_args();$this->load_file($args);}
1742
+ }
 
 
products/photocrati_nextgen/modules/widget/package.module.widget.php CHANGED
@@ -33,6 +33,7 @@ class Mixin_Widget extends Mixin
33
  $options = array('title' => FALSE, 'items' => $number, 'show' => $show, 'type' => 'random', 'width' => $width, 'height' => $height, 'exclude' => $exclude, 'list' => $list, 'webslice' => FALSE);
34
  $widget = new C_Widget_Gallery();
35
  $widget->widget($args = array('widget_id' => 'sidebar_1'), $options);
 
36
  }
37
  /**
38
  * Function for templates without widget support
@@ -44,6 +45,7 @@ class Mixin_Widget extends Mixin
44
  $options = array('title' => FALSE, 'items' => $number, 'show' => $show, 'type' => 'recent', 'width' => $width, 'height' => $height, 'exclude' => $exclude, 'list' => $list, 'webslice' => FALSE);
45
  $widget = new C_Widget_Gallery();
46
  $widget->widget($args = array('widget_id' => 'sidebar_1'), $options);
 
47
  }
48
  /**
49
  * Function for templates without widget support
@@ -57,6 +59,7 @@ class Mixin_Widget extends Mixin
57
  {
58
  $widget = new C_Widget_Slideshow();
59
  $widget->render_slideshow($galleryID, $width, $height);
 
60
  }
61
  }
62
  class C_Widget_Gallery extends WP_Widget
33
  $options = array('title' => FALSE, 'items' => $number, 'show' => $show, 'type' => 'random', 'width' => $width, 'height' => $height, 'exclude' => $exclude, 'list' => $list, 'webslice' => FALSE);
34
  $widget = new C_Widget_Gallery();
35
  $widget->widget($args = array('widget_id' => 'sidebar_1'), $options);
36
+ return $widget;
37
  }
38
  /**
39
  * Function for templates without widget support
45
  $options = array('title' => FALSE, 'items' => $number, 'show' => $show, 'type' => 'recent', 'width' => $width, 'height' => $height, 'exclude' => $exclude, 'list' => $list, 'webslice' => FALSE);
46
  $widget = new C_Widget_Gallery();
47
  $widget->widget($args = array('widget_id' => 'sidebar_1'), $options);
48
+ return $widget;
49
  }
50
  /**
51
  * Function for templates without widget support
59
  {
60
  $widget = new C_Widget_Slideshow();
61
  $widget->render_slideshow($galleryID, $width, $height);
62
+ return $widget;
63
  }
64
  }
65
  class C_Widget_Gallery extends WP_Widget
products/photocrati_nextgen/product.photocrati_nextgen.php CHANGED
@@ -22,6 +22,7 @@ class P_Photocrati_NextGen extends C_Base_Product
22
  'photocrati-ajax' => 'always',
23
  'photocrati-datamapper' => 'always',
24
  'photocrati-nextgen-legacy' => 'always',
 
25
  'photocrati-nextgen-data' => 'always',
26
 
27
  // We should look at how to make the modules below only
@@ -52,7 +53,8 @@ class P_Photocrati_NextGen extends C_Base_Product
52
  'photocrati-widget' => 'always',
53
  'photocrati-third_party_compat' => 'always',
54
  'photocrati-nextgen_xmlrpc' => 'always',
55
- 'photocrati-wpcli' => 'always'
 
56
  );
57
 
58
  function get_modules_provided()
22
  'photocrati-ajax' => 'always',
23
  'photocrati-datamapper' => 'always',
24
  'photocrati-nextgen-legacy' => 'always',
25
+ 'photocrati-simple_html_dom' => 'always',
26
  'photocrati-nextgen-data' => 'always',
27
 
28
  // We should look at how to make the modules below only
53
  'photocrati-widget' => 'always',
54
  'photocrati-third_party_compat' => 'always',
55
  'photocrati-nextgen_xmlrpc' => 'always',
56
+ 'photocrati-wpcli' => 'always',
57
+ 'photocrati-imagify' => 'backend'
58
  );
59
 
60
  function get_modules_provided()
readme.txt CHANGED
@@ -2,11 +2,11 @@
2
  Contributors: photocrati, imagely
3
  Tags: wordpress gallery plugin, gallery, nextgen, nextgen gallery, photo gallery, image gallery, photography, slideshow, images, photo, photo album, watermark
4
  Requires at least: 4.0.0
5
- Stable tag: 2.2.33
6
- Tested up to: 4.9.1
7
  License: GPLv2
8
 
9
- The most popular WordPress gallery plugin and one of the most popular plugins of all time with over 18 million downloads.
10
 
11
  == Description ==
12
 
@@ -59,7 +59,7 @@ Learn more or connect with us:<br>
59
  == Credits ==
60
 
61
  Copyright:<br>
62
- Imagely 2016
63
  Photocrati Media 2012-2016<br>
64
  Alex Rabe 2007-2011
65
 
@@ -187,11 +187,32 @@ For more information, feel free to visit the official website for the NextGEN Ga
187
 
188
  == Changelog ==
189
 
190
- = V2.2.33 - 12.24.2017
191
- * Fixed: Certain image attributes were not being validated correctly
192
-
193
- = V2.2.30 - 12.13.2017
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
  * Fixed: Segfaults on PHP 7.2, 7.1.12, and 7.0.26.
 
 
 
 
195
 
196
  = V2.2.18 - 12.04.2017 =
197
  * NEW: Include PHP 7.2.0 in the warning created by NextGen Gallery 2.2.16
2
  Contributors: photocrati, imagely
3
  Tags: wordpress gallery plugin, gallery, nextgen, nextgen gallery, photo gallery, image gallery, photography, slideshow, images, photo, photo album, watermark
4
  Requires at least: 4.0.0
5
+ Stable tag: 2.2.45
6
+ Tested up to: 4.9.2
7
  License: GPLv2
8
 
9
+ The most popular WordPress gallery plugin and one of the most popular plugins of all time with over 20 million downloads.
10
 
11
  == Description ==
12
 
59
  == Credits ==
60
 
61
  Copyright:<br>
62
+ Imagely 2016-2018
63
  Photocrati Media 2012-2016<br>
64
  Alex Rabe 2007-2011
65
 
187
 
188
  == Changelog ==
189
 
190
+ = V2.2.45 - 02.14.2018 =
191
+ * NEW: Partner page for Imagify image optimization
192
+ * Secured: Image property escaping case-sensitive
193
+ * Secured: Vulnerable to CVE-2017-2416 buffer overflows
194
+ * Kudos: Zhouyuan Yang of Fortinet's FortiGuard Labs
195
+ * Fixed: Incorrect CSS class format used in form generator text field
196
+ * Fixed: Clean exit in FastCGI environments
197
+ * Fixed: Use of deprecated functions
198
+
199
+ = V2.2.43 - 02.05.2018 =
200
+ * NEW: Partner page for Imagify image optimization
201
+ * Secured: Image property escaping case-sensitive
202
+ * Secured: Vulnerable to CVE-2017-2416 buffer overflows
203
+ * Kudos: Zhouyuan Yang of Fortinet's FortiGuard Labs
204
+ * Fixed: Incorrect CSS class format used in form generator text field
205
+ * Fixed: Clean exit in FastCGI environments
206
+
207
+ = V2.2.33 - 12.24.2017 =
208
+ * Secured: Certain image attributes were not being validated correctly
209
+
210
+ = V2.2.30 - 12.13.2017 =
211
  * Fixed: Segfaults on PHP 7.2, 7.1.12, and 7.0.26.
212
+ * Fixed: Wizards initialized too early.
213
+ * Fixed: ImageBrowser display types generating warnings on PHP 7.2
214
+ * Fixed: Widgets causing WSOD on PHP 7.2
215
+ * Fixed: Removed create_function() calls (deprecated in PHP 7.2)
216
 
217
  = V2.2.18 - 12.04.2017 =
218
  * NEW: Include PHP 7.2.0 in the warning created by NextGen Gallery 2.2.16