NextGEN Gallery – WordPress Gallery Plugin - Version 3.2.15

Version Description

  • 09.10.2019 =
  • NEW: Automatically retry loading dynamic thumbnail generation urls
  • NEW: Use NGG_DISABLE_DYNAMIC_IMG_URLS constant to generate images in-process
  • Changed: Dynamic thumbnails are generated in their own PHP processes/url
  • Fixed: Distorted images and thumbnails
  • Fixed: Timeout when viewing large galleries
  • Fixed: Memory optimizations when generating images
Download this release

Release Info

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

Code changes from version 3.2.11 to 3.2.15

changelog.txt CHANGED
@@ -1,8 +1,16 @@
1
  NextGEN Gallery
2
  by Imagely
3
 
 
 
 
 
 
 
 
 
4
  = V3.2.11 - 08.27.2019 =
5
- Secured: IGW queries (reported by Tin Duong of Fortinet's FortiGuard Labs)
6
 
7
  = V3.2.10 - 07.23.2019 =
8
  * Changed: Updated branding for Freemius opt-in
1
  NextGEN Gallery
2
  by Imagely
3
 
4
+ = V3.2.15 - 09.10.2019 =
5
+ * NEW: Automatically retry loading dynamic thumbnail generation urls
6
+ * NEW: Use NGG_DISABLE_DYNAMIC_IMG_URLS constant to generate images in-process
7
+ * Changed: Dynamic thumbnails are generated in their own PHP processes/url
8
+ * Fixed: Distorted images and thumbnails
9
+ * Fixed: Timeout when viewing large galleries
10
+ * Fixed: Memory optimizations when generating images
11
+
12
  = V3.2.11 - 08.27.2019 =
13
+ * Secured: IGW queries (reported by Tin Duong of Fortinet's FortiGuard Labs)
14
 
15
  = V3.2.10 - 07.23.2019 =
16
  * Changed: Updated branding for Freemius opt-in
nggallery.php CHANGED
@@ -4,7 +4,7 @@ if(preg_match('#' . basename(__FILE__) . '#', $_SERVER['PHP_SELF'])) { die('You
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 26 million downloads.
7
- * Version: 3.2.11
8
  * Author: Imagely
9
  * Plugin URI: https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/
10
  * Author URI: https://www.imagely.com
@@ -101,7 +101,7 @@ class C_NextGEN_Bootstrap
101
  }
102
  }
103
  elseif (!($exception instanceof E_Clean_Exit)) {
104
- ob_end_clean();
105
  self::print_exception($exception);
106
  }
107
  }
@@ -714,7 +714,7 @@ class C_NextGEN_Bootstrap
714
  define('NGG_PRODUCT_URL', path_join(str_replace("\\" , '/', NGG_PLUGIN_URL), 'products'));
715
  define('NGG_MODULE_URL', path_join(str_replace("\\", '/', NGG_PRODUCT_URL), 'photocrati_nextgen/modules'));
716
  define('NGG_PLUGIN_STARTED_AT', microtime());
717
- define('NGG_PLUGIN_VERSION', '3.2.11');
718
 
719
  define(
720
  'NGG_SCRIPT_VERSION',
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 26 million downloads.
7
+ * Version: 3.2.15
8
  * Author: Imagely
9
  * Plugin URI: https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/
10
  * Author URI: https://www.imagely.com
101
  }
102
  }
103
  elseif (!($exception instanceof E_Clean_Exit)) {
104
+ if (ob_get_level() > 0) ob_end_clean();
105
  self::print_exception($exception);
106
  }
107
  }
714
  define('NGG_PRODUCT_URL', path_join(str_replace("\\" , '/', NGG_PLUGIN_URL), 'products'));
715
  define('NGG_MODULE_URL', path_join(str_replace("\\", '/', NGG_PRODUCT_URL), 'photocrati_nextgen/modules'));
716
  define('NGG_PLUGIN_STARTED_AT', microtime());
717
+ define('NGG_PLUGIN_VERSION', '3.2.15');
718
 
719
  define(
720
  'NGG_SCRIPT_VERSION',
non_pope/class.photocrati_resource_manager.php CHANGED
@@ -56,6 +56,7 @@ class C_Photocrati_Resource_Manager
56
  if (preg_match("#wp-admin/(network/)?update|wp-login|wp-signup#", $_SERVER['REQUEST_URI'])) $retval = FALSE;
57
  else if (isset($_GET['display_gallery_iframe'])) $retval = FALSE;
58
  else if (defined('WP_ADMIN') && WP_ADMIN && defined('DOING_AJAX') && DOING_AJAX) $retval = FALSE;
 
59
  else if (preg_match("/(js|css|xsl|xml|kml)$/", $_SERVER['REQUEST_URI'])) $retval = FALSE;
60
  else if (preg_match("#/feed(/?)$#i", $_SERVER['REQUEST_URI']) || !empty($_GET['feed'])) $retval = FALSE;
61
  elseif (preg_match("/\\.(\\w{3,4})$/", $_SERVER['REQUEST_URI'], $match)) {
56
  if (preg_match("#wp-admin/(network/)?update|wp-login|wp-signup#", $_SERVER['REQUEST_URI'])) $retval = FALSE;
57
  else if (isset($_GET['display_gallery_iframe'])) $retval = FALSE;
58
  else if (defined('WP_ADMIN') && WP_ADMIN && defined('DOING_AJAX') && DOING_AJAX) $retval = FALSE;
59
+ else if (strpos($_SERVER['REQUEST_URI'], '/nextgen-image/') !== FALSE) $retval = FALSE;
60
  else if (preg_match("/(js|css|xsl|xml|kml)$/", $_SERVER['REQUEST_URI'])) $retval = FALSE;
61
  else if (preg_match("#/feed(/?)$#i", $_SERVER['REQUEST_URI']) || !empty($_GET['feed'])) $retval = FALSE;
62
  elseif (preg_match("/\\.(\\w{3,4})$/", $_SERVER['REQUEST_URI'], $match)) {
products/photocrati_nextgen/modules/dynamic_thumbnails/module.dynamic_thumbnails.php CHANGED
@@ -20,7 +20,7 @@ class M_Dynamic_Thumbnails extends C_Base_Module
20
  'photocrati-dynamic_thumbnails',
21
  'Dynamic Thumbnails',
22
  'Adds support for dynamic thumbnails',
23
- '3.1.8',
24
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
25
  'Imagely',
26
  'https://www.imagely.com'
20
  'photocrati-dynamic_thumbnails',
21
  'Dynamic Thumbnails',
22
  'Adds support for dynamic thumbnails',
23
+ '3.2.13',
24
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
25
  'Imagely',
26
  'https://www.imagely.com'
products/photocrati_nextgen/modules/dynamic_thumbnails/package.module.dynamic_thumbnails.php CHANGED
@@ -27,6 +27,8 @@ class C_Dynamic_Thumbnails_Controller extends C_MVC_Controller
27
  }
28
  function index_action($return = FALSE)
29
  {
 
 
30
  $dynthumbs = C_Dynamic_Thumbnails_Manager::get_instance();
31
  $uri = $_SERVER['REQUEST_URI'];
32
  $params = $dynthumbs->get_params_from_uri($uri);
27
  }
28
  function index_action($return = FALSE)
29
  {
30
+ @set_time_limit(0);
31
+ @ini_set('memory_limit', '-1');
32
  $dynthumbs = C_Dynamic_Thumbnails_Manager::get_instance();
33
  $uri = $_SERVER['REQUEST_URI'];
34
  $params = $dynthumbs->get_params_from_uri($uri);
products/photocrati_nextgen/modules/nextgen_data/module.nextgen_data.php CHANGED
@@ -22,7 +22,7 @@ class M_NextGen_Data extends C_Base_Module
22
  'photocrati-nextgen-data',
23
  'NextGEN Data Tier',
24
  "Provides a data tier for NextGEN gallery based on the DataMapper module",
25
- '3.1.19',
26
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
27
  'Imagely',
28
  'https://www.imagely.com'
22
  'photocrati-nextgen-data',
23
  'NextGEN Data Tier',
24
  "Provides a data tier for NextGEN gallery based on the DataMapper module",
25
+ '3.2.13',
26
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
27
  'Imagely',
28
  'https://www.imagely.com'
products/photocrati_nextgen/modules/nextgen_data/package.module.nextgen_data.php CHANGED
@@ -4060,6 +4060,9 @@ class Mixin_GalleryStorage_Base_Dynamic extends Mixin
4060
  if ($generated && $save) {
4061
  $this->object->update_image_dimension_metadata($image, $image_abspath);
4062
  }
 
 
 
4063
  }
4064
  public function update_image_dimension_metadata($image, $image_abspath)
4065
  {
@@ -4110,6 +4113,9 @@ class Mixin_GalleryStorage_Base_Dynamic extends Mixin
4110
  if ($generated && $save) {
4111
  $this->object->update_image_dimension_metadata($image, $image_abspath);
4112
  }
 
 
 
4113
  }
4114
  /**
4115
  * Generates a thumbnail for an image
@@ -4428,18 +4434,17 @@ class Mixin_GalleryStorage_Base_Getters extends Mixin
4428
  $dynthumbs = C_Dynamic_Thumbnails_Manager::get_instance();
4429
  $abspath = $this->object->get_image_abspath($image, $size, TRUE);
4430
  if ($abspath) {
4431
- $dims = getimagesize($abspath);
4432
  if ($dims) {
4433
  $retval['width'] = $dims[0];
4434
  $retval['height'] = $dims[1];
4435
  }
4436
  } elseif ($size == 'backup') {
4437
  $retval = $this->object->get_image_dimensions($image, 'full');
4438
- } else {
4439
- if ($dynthumbs && $dynthumbs->is_size_dynamic($size)) {
4440
- $new_dims = $this->object->calculate_image_size_dimensions($image, $size);
4441
- $retval = array('width' => $new_dims['real_width'], 'height' => $new_dims['real_height']);
4442
- }
4443
  }
4444
  }
4445
  }
@@ -4504,10 +4509,14 @@ class Mixin_GalleryStorage_Base_Getters extends Mixin
4504
  // Get the image abspath
4505
  $image_abspath = $this->object->get_image_abspath($image, $size);
4506
  if ($dynthumbs->is_size_dynamic($size) && !file_exists($image_abspath)) {
4507
- $params = array('watermark' => false, 'reflection' => false, 'crop' => true);
4508
- $result = $this->generate_image_size($image, $size, $params);
4509
- if ($result) {
4510
- $image_abspath = $this->object->get_image_abspath($image, $size);
 
 
 
 
4511
  }
4512
  }
4513
  // Assuming we have an abspath, we can translate that to a url
@@ -4556,10 +4565,25 @@ class Mixin_GalleryStorage_Base_Getters extends Mixin
4556
  $retval = NULL;
4557
  $image_id = is_numeric($image) ? $image : $image->pid;
4558
  $key = strval($image_id) . $size;
 
4559
  if (!isset(self::$image_url_cache[$key])) {
4560
- self::$image_url_cache[$key] = $this->object->_get_computed_image_url($image, $size);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4561
  }
4562
- $retval = self::$image_url_cache[$key];
4563
  return apply_filters('ngg_get_image_url', $retval, $image, $size);
4564
  }
4565
  /**
@@ -4995,7 +5019,10 @@ class Mixin_GalleryStorage_Base_Management extends Mixin
4995
  if ($named_size === 'thumbnail') {
4996
  unset($image->meta_data[$named_size]['crop_frame']);
4997
  }
4998
- $this->object->generate_image_clone($full_abspath, $this->object->get_image_abspath($image, $named_size), $this->object->get_image_size_params($image, $named_size));
 
 
 
4999
  }
5000
  do_action('ngg_recovered_image', $image);
5001
  // Reimport all metadata
4060
  if ($generated && $save) {
4061
  $this->object->update_image_dimension_metadata($image, $image_abspath);
4062
  }
4063
+ if ($generated) {
4064
+ $generated->destruct();
4065
+ }
4066
  }
4067
  public function update_image_dimension_metadata($image, $image_abspath)
4068
  {
4113
  if ($generated && $save) {
4114
  $this->object->update_image_dimension_metadata($image, $image_abspath);
4115
  }
4116
+ if ($generated) {
4117
+ $generated->destruct();
4118
+ }
4119
  }
4120
  /**
4121
  * Generates a thumbnail for an image
4434
  $dynthumbs = C_Dynamic_Thumbnails_Manager::get_instance();
4435
  $abspath = $this->object->get_image_abspath($image, $size, TRUE);
4436
  if ($abspath) {
4437
+ $dims = @getimagesize($abspath);
4438
  if ($dims) {
4439
  $retval['width'] = $dims[0];
4440
  $retval['height'] = $dims[1];
4441
  }
4442
  } elseif ($size == 'backup') {
4443
  $retval = $this->object->get_image_dimensions($image, 'full');
4444
+ }
4445
+ if (!$retval && $dynthumbs && $dynthumbs->is_size_dynamic($size)) {
4446
+ $new_dims = $this->object->calculate_image_size_dimensions($image, $size);
4447
+ $retval = array('width' => $new_dims['real_width'], 'height' => $new_dims['real_height']);
 
4448
  }
4449
  }
4450
  }
4509
  // Get the image abspath
4510
  $image_abspath = $this->object->get_image_abspath($image, $size);
4511
  if ($dynthumbs->is_size_dynamic($size) && !file_exists($image_abspath)) {
4512
+ if (defined('NGG_DISABLE_DYNAMIC_IMG_URLS') && constant('NGG_DISABLE_DYNAMIC_IMG_URLS')) {
4513
+ $params = array('watermark' => false, 'reflection' => false, 'crop' => true);
4514
+ $result = $this->generate_image_size($image, $size, $params);
4515
+ if ($result) {
4516
+ $image_abspath = $this->object->get_image_abspath($image, $size);
4517
+ }
4518
+ } else {
4519
+ return NULL;
4520
  }
4521
  }
4522
  // Assuming we have an abspath, we can translate that to a url
4565
  $retval = NULL;
4566
  $image_id = is_numeric($image) ? $image : $image->pid;
4567
  $key = strval($image_id) . $size;
4568
+ $success = TRUE;
4569
  if (!isset(self::$image_url_cache[$key])) {
4570
+ $url = $this->object->_get_computed_image_url($image, $size);
4571
+ if ($url) {
4572
+ self::$image_url_cache[$key] = $url;
4573
+ $success = TRUE;
4574
+ } else {
4575
+ $success = FALSE;
4576
+ }
4577
+ }
4578
+ if ($success) {
4579
+ $retval = self::$image_url_cache[$key];
4580
+ } else {
4581
+ $dynthumbs = C_Dynamic_Thumbnails_Manager::get_instance();
4582
+ if ($dynthumbs->is_size_dynamic($size)) {
4583
+ $params = $dynthumbs->get_params_from_name($size);
4584
+ $retval = $dynthumbs->get_image_url($image, $params);
4585
+ }
4586
  }
 
4587
  return apply_filters('ngg_get_image_url', $retval, $image, $size);
4588
  }
4589
  /**
5019
  if ($named_size === 'thumbnail') {
5020
  unset($image->meta_data[$named_size]['crop_frame']);
5021
  }
5022
+ $thumbnail = $this->object->generate_image_clone($full_abspath, $this->object->get_image_abspath($image, $named_size), $this->object->get_image_size_params($image, $named_size));
5023
+ if ($thumbnail) {
5024
+ $thumbnail->destruct();
5025
+ }
5026
  }
5027
  do_action('ngg_recovered_image', $image);
5028
  // Reimport all metadata
products/photocrati_nextgen/modules/nextgen_gallery_display/module.nextgen_gallery_display.php CHANGED
@@ -23,7 +23,7 @@ class M_Gallery_Display extends C_Base_Module
23
  'photocrati-nextgen_gallery_display',
24
  'Gallery Display',
25
  'Provides the ability to display gallery of images',
26
- '3.2.11',
27
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
28
  'Imagely',
29
  'https://www.imagely.com'
23
  'photocrati-nextgen_gallery_display',
24
  'Gallery Display',
25
  'Provides the ability to display gallery of images',
26
+ '3.2.13',
27
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
28
  'Imagely',
29
  'https://www.imagely.com'
products/photocrati_nextgen/modules/nextgen_gallery_display/package.module.nextgen_gallery_display.php CHANGED
@@ -317,6 +317,17 @@ class Mixin_Display_Type_Controller extends Mixin
317
  {
318
  // This script provides common JavaScript among all display types
319
  wp_enqueue_script('ngg_common');
 
 
 
 
 
 
 
 
 
 
 
320
  // Enqueue the display type library
321
  wp_enqueue_script($displayed_gallery->display_type, $this->object->_get_js_lib_url($displayed_gallery), array(), NGG_SCRIPT_VERSION);
322
  // Add "galleries = {};"
@@ -856,9 +867,9 @@ class Mixin_Displayed_Gallery_Queries extends Mixin
856
  $sort_by = in_array(strtolower($this->object->order_by), C_Image_Mapper::get_instance()->get_column_names()) ? $this->object->order_by : $settings->galSort;
857
  // Quickly sanitize
858
  global $wpdb;
859
- $this->object->container_ids = array_map(array($wpdb, '_escape'), $this->object->container_ids);
860
- $this->object->entity_ids = array_map(array($wpdb, '_escape'), $this->object->entity_ids);
861
- $this->object->exclusions = array_map(array($wpdb, '_escape'), $this->object->exclusions);
862
  // Here's what this method is doing:
863
  // 1) Determines what results need returned
864
  // 2) Determines from what container ids the results should come from
@@ -1943,20 +1954,20 @@ class Mixin_Displayed_Gallery_Renderer extends Mixin
1943
  // Try getting the rendered HTML from the cache
1944
  $key = C_Photocrati_Transient_Manager::create_key('displayed_gallery_rendering', $key_params);
1945
  $html = C_Photocrati_Transient_Manager::fetch($key, FALSE);
1946
- // Output debug messages
1947
- if ($html) {
1948
- $retval .= $this->debug_msg("HIT!");
1949
- } else {
1950
- $retval .= $this->debug_msg("MISS!");
1951
- }
1952
- // TODO: This is hack. We need to figure out a more uniform way of detecting dynamic image urls
1953
- if (strpos($html, C_Photocrati_Settings_Manager::get_instance()->dynamic_thumbnail_slug . '/') !== FALSE) {
1954
- $html = FALSE;
1955
- // forces the cache to be re-generated
1956
- }
1957
  } else {
1958
  $retval .= $this->debug_msg("Not looking up in cache as per rules");
1959
  }
 
 
 
 
 
 
 
 
 
 
 
1960
  // If a cached version doesn't exist, then create the cache
1961
  if (!$html) {
1962
  $retval .= $this->debug_msg("Rendering displayed gallery");
317
  {
318
  // This script provides common JavaScript among all display types
319
  wp_enqueue_script('ngg_common');
320
+ wp_add_inline_script('ngg_common', '
321
+ var nggLastTimeoutVal = 1000;
322
+
323
+ var nggRetryFailedImage = function(img) {
324
+ setTimeout(function(){
325
+ img.src = img.src;
326
+ }, nggLastTimeoutVal);
327
+
328
+ nggLastTimeoutVal += 500;
329
+ }
330
+ ');
331
  // Enqueue the display type library
332
  wp_enqueue_script($displayed_gallery->display_type, $this->object->_get_js_lib_url($displayed_gallery), array(), NGG_SCRIPT_VERSION);
333
  // Add "galleries = {};"
867
  $sort_by = in_array(strtolower($this->object->order_by), C_Image_Mapper::get_instance()->get_column_names()) ? $this->object->order_by : $settings->galSort;
868
  // Quickly sanitize
869
  global $wpdb;
870
+ $this->object->container_ids = $this->object->container_ids ? array_map(array($wpdb, '_escape'), $this->object->container_ids) : array();
871
+ $this->object->entity_ids = $this->object->entity_ids ? array_map(array($wpdb, '_escape'), $this->object->entity_ids) : array();
872
+ $this->object->exclusions = $this->object->exclusions ? array_map(array($wpdb, '_escape'), $this->object->exclusions) : array();
873
  // Here's what this method is doing:
874
  // 1) Determines what results need returned
875
  // 2) Determines from what container ids the results should come from
1954
  // Try getting the rendered HTML from the cache
1955
  $key = C_Photocrati_Transient_Manager::create_key('displayed_gallery_rendering', $key_params);
1956
  $html = C_Photocrati_Transient_Manager::fetch($key, FALSE);
 
 
 
 
 
 
 
 
 
 
 
1957
  } else {
1958
  $retval .= $this->debug_msg("Not looking up in cache as per rules");
1959
  }
1960
+ // TODO: This is hack. We need to figure out a more uniform way of detecting dynamic image urls
1961
+ if (strpos($html, C_Photocrati_Settings_Manager::get_instance()->dynamic_thumbnail_slug . '/') !== FALSE) {
1962
+ $html = FALSE;
1963
+ // forces the cache to be re-generated
1964
+ }
1965
+ // Output debug messages
1966
+ if ($html) {
1967
+ $retval .= $this->debug_msg("HIT!");
1968
+ } else {
1969
+ $retval .= $this->debug_msg("MISS!");
1970
+ }
1971
  // If a cached version doesn't exist, then create the cache
1972
  if (!$html) {
1973
  $retval .= $this->debug_msg("Rendering displayed gallery");
readme.txt CHANGED
@@ -2,7 +2,7 @@
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: 3.2.11
6
  Tested up to: 5.2.2
7
  License: GPLv2
8
 
@@ -179,6 +179,14 @@ For more information, feel free to visit the official website for the NextGEN Ga
179
 
180
  == Changelog ==
181
 
 
 
 
 
 
 
 
 
182
  = V3.2.11 - 08.27.2019 =
183
  Secured: IGW queries (reported by Tin Duong of Fortinet's FortiGuard Labs)
184
 
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: 3.2.13
6
  Tested up to: 5.2.2
7
  License: GPLv2
8
 
179
 
180
  == Changelog ==
181
 
182
+ = V3.2.15 - 09.10.2019 =
183
+ * NEW: Automatically retry loading dynamic thumbnail generation urls
184
+ * NEW: Use NGG_DISABLE_DYNAMIC_IMG_URLS constant to generate images in-process
185
+ * Changed: Dynamic thumbnails are generated in their own PHP processes/url
186
+ * Fixed: Distorted images and thumbnails
187
+ * Fixed: Timeout when viewing large galleries
188
+ * Fixed: Memory optimizations when generating images
189
+
190
  = V3.2.11 - 08.27.2019 =
191
  Secured: IGW queries (reported by Tin Duong of Fortinet's FortiGuard Labs)
192