NextGEN Gallery – WordPress Gallery Plugin - Version 3.2.23

Version Description

  • 12.02.2019 =
  • NEW: There is a new setting under Other Options > Misc to disable enqueueing FontAwesome entirely
  • Changed: WP-CLI commands have been namespaced and numerous new commands have been added
  • Fixed: Add Gallery / Images page would instruct users to upload zip files even if the multisite settings disallowed it
  • Fixed: Conflict with Elementor breaking the Attach-To-Post window styling
  • Fixed: Corrected PHP warnings generated when creating the template & static override directory ('ngg') inside WP_CONTENT_DIR if write access isn't available
  • Fixed: Gallery slug generation was broken when the gallery name included special characters and broke those galleries as album children
  • Fixed: Improved performance on Manage Galleries page by simplifying query to count images belonging to galleries
  • Fixed: Manage Galleries could generate a PHP warning when listing galleries created by users that have since been deleted
  • Fixed: Shutter Reloaded's navigation icons were always missing
  • Fixed: Slideshow widget was enqueueing a file that no exists
  • Fixed: Two basic slideshow displays on one page would cause a JS error that broke their display
  • Fixed: URL resolution for paginated galleries and dynamic thumbnails was broken if WordPress was in a sub-directory of a sub-directory install (split home & site url)
Download this release

Release Info

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

Code changes from version 3.2.21 to 3.2.23

Files changed (26) hide show
  1. changelog.txt +14 -0
  2. nggallery.php +7 -8
  3. non_pope/class.photocrati_resource_manager.php +7 -1
  4. products/photocrati_nextgen/modules/lightbox/package.module.lightbox.php +5 -3
  5. products/photocrati_nextgen/modules/lightbox/static/shutter_reloaded/shutter.js +1 -4
  6. products/photocrati_nextgen/modules/lightbox/static/shutter_reloaded/shutter.min.js +1 -1
  7. products/photocrati_nextgen/modules/mvc/package.module.mvc.php +16 -16
  8. products/photocrati_nextgen/modules/nextgen_addgallery_page/templates/upload_images.php +9 -1
  9. products/photocrati_nextgen/modules/nextgen_admin/package.module.nextgen_admin.php +3 -3
  10. products/photocrati_nextgen/modules/nextgen_basic_album/package.module.nextgen_basic_album.php +4 -0
  11. products/photocrati_nextgen/modules/nextgen_basic_gallery/package.module.nextgen_basic_gallery.php +2 -2
  12. products/photocrati_nextgen/modules/nextgen_basic_gallery/static/slideshow/ngg_basic_slideshow.js +4 -13
  13. products/photocrati_nextgen/modules/nextgen_basic_gallery/static/slideshow/ngg_basic_slideshow.min.js +1 -1
  14. products/photocrati_nextgen/modules/nextgen_basic_gallery/templates/slideshow/index.php +42 -30
  15. products/photocrati_nextgen/modules/nextgen_data/package.module.nextgen_data.php +7 -6
  16. products/photocrati_nextgen/modules/nextgen_gallery_display/module.nextgen_gallery_display.php +4 -0
  17. products/photocrati_nextgen/modules/nextgen_other_options/package.module.nextgen_other_options.php +1 -1
  18. products/photocrati_nextgen/modules/nextgen_other_options/templates/misc_tab.php +2 -0
  19. products/photocrati_nextgen/modules/nextgen_pro_upgrade/module.nextgen_pro_upgrade.php +1 -1
  20. products/photocrati_nextgen/modules/nextgen_settings/module.nextgen_settings.php +2 -1
  21. products/photocrati_nextgen/modules/ngglegacy/admin/manage-galleries.php +6 -6
  22. products/photocrati_nextgen/modules/static_assets/module.static_assets.php +16 -13
  23. products/photocrati_nextgen/modules/widget/package.module.widget.php +1 -1
  24. products/photocrati_nextgen/modules/wpcli/include/ngg_wpcli.php +566 -0
  25. products/photocrati_nextgen/modules/wpcli/module.wpcli.php +7 -88
  26. readme.txt +16 -1
changelog.txt CHANGED
@@ -1,6 +1,20 @@
1
  NextGEN Gallery
2
  by Imagely
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  = V3.2.21 - 11.20.2019 =
5
  * Changed: Small branding and color update
6
 
1
  NextGEN Gallery
2
  by Imagely
3
 
4
+ = V3.2.23 - 12.02.2019 =
5
+ * NEW: There is a new setting under Other Options > Misc to disable enqueueing FontAwesome entirely
6
+ * Changed: WP-CLI commands have been namespaced and numerous new commands have been added
7
+ * Fixed: Add Gallery / Images page would instruct users to upload zip files even if the multisite settings disallowed it
8
+ * Fixed: Conflict with Elementor breaking the Attach-To-Post window styling
9
+ * Fixed: Corrected PHP warnings generated when creating the template & static override directory ('ngg') inside WP_CONTENT_DIR if write access isn't available
10
+ * Fixed: Gallery slug generation was broken when the gallery name included special characters and broke those galleries as album children
11
+ * Fixed: Improved performance on Manage Galleries page by simplifying query to count images belonging to galleries
12
+ * Fixed: Manage Galleries could generate a PHP warning when listing galleries created by users that have since been deleted
13
+ * Fixed: Shutter Reloaded's navigation icons were always missing
14
+ * Fixed: Slideshow widget was enqueueing a file that no exists
15
+ * Fixed: Two basic slideshow displays on one page would cause a JS error that broke their display
16
+ * Fixed: URL resolution for paginated galleries and dynamic thumbnails was broken if WordPress was in a sub-directory of a sub-directory install (split home & site url)
17
+
18
  = V3.2.21 - 11.20.2019 =
19
  * Changed: Small branding and color update
20
 
nggallery.php CHANGED
@@ -4,12 +4,13 @@ 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 27 million downloads.
7
- * Version: 3.2.21
8
  * Author: Imagely
9
  * Plugin URI: https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/
10
  * Author URI: https://www.imagely.com
11
  * License: GPLv2
12
  * Text Domain: nggallery
 
13
  * Domain Path: /products/photocrati_nextgen/modules/i18n/lang
14
  */
15
 
@@ -622,7 +623,7 @@ class C_NextGEN_Bootstrap
622
 
623
  // Set context to path if subdirectory install
624
  $parts = parse_url($router->get_base_url(FALSE));
625
- $siteparts = parse_url(get_option('siteurl'));
626
 
627
  if (isset($parts['path']) && isset($siteparts['path']))
628
  {
@@ -714,7 +715,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.21');
718
 
719
  define(
720
  'NGG_SCRIPT_VERSION',
@@ -957,9 +958,6 @@ function ngg_fs_custom_connect_message(
957
  );
958
  }
959
 
960
-
961
-
962
-
963
  /**
964
  * Add custom NextGEN Gallery icon for Freemius
965
  *
@@ -1074,8 +1072,9 @@ function ngg_fs( $activate_for_all = false ) {
1074
  }
1075
 
1076
  // Init Freemius
1077
- ngg_fs();
 
1078
 
1079
  // #endregion Freemius
1080
 
1081
- new C_NextGEN_Bootstrap();
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 27 million downloads.
7
+ * Version: 3.2.23
8
  * Author: Imagely
9
  * Plugin URI: https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/
10
  * Author URI: https://www.imagely.com
11
  * License: GPLv2
12
  * Text Domain: nggallery
13
+ * Requires PHP: 5.4
14
  * Domain Path: /products/photocrati_nextgen/modules/i18n/lang
15
  */
16
 
623
 
624
  // Set context to path if subdirectory install
625
  $parts = parse_url($router->get_base_url(FALSE));
626
+ $siteparts = parse_url(get_option('home'));
627
 
628
  if (isset($parts['path']) && isset($siteparts['path']))
629
  {
715
  define('NGG_PRODUCT_URL', path_join(str_replace("\\" , '/', NGG_PLUGIN_URL), 'products'));
716
  define('NGG_MODULE_URL', path_join(str_replace("\\", '/', NGG_PRODUCT_URL), 'photocrati_nextgen/modules'));
717
  define('NGG_PLUGIN_STARTED_AT', microtime());
718
+ define('NGG_PLUGIN_VERSION', '3.2.23');
719
 
720
  define(
721
  'NGG_SCRIPT_VERSION',
958
  );
959
  }
960
 
 
 
 
961
  /**
962
  * Add custom NextGEN Gallery icon for Freemius
963
  *
1072
  }
1073
 
1074
  // Init Freemius
1075
+ if (!defined('NGG_DISABLE_FREEMIUS') || !NGG_DISABLE_FREEMIUS)
1076
+ ngg_fs();
1077
 
1078
  // #endregion Freemius
1079
 
1080
+ new C_NextGEN_Bootstrap();
non_pope/class.photocrati_resource_manager.php CHANGED
@@ -82,7 +82,13 @@ class C_Photocrati_Resource_Manager
82
  */
83
  function start_buffer()
84
  {
85
- if (defined('NGG_DISABLE_RESOURCE_MANAGER') && NGG_DISABLE_RESOURCE_MANAGER)
 
 
 
 
 
 
86
  return;
87
 
88
  if (apply_filters('run_ngg_resource_manager', $this->valid_request)) {
82
  */
83
  function start_buffer()
84
  {
85
+ // This is admittedly an ugly hack, but much easier than reworking the entire nextgen_admin modules
86
+ if (!empty($_GET['page']) && $_GET['page'] === 'ngg_addgallery' && isset($_GET['attach_to_post']))
87
+ $force = TRUE;
88
+ else
89
+ $force = FALSE;
90
+
91
+ if (defined('NGG_DISABLE_RESOURCE_MANAGER') && NGG_DISABLE_RESOURCE_MANAGER && !$force)
92
  return;
93
 
94
  if (apply_filters('run_ngg_resource_manager', $this->valid_request)) {
products/photocrati_nextgen/modules/lightbox/package.module.lightbox.php CHANGED
@@ -197,13 +197,15 @@ class C_Lightbox_Library_Manager
197
  if (!wp_script_is('ngg_lightbox_context')) {
198
  wp_enqueue_script('ngg_lightbox_context', $router->get_static_url('photocrati-lightbox#lightbox_context.js'), array('ngg_common', 'photocrati_ajax'), NGG_SCRIPT_VERSION, TRUE);
199
  }
200
- // Make the path to the static resources available for libraries
201
- // Shutter-Reloaded in particular depends on this
 
 
202
  $this->_add_script_data(
203
  'ngg_common',
204
  // TODO: Should this be ngg_lightbox_context instead?
205
  'nextgen_lightbox_settings',
206
- array('static_path' => $router->get_static_url('', 'photocrati-lightbox'), 'context' => $thumbEffectContext),
207
  TRUE,
208
  TRUE
209
  );
197
  if (!wp_script_is('ngg_lightbox_context')) {
198
  wp_enqueue_script('ngg_lightbox_context', $router->get_static_url('photocrati-lightbox#lightbox_context.js'), array('ngg_common', 'photocrati_ajax'), NGG_SCRIPT_VERSION, TRUE);
199
  }
200
+ // Make the path to the static resources available for libraries.
201
+ //
202
+ // Yes the {placeholder} is a stupid hack but it's necessary for Shutter Reloaded and is much faster
203
+ // than making get_static_url() function without requesting a filename parameter
204
  $this->_add_script_data(
205
  'ngg_common',
206
  // TODO: Should this be ngg_lightbox_context instead?
207
  'nextgen_lightbox_settings',
208
+ array('static_path' => M_Static_Assets::get_static_url('{placeholder}', 'photocrati-lightbox'), 'context' => $thumbEffectContext),
209
  TRUE,
210
  TRUE
211
  );
products/photocrati_nextgen/modules/lightbox/static/shutter_reloaded/shutter.js CHANGED
@@ -20,9 +20,6 @@
20
  GNU General Public License for more details.
21
  */
22
 
23
- // Compute path to images
24
- var imagePath = nextgen_lightbox_settings.static_path + '/shutter_reloaded/images/';
25
-
26
  shutterReloaded = {
27
 
28
  // ***************************************************************************
@@ -37,7 +34,7 @@ shutterReloaded = {
37
  textBtns : false,
38
 
39
  // change the path to Shutter's image buttons directory if needed
40
- shImgDir : imagePath,
41
 
42
  // ***************************************************************************
43
 
20
  GNU General Public License for more details.
21
  */
22
 
 
 
 
23
  shutterReloaded = {
24
 
25
  // ***************************************************************************
34
  textBtns : false,
35
 
36
  // change the path to Shutter's image buttons directory if needed
37
+ shImgDir : nextgen_lightbox_settings.static_path.replace('/{placeholder}', '') + '/shutter_reloaded/images/',
38
 
39
  // ***************************************************************************
40
 
products/photocrati_nextgen/modules/lightbox/static/shutter_reloaded/shutter.min.js CHANGED
@@ -1 +1 @@
1
- var imagePath=nextgen_lightbox_settings.static_path+"/shutter_reloaded/images/";shutterReloaded={L10n:["Previous","Next","Close","Full Size","Fit to Screen","Image","of","Loading..."],imageCount:!0,textBtns:!1,shImgDir:imagePath,I:function(t){return document.getElementById(t)},Init:function(t){var e,i,s,h,n,o,l,d,r,a;for(h=0;h<document.links.length;h++)e=document.links[h],".jpg"!=(s=-1==e.href.indexOf("?")?e.href.slice(-4).toLowerCase():e.href.substring(0,e.href.indexOf("?")).slice(-4).toLowerCase())&&".png"!=s&&".gif"!=s&&"jpeg"!=s||"sh"==t&&-1==e.className.toLowerCase().indexOf("shutter")||"lb"==t&&-1==e.rel.toLowerCase().indexOf("lightbox")||(-1!=e.className.toLowerCase().indexOf("shutterset")?n=-1!=e.className.indexOf(" ")?e.className.slice(0,e.className.indexOf(" ")):e.className:-1!=e.rel.toLowerCase().indexOf("lightbox[")?n=e.rel:(n=0,o=-1),n&&(shutterSets[n]||(shutterSets[n]=[]),o=shutterSets[n].push(h)),l=e.href.slice(e.href.lastIndexOf("/")+1),i=e.title&&e.title!=l?e.title:"",shutterLinks[h]={link:e.href,num:o,set:n,title:i},e.onclick=new Function('shutterReloaded.Make("'+h+'");return false;'));if(!this.textBtns)for(d=["close.gif","prev.gif","next.gif","resize1.gif","resize2.gif","loading.gif"],r=0;r<d.length;r++)a=new Image,a.src=this.shImgDir+d[r]},Make:function(t,e){var i,s,h,n,o,l,d,r,a,u,g,m,c,w="",f="",p="";this.Top||(void 0!==window.pageYOffset?this.Top=window.pageYOffset:this.Top=document.documentElement.scrollTop>0?document.documentElement.scrollTop:document.body.scrollTop),void 0===this.pgHeight&&(this.pgHeight=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight)),this.FS=!!e||null,this.resizing&&(this.resizing=null),window.onresize=new Function('shutterReloaded.Resize("'+t+'");'),document.documentElement.style.overflowX="hidden",this.VP||(this._viewPort(),this.VP=!0),(r=this.I("shShutter"))||(r=document.createElement("div"),r.setAttribute("id","shShutter"),document.getElementsByTagName("body")[0].appendChild(r),this.fixTags()),(d=this.I("shDisplay"))||(d=document.createElement("div"),d.setAttribute("id","shDisplay"),d.style.top=this.Top+"px",document.getElementsByTagName("body")[0].appendChild(d)),r.style.height=this.pgHeight+"px";var y=this.textBtns?" | ":"";shutterLinks[t].num>1&&(i=shutterSets[shutterLinks[t].set][shutterLinks[t].num-2],o=this.textBtns?this.L10n[0]:'<img src="'+this.shImgDir+'prev.gif" title="'+this.L10n[0]+'" />',w='<a href="#" onclick="shutterReloaded.Make('+i+');return false">'+o+"</a>"+y,h=new Image,h.src=shutterLinks[i].link),-1!=shutterLinks[t].num&&shutterLinks[t].num<shutterSets[shutterLinks[t].set].length&&(s=shutterSets[shutterLinks[t].set][shutterLinks[t].num],l=this.textBtns?this.L10n[1]:'<img src="'+this.shImgDir+'next.gif" title="'+this.L10n[1]+'" />',f='<a href="#" onclick="shutterReloaded.Make('+s+');return false">'+l+"</a>"+y,n=new Image,n.src=shutterLinks[s].link),g=this.textBtns?this.L10n[2]:'<img src="'+this.shImgDir+'close.gif" title="'+this.L10n[2]+'" />',u=shutterLinks[t].num>0&&this.imageCount?" "+this.L10n[5]+"&nbsp;"+shutterLinks[t].num+"&nbsp;"+this.L10n[6]+"&nbsp;"+shutterSets[shutterLinks[t].set].length:"",u&&this.textBtns&&(u+=" |"),this.FS?m=this.textBtns?this.L10n[4]:'<img src="'+this.shImgDir+'resize2.gif" title="'+this.L10n[4]+'" />':(m=this.textBtns?this.L10n[3]:'<img src="'+this.shImgDir+'resize1.gif" title="'+this.L10n[3]+'" />',p=",1"),c='<span id="fullSize"><a href="#" onclick="shutterReloaded.Make('+t+p+');return false">'+m+"</a>"+y+"</span>",(a=this.I("shNavBar"))||(a=document.createElement("div"),a.setAttribute("id","shNavBar"),document.getElementsByTagName("body")[0].appendChild(a)),a.innerHTML=y+w+'<a href="#" onclick="shutterReloaded.hideShutter();return false">'+g+"</a>"+y+c+f+u,d.innerHTML='<div id="shWrap"><img src="'+shutterLinks[t].link+'" id="shTopImg" onload="shutterReloaded.ShowImg();" onclick="shutterReloaded.hideShutter();" /><div id="shTitle">'+shutterLinks[t].title+"</div></div>",window.setTimeout(function(){shutterReloaded.loading()},2e3)},loading:function(){var t,e,i;(i=this.I("shWrap"))&&"visible"==i.style.visibility||(t=this.I("shShutter"))&&(this.I("shWaitBar")||(e=document.createElement("div"),e.setAttribute("id","shWaitBar"),e.style.top=this.Top+"px",e.innerHTML='<img src="'+this.shImgDir+'loading.gif" title="'+this.L10n[7]+'" />',t.appendChild(e)))},hideShutter:function(){var t,e,i;(t=this.I("shDisplay"))&&t.parentNode.removeChild(t),(e=this.I("shShutter"))&&e.parentNode.removeChild(e),(i=this.I("shNavBar"))&&i.parentNode.removeChild(i),this.fixTags(!0),window.scrollTo(0,this.Top),window.onresize=this.FS=this.Top=this.VP=null,document.documentElement.style.overflowX=""},Resize:function(t){if(!this.resizing&&this.I("shShutter")){var e=this.I("shWrap");e&&(e.style.visibility="hidden"),window.setTimeout(function(){shutterReloaded.resizing=null},500),window.setTimeout(new Function('shutterReloaded.VP = null;shutterReloaded.Make("'+t+'");'),100),this.resizing=!0}},_viewPort:function(){var t=window.innerHeight?window.innerHeight:0,e=document.body.clientHeight?document.body.clientHeight:0,i=document.documentElement?document.documentElement.clientHeight:0;t>0?(this.wHeight=t-e>1&&t-e<30?e:t,this.wHeight=this.wHeight-i>1&&this.wHeight-i<30?i:this.wHeight):this.wHeight=i>0?i:e;var s=document.documentElement?document.documentElement.clientWidth:0,h=window.innerWidth?window.innerWidth:document.body.clientWidth;this.wWidth=s>1?s:h},ShowImg:function(){var t,e,i,s,h,n,o,l,d,r,a,u,g=0;(t=this.I("shShutter"))&&((e=this.I("shWrap"))&&"visible"==e.style.visibility||((i=this.I("shWaitBar"))&&i.parentNode.removeChild(i),s=this.I("shDisplay"),n=this.I("shTopImg"),h=this.I("shTitle"),o=this.I("shNavBar"),t.style.width=s.style.width="",h.style.width=n.width-4+"px",l=o.offsetHeight?h.offsetHeight+o.offsetHeight:30,d=this.wHeight-7-l,this.FS?(n.width>this.wWidth-10&&(t.style.width=s.style.width=n.width+10+"px"),document.documentElement.style.overflowX=""):(window.scrollTo(0,this.Top),n.height>d&&(n.width=n.width*(d/n.height),n.height=d,g=1),n.width>this.wWidth-16&&(n.height=n.height*((this.wWidth-16)/n.width),n.width=this.wWidth-16,g=1),h.style.width=n.width-4+"px",o.style.bottom="0px"),r=this.Top+n.height+l+10,r>this.pgHeight&&(t.style.height=r+"px"),window.scrollTo(0,this.Top),(this.FS&&(n.height>d||n.width>this.wWidth)||g)&&(this.I("fullSize").style.display="inline"),a=.45*(d-n.height),u=a>3?Math.floor(a):3,s.style.top=this.Top+u+"px",o.style.bottom="0",e.style.visibility="visible"))},fixTags:function(t){var e=document.getElementsByTagName("select"),s=document.getElementsByTagName("object"),h=document.getElementsByTagName("embed");if(t)var n="visible";else var n="hidden";for(i=0;i<e.length;i++)e[i].style.visibility=n;for(i=0;i<s.length;i++)s[i].style.visibility=n;for(i=0;i<h.length;i++)h[i].style.visibility=n}};var shutterLinks={},shutterSets={};"function"==typeof shutterOnload&&(oldonload=window.onload,"function"!=typeof window.onload?window.onload=shutterOnload:window.onload=function(){shutterOnload(),oldonload&&oldonload()});
1
+ shutterReloaded={L10n:["Previous","Next","Close","Full Size","Fit to Screen","Image","of","Loading..."],imageCount:!0,textBtns:!1,shImgDir:nextgen_lightbox_settings.static_path.replace("/{placeholder}","")+"/shutter_reloaded/images/",I:function(t){return document.getElementById(t)},Init:function(t){var e,i,s,h,n,o,l,d,r,a;for(h=0;h<document.links.length;h++)e=document.links[h],".jpg"!=(s=-1==e.href.indexOf("?")?e.href.slice(-4).toLowerCase():e.href.substring(0,e.href.indexOf("?")).slice(-4).toLowerCase())&&".png"!=s&&".gif"!=s&&"jpeg"!=s||"sh"==t&&-1==e.className.toLowerCase().indexOf("shutter")||"lb"==t&&-1==e.rel.toLowerCase().indexOf("lightbox")||(-1!=e.className.toLowerCase().indexOf("shutterset")?n=-1!=e.className.indexOf(" ")?e.className.slice(0,e.className.indexOf(" ")):e.className:-1!=e.rel.toLowerCase().indexOf("lightbox[")?n=e.rel:(n=0,o=-1),n&&(shutterSets[n]||(shutterSets[n]=[]),o=shutterSets[n].push(h)),l=e.href.slice(e.href.lastIndexOf("/")+1),i=e.title&&e.title!=l?e.title:"",shutterLinks[h]={link:e.href,num:o,set:n,title:i},e.onclick=new Function('shutterReloaded.Make("'+h+'");return false;'));if(!this.textBtns)for(d=["close.gif","prev.gif","next.gif","resize1.gif","resize2.gif","loading.gif"],r=0;r<d.length;r++)a=new Image,a.src=this.shImgDir+d[r]},Make:function(t,e){var i,s,h,n,o,l,d,r,a,u,g,m,c,w="",f="",p="";this.Top||(void 0!==window.pageYOffset?this.Top=window.pageYOffset:this.Top=document.documentElement.scrollTop>0?document.documentElement.scrollTop:document.body.scrollTop),void 0===this.pgHeight&&(this.pgHeight=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight)),this.FS=!!e||null,this.resizing&&(this.resizing=null),window.onresize=new Function('shutterReloaded.Resize("'+t+'");'),document.documentElement.style.overflowX="hidden",this.VP||(this._viewPort(),this.VP=!0),(r=this.I("shShutter"))||(r=document.createElement("div"),r.setAttribute("id","shShutter"),document.getElementsByTagName("body")[0].appendChild(r),this.fixTags()),(d=this.I("shDisplay"))||(d=document.createElement("div"),d.setAttribute("id","shDisplay"),d.style.top=this.Top+"px",document.getElementsByTagName("body")[0].appendChild(d)),r.style.height=this.pgHeight+"px";var y=this.textBtns?" | ":"";shutterLinks[t].num>1&&(i=shutterSets[shutterLinks[t].set][shutterLinks[t].num-2],o=this.textBtns?this.L10n[0]:'<img src="'+this.shImgDir+'prev.gif" title="'+this.L10n[0]+'" />',w='<a href="#" onclick="shutterReloaded.Make('+i+');return false">'+o+"</a>"+y,h=new Image,h.src=shutterLinks[i].link),-1!=shutterLinks[t].num&&shutterLinks[t].num<shutterSets[shutterLinks[t].set].length&&(s=shutterSets[shutterLinks[t].set][shutterLinks[t].num],l=this.textBtns?this.L10n[1]:'<img src="'+this.shImgDir+'next.gif" title="'+this.L10n[1]+'" />',f='<a href="#" onclick="shutterReloaded.Make('+s+');return false">'+l+"</a>"+y,n=new Image,n.src=shutterLinks[s].link),g=this.textBtns?this.L10n[2]:'<img src="'+this.shImgDir+'close.gif" title="'+this.L10n[2]+'" />',u=shutterLinks[t].num>0&&this.imageCount?" "+this.L10n[5]+"&nbsp;"+shutterLinks[t].num+"&nbsp;"+this.L10n[6]+"&nbsp;"+shutterSets[shutterLinks[t].set].length:"",u&&this.textBtns&&(u+=" |"),this.FS?m=this.textBtns?this.L10n[4]:'<img src="'+this.shImgDir+'resize2.gif" title="'+this.L10n[4]+'" />':(m=this.textBtns?this.L10n[3]:'<img src="'+this.shImgDir+'resize1.gif" title="'+this.L10n[3]+'" />',p=",1"),c='<span id="fullSize"><a href="#" onclick="shutterReloaded.Make('+t+p+');return false">'+m+"</a>"+y+"</span>",(a=this.I("shNavBar"))||(a=document.createElement("div"),a.setAttribute("id","shNavBar"),document.getElementsByTagName("body")[0].appendChild(a)),a.innerHTML=y+w+'<a href="#" onclick="shutterReloaded.hideShutter();return false">'+g+"</a>"+y+c+f+u,d.innerHTML='<div id="shWrap"><img src="'+shutterLinks[t].link+'" id="shTopImg" onload="shutterReloaded.ShowImg();" onclick="shutterReloaded.hideShutter();" /><div id="shTitle">'+shutterLinks[t].title+"</div></div>",window.setTimeout(function(){shutterReloaded.loading()},2e3)},loading:function(){var t,e,i;(i=this.I("shWrap"))&&"visible"==i.style.visibility||(t=this.I("shShutter"))&&(this.I("shWaitBar")||(e=document.createElement("div"),e.setAttribute("id","shWaitBar"),e.style.top=this.Top+"px",e.innerHTML='<img src="'+this.shImgDir+'loading.gif" title="'+this.L10n[7]+'" />',t.appendChild(e)))},hideShutter:function(){var t,e,i;(t=this.I("shDisplay"))&&t.parentNode.removeChild(t),(e=this.I("shShutter"))&&e.parentNode.removeChild(e),(i=this.I("shNavBar"))&&i.parentNode.removeChild(i),this.fixTags(!0),window.scrollTo(0,this.Top),window.onresize=this.FS=this.Top=this.VP=null,document.documentElement.style.overflowX=""},Resize:function(t){if(!this.resizing&&this.I("shShutter")){var e=this.I("shWrap");e&&(e.style.visibility="hidden"),window.setTimeout(function(){shutterReloaded.resizing=null},500),window.setTimeout(new Function('shutterReloaded.VP = null;shutterReloaded.Make("'+t+'");'),100),this.resizing=!0}},_viewPort:function(){var t=window.innerHeight?window.innerHeight:0,e=document.body.clientHeight?document.body.clientHeight:0,i=document.documentElement?document.documentElement.clientHeight:0;t>0?(this.wHeight=t-e>1&&t-e<30?e:t,this.wHeight=this.wHeight-i>1&&this.wHeight-i<30?i:this.wHeight):this.wHeight=i>0?i:e;var s=document.documentElement?document.documentElement.clientWidth:0,h=window.innerWidth?window.innerWidth:document.body.clientWidth;this.wWidth=s>1?s:h},ShowImg:function(){var t,e,i,s,h,n,o,l,d,r,a,u,g=0;(t=this.I("shShutter"))&&((e=this.I("shWrap"))&&"visible"==e.style.visibility||((i=this.I("shWaitBar"))&&i.parentNode.removeChild(i),s=this.I("shDisplay"),n=this.I("shTopImg"),h=this.I("shTitle"),o=this.I("shNavBar"),t.style.width=s.style.width="",h.style.width=n.width-4+"px",l=o.offsetHeight?h.offsetHeight+o.offsetHeight:30,d=this.wHeight-7-l,this.FS?(n.width>this.wWidth-10&&(t.style.width=s.style.width=n.width+10+"px"),document.documentElement.style.overflowX=""):(window.scrollTo(0,this.Top),n.height>d&&(n.width=n.width*(d/n.height),n.height=d,g=1),n.width>this.wWidth-16&&(n.height=n.height*((this.wWidth-16)/n.width),n.width=this.wWidth-16,g=1),h.style.width=n.width-4+"px",o.style.bottom="0px"),r=this.Top+n.height+l+10,r>this.pgHeight&&(t.style.height=r+"px"),window.scrollTo(0,this.Top),(this.FS&&(n.height>d||n.width>this.wWidth)||g)&&(this.I("fullSize").style.display="inline"),a=.45*(d-n.height),u=a>3?Math.floor(a):3,s.style.top=this.Top+u+"px",o.style.bottom="0",e.style.visibility="visible"))},fixTags:function(t){var e=document.getElementsByTagName("select"),s=document.getElementsByTagName("object"),h=document.getElementsByTagName("embed");if(t)var n="visible";else var n="hidden";for(i=0;i<e.length;i++)e[i].style.visibility=n;for(i=0;i<s.length;i++)s[i].style.visibility=n;for(i=0;i<h.length;i++)h[i].style.visibility=n}};var shutterLinks={},shutterSets={};"function"==typeof shutterOnload&&(oldonload=window.onload,"function"!=typeof window.onload?window.onload=shutterOnload:window.onload=function(){shutterOnload(),oldonload&&oldonload()});
products/photocrati_nextgen/modules/mvc/package.module.mvc.php CHANGED
@@ -524,28 +524,28 @@ class Mixin_Mvc_View_Instance_Methods extends Mixin
524
  }
525
  return $retval;
526
  }
527
- function get_template_override_dir($module = NULL)
528
  {
529
- $fs = C_Fs::get_instance();
530
- $dir = $fs->join_paths(WP_CONTENT_DIR, 'ngg');
531
- if (!@file_exists($dir)) {
532
- wp_mkdir_p($dir);
533
  }
534
- $dir = $fs->join_paths($dir, 'modules');
535
- if (!@file_exists($dir)) {
536
- wp_mkdir_p($dir);
537
  }
538
- if ($module) {
539
- $dir = $fs->join_paths($dir, $module);
540
- if (!@file_exists($dir)) {
541
- wp_mkdir_p($dir);
542
  }
543
- $dir = $fs->join_paths($dir, 'templates');
544
- if (!@file_exists($dir)) {
545
- wp_mkdir_p($dir);
546
  }
 
547
  }
548
- return $dir;
549
  }
550
  function get_template_override_abspath($module, $filename)
551
  {
524
  }
525
  return $retval;
526
  }
527
+ function get_template_override_dir($module_id = NULL)
528
  {
529
+ $root = trailingslashit(path_join(WP_CONTENT_DIR, 'ngg'));
530
+ if (!@file_exists($root) && is_writable(trailingslashit(WP_CONTENT_DIR))) {
531
+ wp_mkdir_p($root);
 
532
  }
533
+ $modules = trailingslashit(path_join($root, 'modules'));
534
+ if (!@file_exists($modules) && is_writable($root)) {
535
+ wp_mkdir_p($modules);
536
  }
537
+ if ($module_id) {
538
+ $module_dir = trailingslashit(path_join($modules, $module_id));
539
+ if (!@file_exists($module_dir) && is_writable($modules)) {
540
+ wp_mkdir_p($module_dir);
541
  }
542
+ $template_dir = trailingslashit(path_join($module_dir, 'templates'));
543
+ if (!@file_exists($template_dir) && is_writable($module_dir)) {
544
+ wp_mkdir_p($template_dir);
545
  }
546
+ return $template_dir;
547
  }
548
+ return $modules;
549
  }
550
  function get_template_override_abspath($module, $filename)
551
  {
products/photocrati_nextgen/modules/nextgen_addgallery_page/templates/upload_images.php CHANGED
@@ -115,7 +115,15 @@
115
  });
116
 
117
  // Change the text for the dragdrop
118
- $('.plupload_droptext').html("<?php _e('Drag image and ZIP files here or click <strong>Add Files</strong>', 'nggallery'); ?>");
 
 
 
 
 
 
 
 
119
 
120
  // Move the buttons
121
  var buttons = $('.plupload_buttons').detach();
115
  });
116
 
117
  // Change the text for the dragdrop
118
+ <?php
119
+ $settings = C_NextGen_Settings::get_instance();
120
+ $display_zips = (!is_multisite() || (is_multisite() && $settings->get('wpmuZipUpload')));
121
+ if ($display_zips)
122
+ $message = __('Drag image and ZIP files here or click <strong>Add Files</strong>', 'nggallery');
123
+ else
124
+ $message = __('Drag image files here or click <strong>Add Files</strong>', 'nggallery');
125
+ ?>
126
+ $('.plupload_droptext').html("<?php print $message; ?>");
127
 
128
  // Move the buttons
129
  var buttons = $('.plupload_buttons').detach();
products/photocrati_nextgen/modules/nextgen_admin/package.module.nextgen_admin.php CHANGED
@@ -1003,10 +1003,10 @@ class Mixin_NextGen_Admin_Page_Instance_Methods extends Mixin
1003
  // Experiment
1004
  $currentDate = date('Y-m-d');
1005
  $currentDate = date('Y-m-d', strtotime($currentDate));
1006
- $bf_sale_start = date('Y-m-d', strtotime("11/26/2019"));
1007
- $bf_sale_end = date('Y-m-d', strtotime("11/30/2019"));
1008
  if ($currentDate >= $bf_sale_start && $currentDate <= $bf_sale_end) {
1009
- $message = '<p class="ngg-header-promo black-friday"><span>' . __('Black Friday Sale!') . '</span><br>' . __('40% Off NextGEN Pro!') . '<a href="https://www.imagely.com/wordpress-gallery-plugin/nextgen-pro/?utm_source=ngg&utm_medium=ngguser&utm_campaign=ngpro" class="button-primary" target="_blank">' . __('Upgrade to NextGEN Pro') . '</a></p>';
1010
  } else {
1011
  $message = '<p class="ngg-header-promo">' . __('Tip: Want more beautiful galleries, a stunning lightbox, image social sharing, ecommerce, PRO support, and more?') . '<a href="https://www.imagely.com/wordpress-gallery-plugin/nextgen-pro/?utm_source=ngg&utm_medium=ngguser&utm_campaign=ngpro" class="button-primary" target="_blank">' . __('Upgrade to NextGEN Pro') . '</a></p>';
1012
  }
1003
  // Experiment
1004
  $currentDate = date('Y-m-d');
1005
  $currentDate = date('Y-m-d', strtotime($currentDate));
1006
+ $bf_sale_start = date('Y-m-d', strtotime("12/02/2019"));
1007
+ $bf_sale_end = date('Y-m-d', strtotime("12/05/2019"));
1008
  if ($currentDate >= $bf_sale_start && $currentDate <= $bf_sale_end) {
1009
+ $message = '<p class="ngg-header-promo black-friday"><span>' . __('Cyber Monday Sale!') . '</span><br>' . __('40% Off NextGEN Pro!') . '<a href="https://www.imagely.com/wordpress-gallery-plugin/nextgen-pro/?utm_source=ngg&utm_medium=ngguser&utm_campaign=ngpro" class="button-primary" target="_blank">' . __('Upgrade to NextGEN Pro') . '</a></p>';
1010
  } else {
1011
  $message = '<p class="ngg-header-promo">' . __('Tip: Want more beautiful galleries, a stunning lightbox, image social sharing, ecommerce, PRO support, and more?') . '<a href="https://www.imagely.com/wordpress-gallery-plugin/nextgen-pro/?utm_source=ngg&utm_medium=ngguser&utm_campaign=ngpro" class="button-primary" target="_blank">' . __('Upgrade to NextGEN Pro') . '</a></p>';
1012
  }
products/photocrati_nextgen/modules/nextgen_basic_album/package.module.nextgen_basic_album.php CHANGED
@@ -441,6 +441,10 @@ class A_NextGen_Basic_Album_Controller extends Mixin_NextGen_Basic_Pagination
441
  // the user passed in a gallery id instead
442
  $mapper = C_Gallery_Mapper::get_instance();
443
  $tmp = $mapper->select()->where(array('slug = %s', $gallery))->limit(1)->run_query();
 
 
 
 
444
  $result = reset($tmp);
445
  unset($tmp);
446
  if ($result) {
441
  // the user passed in a gallery id instead
442
  $mapper = C_Gallery_Mapper::get_instance();
443
  $tmp = $mapper->select()->where(array('slug = %s', $gallery))->limit(1)->run_query();
444
+ // NextGen turns "This & That" into "this-&amp;-that" when assigning gallery slugs
445
+ if (empty($tmp) && strpos($gallery, '&') !== FALSE) {
446
+ $tmp = $mapper->select()->where(array('slug = %s', str_replace('&', '&amp;', $gallery)))->limit(1)->run_query();
447
+ }
448
  $result = reset($tmp);
449
  unset($tmp);
450
  if ($result) {
products/photocrati_nextgen/modules/nextgen_basic_gallery/package.module.nextgen_basic_gallery.php CHANGED
@@ -241,8 +241,8 @@ class A_NextGen_Basic_Slideshow_Controller extends Mixin
241
  $storage = C_Gallery_Storage::get_instance();
242
  // Create parameter list for the view
243
  $params = $displayed_gallery->display_settings;
244
- $params['storage'] =& $storage;
245
- $params['images'] =& $images;
246
  $params['displayed_gallery_id'] = $displayed_gallery->id();
247
  $params['current_page'] = $current_page;
248
  $params['effect_code'] = $this->object->get_effect_code($displayed_gallery);
241
  $storage = C_Gallery_Storage::get_instance();
242
  // Create parameter list for the view
243
  $params = $displayed_gallery->display_settings;
244
+ $params['storage'] = $storage;
245
+ $params['images'] = $images;
246
  $params['displayed_gallery_id'] = $displayed_gallery->id();
247
  $params['current_page'] = $current_page;
248
  $params['effect_code'] = $this->object->get_effect_code($displayed_gallery);
products/photocrati_nextgen/modules/nextgen_basic_gallery/static/slideshow/ngg_basic_slideshow.js CHANGED
@@ -1,15 +1,10 @@
1
- (function($){
2
-
3
- $(document).ready(function(){
4
-
5
  $.each(window.galleries, function(index, gallery) {
6
-
7
  if (gallery.display_type === 'photocrati-nextgen_basic_slideshow') {
8
-
9
  var settings = gallery.display_settings;
10
  var fadeValue = (settings.transition_style == "fade") ? true : false;
11
-
12
- $('.ngg-galleryoverview.ngg-slideshow').slick({
13
  autoplay: Number(settings.autoplay) ? true : false,
14
  arrows: Number(settings.arrows) ? true : false,
15
  draggable: false,
@@ -19,11 +14,7 @@
19
  speed: settings.transition_speed,
20
  pauseOnHover: Number(settings.pauseonhover) ? true : false
21
  });
22
-
23
  }
24
-
25
  });
26
-
27
- });
28
-
29
  })(jQuery);
1
+ (function($) {
2
+ $(document).ready(function() {
 
 
3
  $.each(window.galleries, function(index, gallery) {
 
4
  if (gallery.display_type === 'photocrati-nextgen_basic_slideshow') {
 
5
  var settings = gallery.display_settings;
6
  var fadeValue = (settings.transition_style == "fade") ? true : false;
7
+ $('.ngg-galleryoverview.ngg-slideshow[data-gallery-id="' + gallery.ID + '"]').slick({
 
8
  autoplay: Number(settings.autoplay) ? true : false,
9
  arrows: Number(settings.arrows) ? true : false,
10
  draggable: false,
14
  speed: settings.transition_speed,
15
  pauseOnHover: Number(settings.pauseonhover) ? true : false
16
  });
 
17
  }
 
18
  });
19
+ });
 
 
20
  })(jQuery);
products/photocrati_nextgen/modules/nextgen_basic_gallery/static/slideshow/ngg_basic_slideshow.min.js CHANGED
@@ -1 +1 @@
1
- !function(e){e(document).ready(function(){e.each(window.galleries,function(a,o){if("photocrati-nextgen_basic_slideshow"===o.display_type){var s=o.display_settings,i="fade"==s.transition_style;e(".ngg-galleryoverview.ngg-slideshow").slick({autoplay:!!Number(s.autoplay),arrows:!!Number(s.arrows),draggable:!1,dots:!1,fade:i,autoplaySpeed:s.interval,speed:s.transition_speed,pauseOnHover:!!Number(s.pauseonhover)})}})})}(jQuery);
1
+ !function(e){e(document).ready(function(){e.each(window.galleries,function(a,i){if("photocrati-nextgen_basic_slideshow"===i.display_type){var o=i.display_settings,r="fade"==o.transition_style;e('.ngg-galleryoverview.ngg-slideshow[data-gallery-id="'+i.ID+'"]').slick({autoplay:!!Number(o.autoplay),arrows:!!Number(o.arrows),draggable:!1,dots:!1,fade:r,autoplaySpeed:o.interval,speed:o.transition_speed,pauseOnHover:!!Number(o.pauseonhover)})}})})}(jQuery);
products/photocrati_nextgen/modules/nextgen_basic_gallery/templates/slideshow/index.php CHANGED
@@ -1,49 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php $this->start_element('nextgen_gallery.gallery_container', 'container', $displayed_gallery); ?>
2
 
3
  <?php $this->include_template('photocrati-nextgen_gallery_display#container/before'); ?>
4
 
5
  <div class="ngg-galleryoverview ngg-slideshow"
6
  id="<?php echo esc_attr($anchor); ?>"
 
7
  style="max-width: <?php echo esc_attr($gallery_width); ?>px; max-height: <?php echo esc_attr($gallery_height); ?>px;">
8
 
9
- <?php for ($i = 0; $i < count($images); $i++) {
10
-
11
- $image = $images[$i];
12
- $image->style = 'style="height:' . esc_attr($gallery_height) . 'px"';
13
  $template_params = array(
14
  'index' => $i,
15
  'class' => 'ngg-gallery-slideshow-image'
16
  );
17
  $template_params = array_merge(get_defined_vars(), $template_params);
18
 
19
- $this->include_template('photocrati-nextgen_gallery_display#image/before', $template_params);
20
-
21
- ?>
22
-
23
- <a href="<?php echo esc_attr($storage->get_image_url($image)); ?>"
24
- title="<?php echo esc_attr($image->description); ?>"
25
- data-src="<?php echo esc_attr($storage->get_image_url($image)); ?>"
26
- data-thumbnail="<?php echo esc_attr($storage->get_image_url($image, 'thumb')); ?>"
27
- data-image-id="<?php echo esc_attr($image->{$image->id_field}); ?>"
28
- data-title="<?php echo esc_attr($image->alttext); ?>"
29
- data-description="<?php echo esc_attr(stripslashes($image->description)); ?>"
30
- <?php echo $effect_code ?>>
31
-
32
- <img data-image-id='<?php echo esc_attr($image->pid); ?>'
33
- title="<?php echo esc_attr($image->description)?>"
34
- alt="<?php echo esc_attr($image->alttext)?>"
35
- src="<?php echo esc_attr($storage->get_image_url($image, 'full', TRUE))?>"
36
- style="max-height: <?php echo esc_attr($gallery_height -20); ?>px;"
37
- />
38
-
39
- </a>
40
-
41
- <?php
42
-
43
- $this->include_template('photocrati-nextgen_gallery_display#image/after', $template_params);
44
 
 
 
45
  } ?>
46
-
47
  </div>
48
 
49
  <?php $this->include_template('photocrati-nextgen_gallery_display#container/after'); ?>
1
+ <?php
2
+ /**
3
+ * @var C_Displayed_Gallery $displayed_gallery
4
+ * @var C_Gallery_Storage $storage
5
+ * @var array $images
6
+ * @var bool $show_thumbnail_link
7
+ * @var int $aspect_ratio
8
+ * @var int $current_page
9
+ * @var int $gallery_height
10
+ * @var int $gallery_width
11
+ * @var string $anchor
12
+ * @var string $displayed_gallery_id
13
+ * @var string $effect_code
14
+ * @var string $placeholder
15
+ * @var string $thumbnail_link
16
+ * @var string $thumbnail_link_text
17
+ */ ?>
18
  <?php $this->start_element('nextgen_gallery.gallery_container', 'container', $displayed_gallery); ?>
19
 
20
  <?php $this->include_template('photocrati-nextgen_gallery_display#container/before'); ?>
21
 
22
  <div class="ngg-galleryoverview ngg-slideshow"
23
  id="<?php echo esc_attr($anchor); ?>"
24
+ data-gallery-id="<?php print esc_attr($displayed_gallery_id); ?>"
25
  style="max-width: <?php echo esc_attr($gallery_width); ?>px; max-height: <?php echo esc_attr($gallery_height); ?>px;">
26
 
27
+ <?php
28
+ for ($i = 0; $i < count($images); $i++) {
29
+ $image = $images[$i];
30
+ $image->style = 'style="height:' . esc_attr($gallery_height) . 'px"';
31
  $template_params = array(
32
  'index' => $i,
33
  'class' => 'ngg-gallery-slideshow-image'
34
  );
35
  $template_params = array_merge(get_defined_vars(), $template_params);
36
 
37
+ $this->include_template('photocrati-nextgen_gallery_display#image/before', $template_params);
38
+ ?>
39
+
40
+ <a href="<?php echo esc_attr($storage->get_image_url($image)); ?>"
41
+ title="<?php echo esc_attr($image->description); ?>"
42
+ data-src="<?php echo esc_attr($storage->get_image_url($image)); ?>"
43
+ data-thumbnail="<?php echo esc_attr($storage->get_image_url($image, 'thumb')); ?>"
44
+ data-image-id="<?php echo esc_attr($image->{$image->id_field}); ?>"
45
+ data-title="<?php echo esc_attr($image->alttext); ?>"
46
+ data-description="<?php echo esc_attr(stripslashes($image->description)); ?>"
47
+ <?php echo $effect_code ?>>
48
+
49
+ <img data-image-id='<?php echo esc_attr($image->pid); ?>'
50
+ title="<?php echo esc_attr($image->description); ?>"
51
+ alt="<?php echo esc_attr($image->alttext); ?>"
52
+ src="<?php echo esc_attr($storage->get_image_url($image, 'full')); ?>"
53
+ style="max-height: <?php echo esc_attr($gallery_height - 20); ?>px;"/>
54
+ </a>
 
 
 
 
 
 
 
55
 
56
+ <?php
57
+ $this->include_template('photocrati-nextgen_gallery_display#image/after', $template_params);
58
  } ?>
 
59
  </div>
60
 
61
  <?php $this->include_template('photocrati-nextgen_gallery_display#container/after'); ?>
products/photocrati_nextgen/modules/nextgen_data/package.module.nextgen_data.php CHANGED
@@ -671,9 +671,12 @@ class Mixin_NextGen_Gallery_Validation
671
  if (!$this->object->name) {
672
  $this->object->name = apply_filters('ngg_gallery_name', sanitize_file_name($sanitized_title));
673
  }
674
- // If no slug is set, use the title to generate one
675
- if (!$this->object->slug) {
676
- $this->object->slug = preg_replace('|[^a-z0-9 \\-~+_.#=!&;,/:%@$\\|*\'()\\x80-\\xff]|i', '', $sanitized_title);
 
 
 
677
  $this->object->slug = nggdb::get_unique_slug($this->object->slug, 'gallery');
678
  }
679
  }
@@ -863,10 +866,8 @@ class Mixin_Gallery_Mapper extends Mixin
863
  }
864
  $slug = $entity->slug;
865
  $entity->slug = str_replace(' ', '-', $entity->slug);
866
- // Note: we do the following to mimic the behaviour of esc_url so that slugs are always valid in URLs after escaping
867
- $entity->slug = preg_replace('|[^a-z0-9 \\-~+_.#=!&;,/:%@$\\|*\'()\\x80-\\xff]|i', '', $entity->slug);
868
  if ($slug != $entity->slug) {
869
- // creating new slug for the gallery
870
  $entity->slug = nggdb::get_unique_slug($entity->slug, 'gallery');
871
  }
872
  $retval = $this->call_parent('_save_entity', $entity);
671
  if (!$this->object->name) {
672
  $this->object->name = apply_filters('ngg_gallery_name', sanitize_file_name($sanitized_title));
673
  }
674
+ // Assign a slug; possibly updating the current slug if it was conceived by a method other than sanitize_title()
675
+ // NextGen 3.2.19 and older used a method adopted from esc_url() which would convert ampersands to "&amp;"
676
+ // and allow slashes in gallery slugs which breaks their ability to be linked to as children of albums
677
+ $sanitized_slug = sanitize_title($sanitized_title);
678
+ if (empty($this->object->slug) || $this->object->slug !== $sanitized_slug) {
679
+ $this->object->slug = $sanitized_slug;
680
  $this->object->slug = nggdb::get_unique_slug($this->object->slug, 'gallery');
681
  }
682
  }
866
  }
867
  $slug = $entity->slug;
868
  $entity->slug = str_replace(' ', '-', $entity->slug);
869
+ $entity->slug = sanitize_title($entity->slug);
 
870
  if ($slug != $entity->slug) {
 
871
  $entity->slug = nggdb::get_unique_slug($entity->slug, 'gallery');
872
  }
873
  $retval = $this->call_parent('_save_entity', $entity);
products/photocrati_nextgen/modules/nextgen_gallery_display/module.nextgen_gallery_display.php CHANGED
@@ -198,6 +198,10 @@ class M_Gallery_Display extends C_Base_Module
198
  if (defined('FONT_AWESOME_OFFICIAL_LOADED') && !is_admin())
199
  return;
200
 
 
 
 
 
201
  wp_register_script(
202
  'fontawesome_v4_shim',
203
  'https://use.fontawesome.com/releases/v5.3.1/js/v4-shims.js',
198
  if (defined('FONT_AWESOME_OFFICIAL_LOADED') && !is_admin())
199
  return;
200
 
201
+ $settings = C_NextGen_Settings::get_instance();
202
+ if ($settings->get('disable_fontawesome'))
203
+ return;
204
+
205
  wp_register_script(
206
  'fontawesome_v4_shim',
207
  'https://use.fontawesome.com/releases/v5.3.1/js/v4-shims.js',
products/photocrati_nextgen/modules/nextgen_other_options/package.module.nextgen_other_options.php CHANGED
@@ -329,7 +329,7 @@ class A_Miscellaneous_Form extends Mixin
329
  }
330
  function render()
331
  {
332
- return $this->object->render_partial('photocrati-nextgen_other_options#misc_tab', array('mediarss_activated' => C_NextGen_Settings::get_instance()->useMediaRSS, 'mediarss_activated_label' => __('Add MediaRSS link?', 'nggallery'), 'mediarss_activated_help' => __('When enabled, adds a MediaRSS link to your header. Third-party web services can use this to publish your galleries', 'nggallery'), 'mediarss_activated_no' => __('No'), 'mediarss_activated_yes' => __('Yes'), 'galleries_in_feeds' => C_NextGen_Settings::get_instance()->galleries_in_feeds, 'galleries_in_feeds_label' => __('Display galleries in feeds', 'nggallery'), 'galleries_in_feeds_help' => __('NextGEN hides its gallery displays in feeds other than MediaRSS. This enables image galleries in feeds.', 'nggallery'), 'galleries_in_feeds_no' => __('No'), 'galleries_in_feeds_yes' => __('Yes'), 'cache_label' => __('Clear image cache', 'nggallery'), 'cache_confirmation' => __("Completely clear the NextGEN cache of all image modifications?\n\nChoose [Cancel] to Stop, [OK] to proceed.", 'nggallery'), 'slug_field' => $this->_render_text_field((object) array('name' => 'misc_settings'), 'router_param_slug', __('Permalink slug', 'nggallery'), $this->object->get_model()->router_param_slug), 'maximum_entity_count_field' => $this->_render_number_field((object) array('name' => 'misc_settings'), 'maximum_entity_count', __('Maximum image count', 'nggallery'), $this->object->get_model()->maximum_entity_count, __('This is the maximum limit of images that NextGEN will restrict itself to querying', 'nggallery') . " \n " . __('Note: This limit will not apply to slideshow widgets or random galleries if/when those galleries specify their own image limits', 'nggallery'), FALSE, '', 1), 'random_widget_cache_ttl_field' => $this->_render_number_field((object) array('name' => 'misc_settings'), 'random_widget_cache_ttl', __('Random widget cache duration', 'nggallery'), $this->object->get_model()->random_widget_cache_ttl, __('The duration of time (in minutes) that "random" widget galleries should be cached. A setting of zero will disable caching.', 'nggallery'), FALSE, '', 0), 'alternate_random_method_field' => $this->_render_radio_field((object) array('name' => 'misc_settings'), 'use_alternate_random_method', __('Use alternative method of retrieving random image galleries', 'nggallery'), C_NextGen_Settings::get_instance()->use_alternate_random_method, __("Some web hosts' database servers disable or disrupt queries using 'ORDER BY RAND()' which can cause galleries to lose their randomness. NextGen provides an alternative (but not completely random) method to determine what images are fed into 'random' galleries.", 'nggallery'))), TRUE);
333
  }
334
  function cache_action()
335
  {
329
  }
330
  function render()
331
  {
332
+ return $this->object->render_partial('photocrati-nextgen_other_options#misc_tab', array('mediarss_activated' => C_NextGen_Settings::get_instance()->useMediaRSS, 'mediarss_activated_label' => __('Add MediaRSS link?', 'nggallery'), 'mediarss_activated_help' => __('When enabled, adds a MediaRSS link to your header. Third-party web services can use this to publish your galleries', 'nggallery'), 'mediarss_activated_no' => __('No'), 'mediarss_activated_yes' => __('Yes'), 'galleries_in_feeds' => C_NextGen_Settings::get_instance()->galleries_in_feeds, 'galleries_in_feeds_label' => __('Display galleries in feeds', 'nggallery'), 'galleries_in_feeds_help' => __('NextGEN hides its gallery displays in feeds other than MediaRSS. This enables image galleries in feeds.', 'nggallery'), 'galleries_in_feeds_no' => __('No'), 'galleries_in_feeds_yes' => __('Yes'), 'cache_label' => __('Clear image cache', 'nggallery'), 'cache_confirmation' => __("Completely clear the NextGEN cache of all image modifications?\n\nChoose [Cancel] to Stop, [OK] to proceed.", 'nggallery'), 'slug_field' => $this->_render_text_field((object) array('name' => 'misc_settings'), 'router_param_slug', __('Permalink slug', 'nggallery'), $this->object->get_model()->router_param_slug), 'maximum_entity_count_field' => $this->_render_number_field((object) array('name' => 'misc_settings'), 'maximum_entity_count', __('Maximum image count', 'nggallery'), $this->object->get_model()->maximum_entity_count, __('This is the maximum limit of images that NextGEN will restrict itself to querying', 'nggallery') . " \n " . __('Note: This limit will not apply to slideshow widgets or random galleries if/when those galleries specify their own image limits', 'nggallery'), FALSE, '', 1), 'random_widget_cache_ttl_field' => $this->_render_number_field((object) array('name' => 'misc_settings'), 'random_widget_cache_ttl', __('Random widget cache duration', 'nggallery'), $this->object->get_model()->random_widget_cache_ttl, __('The duration of time (in minutes) that "random" widget galleries should be cached. A setting of zero will disable caching.', 'nggallery'), FALSE, '', 0), 'alternate_random_method_field' => $this->_render_radio_field((object) array('name' => 'misc_settings'), 'use_alternate_random_method', __('Use alternative method of retrieving random image galleries', 'nggallery'), C_NextGen_Settings::get_instance()->use_alternate_random_method, __("Some web hosts' database servers disable or disrupt queries using 'ORDER BY RAND()' which can cause galleries to lose their randomness. NextGen provides an alternative (but not completely random) method to determine what images are fed into 'random' galleries.", 'nggallery')), 'alternate_random_method_field' => $this->_render_radio_field((object) array('name' => 'misc_settings'), 'use_alternate_random_method', __('Use alternative method of retrieving random image galleries', 'nggallery'), C_NextGen_Settings::get_instance()->use_alternate_random_method, __("Some web hosts' database servers disable or disrupt queries using 'ORDER BY RAND()' which can cause galleries to lose their randomness. NextGen provides an alternative (but not completely random) method to determine what images are fed into 'random' galleries.", 'nggallery')), 'disable_fontawesome_field' => $this->_render_radio_field((object) array('name' => 'misc_settings'), 'disable_fontawesome', __('Do not enqueue FontAwesome', 'nggallery'), C_NextGen_Settings::get_instance()->disable_fontawesome, __("Warning: your theme or another plugin must provide FontAwesome or your gallery displays may appear incorrectly", 'nggallery'))), TRUE);
333
  }
334
  function cache_action()
335
  {
products/photocrati_nextgen/modules/nextgen_other_options/templates/misc_tab.php CHANGED
@@ -85,4 +85,6 @@
85
  <?php print $random_widget_cache_ttl_field; ?>
86
 
87
  <?php print $alternate_random_method_field; ?>
 
 
88
  </table>
85
  <?php print $random_widget_cache_ttl_field; ?>
86
 
87
  <?php print $alternate_random_method_field; ?>
88
+
89
+ <?php print $disable_fontawesome_field; ?>
90
  </table>
products/photocrati_nextgen/modules/nextgen_pro_upgrade/module.nextgen_pro_upgrade.php CHANGED
@@ -21,7 +21,7 @@ class M_NextGen_Pro_Upgrade extends C_Base_Module
21
  'photocrati-nextgen_pro_upgrade',
22
  'NextGEN Pro Page',
23
  'NextGEN Gallery Pro Upgrade Page',
24
- '3.1.19',
25
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
26
  'Imagely',
27
  'https://www.imagely.com'
21
  'photocrati-nextgen_pro_upgrade',
22
  'NextGEN Pro Page',
23
  'NextGEN Gallery Pro Upgrade Page',
24
+ '3.2.23',
25
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
26
  'Imagely',
27
  'https://www.imagely.com'
products/photocrati_nextgen/modules/nextgen_settings/module.nextgen_settings.php CHANGED
@@ -18,7 +18,7 @@ class M_NextGen_Settings extends C_Base_Module
18
  'photocrati-nextgen_settings',
19
  'NextGEN Gallery Settings',
20
  'Provides central management for NextGEN Gallery settings',
21
- '3.1.8',
22
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
23
  'Imagely',
24
  'https://www.imagely.com'
@@ -133,6 +133,7 @@ class C_NextGen_Settings_Installer
133
  // Misc
134
  // It is known that WPEngine disables 'order by rand()' by default, but exposes it as an option to users
135
  'use_alternate_random_method' => (function_exists('is_wpe') && is_wpe()) ? TRUE : FALSE,
 
136
 
137
  // Duration of caching of 'random' widgets image IDs
138
  'random_widget_cache_ttl' => 30
18
  'photocrati-nextgen_settings',
19
  'NextGEN Gallery Settings',
20
  'Provides central management for NextGEN Gallery settings',
21
+ '3.1.9',
22
  'https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/',
23
  'Imagely',
24
  'https://www.imagely.com'
133
  // Misc
134
  // It is known that WPEngine disables 'order by rand()' by default, but exposes it as an option to users
135
  'use_alternate_random_method' => (function_exists('is_wpe') && is_wpe()) ? TRUE : FALSE,
136
+ 'disable_fontawesome' => FALSE,
137
 
138
  // Duration of caching of 'random' widgets image IDs
139
  'random_widget_cache_ttl' => 30
products/photocrati_nextgen/modules/ngglegacy/admin/manage-galleries.php CHANGED
@@ -293,8 +293,9 @@ function nggallery_manage_gallery_main() {
293
  <?php
294
  break;
295
  case 'author' :
 
296
  ?>
297
- <td <?php echo $attributes ?>><?php echo esc_html( $author_user->display_name ); ?></td>
298
  <?php
299
  break;
300
  case 'page_id' :
@@ -303,11 +304,10 @@ function nggallery_manage_gallery_main() {
303
  <?php
304
  break;
305
  case 'quantity' :
306
- $gallery->counter = count(
307
- $image_mapper->select($image_mapper->get_primary_key_column())->
308
- where(array("galleryid = %d", $gallery->{$gallery->id_field}))->
309
- run_query(FALSE, FALSE, TRUE)
310
- );
311
 
312
  ?>
313
  <td <?php echo $attributes ?>><?php echo $gallery->counter; ?></td>
293
  <?php
294
  break;
295
  case 'author' :
296
+ $author_string = $author_user === FALSE ? __('Deleted user', 'nggallery') : $author_user->display_name;
297
  ?>
298
+ <td <?php echo $attributes ?>><?php echo esc_html($author_string); ?></td>
299
  <?php
300
  break;
301
  case 'page_id' :
304
  <?php
305
  break;
306
  case 'quantity' :
307
+ global $wpdb;
308
+ $gallery->counter = $wpdb->get_var($wpdb->prepare(
309
+ "SELECT COUNT(*) FROM {$wpdb->nggpictures} WHERE galleryid = %d", $gallery->{$gallery->id_field}
310
+ ));
 
311
 
312
  ?>
313
  <td <?php echo $attributes ?>><?php echo $gallery->counter; ?></td>
products/photocrati_nextgen/modules/static_assets/module.static_assets.php CHANGED
@@ -101,26 +101,29 @@ class M_Static_Assets extends C_Base_Module
101
  */
102
  static function get_static_override_dir($module_id = NULL)
103
  {
104
- $dir = path_join(WP_CONTENT_DIR, 'ngg');
105
- if (!@file_exists($dir))
106
- wp_mkdir_p($dir);
107
 
108
- $dir = path_join($dir, 'modules');
109
- if (!@file_exists($dir))
110
- wp_mkdir_p($dir);
 
111
 
112
  if ($module_id)
113
  {
114
- $dir = path_join($dir, $module_id);
115
- if (!@file_exists($dir))
116
- wp_mkdir_p($dir);
 
 
 
 
117
 
118
- $dir = path_join($dir, 'static');
119
- if (!@file_exists($dir))
120
- wp_mkdir_p($dir);
121
  }
122
 
123
- return $dir;
124
  }
125
  }
126
 
101
  */
102
  static function get_static_override_dir($module_id = NULL)
103
  {
104
+ $root = trailingslashit(path_join(WP_CONTENT_DIR, 'ngg'));
105
+ if (!@file_exists($root) && is_writable(trailingslashit(WP_CONTENT_DIR)))
106
+ wp_mkdir_p($root);
107
 
108
+ $modules = trailingslashit(path_join($root, 'modules'));
109
+
110
+ if (!@file_exists($modules) && is_writable($root))
111
+ wp_mkdir_p($modules);
112
 
113
  if ($module_id)
114
  {
115
+ $module_dir = trailingslashit(path_join($modules, $module_id));
116
+ if (!@file_exists($module_dir) && is_writable($modules))
117
+ wp_mkdir_p($module_dir);
118
+
119
+ $static_dir = trailingslashit(path_join($module_dir, 'static'));
120
+ if (!@file_exists($static_dir) && is_writable($module_dir))
121
+ wp_mkdir_p($static_dir);
122
 
123
+ return $static_dir;
 
 
124
  }
125
 
126
+ return $modules;
127
  }
128
  }
129
 
products/photocrati_nextgen/modules/widget/package.module.widget.php CHANGED
@@ -292,7 +292,7 @@ class C_Widget_Slideshow extends WP_Widget
292
  {
293
  $router = C_Router::get_instance();
294
  wp_enqueue_style('nextgen_widgets_style', $router->get_static_url('photocrati-widget#widgets.css'), array(), NGG_SCRIPT_VERSION);
295
- wp_enqueue_style('nextgen_basic_slideshow_style', $router->get_static_url('photocrati-nextgen_basic_gallery#slideshow/nextgen_basic_slideshow.css'), array(), NGG_SCRIPT_VERSION);
296
  // these are handled by extract() but I want to silence my IDE warnings that these vars don't exist
297
  $before_widget = NULL;
298
  $before_title = NULL;
292
  {
293
  $router = C_Router::get_instance();
294
  wp_enqueue_style('nextgen_widgets_style', $router->get_static_url('photocrati-widget#widgets.css'), array(), NGG_SCRIPT_VERSION);
295
+ wp_enqueue_style('nextgen_basic_slideshow_style', $router->get_static_url('photocrati-nextgen_basic_gallery#slideshow/ngg_basic_slideshow.css'), array(), NGG_SCRIPT_VERSION);
296
  // these are handled by extract() but I want to silence my IDE warnings that these vars don't exist
297
  $before_widget = NULL;
298
  $before_title = NULL;
products/photocrati_nextgen/modules/wpcli/include/ngg_wpcli.php ADDED
@@ -0,0 +1,566 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class C_NGG_WPCLI
4
+ {
5
+ }
6
+
7
+ class C_NGG_WPCLI_Cache
8
+ {
9
+ /**
10
+ * Flushes NextGen Gallery caches
11
+ * @param array $args
12
+ * @param array $assoc_args
13
+ * @synopsis [--expired]
14
+ */
15
+ function flush($args, $assoc_args)
16
+ {
17
+ $expired = !empty($assoc_args['expired']) ? TRUE : FALSE;
18
+ C_Photocrati_Transient_Manager::flush($expired);
19
+ WP_CLI::success('Flushed caches');
20
+ }
21
+ }
22
+
23
+ class C_NGG_WPCLI_Album
24
+ {
25
+ /**
26
+ * Create a new album
27
+ * @param array $args
28
+ * @param array $assoc_args
29
+ * @synopsis <album_name> [--description=<description>] --author=<user_login>
30
+ */
31
+ function create($args, $assoc_args)
32
+ {
33
+ $mapper = C_Album_Mapper::get_instance();
34
+ $user = get_user_by('login', $assoc_args['author']);
35
+ if (!$user)
36
+ WP_CLI::error("Unable to find user {$assoc_args['author']}");
37
+
38
+ $description = !empty($assoc_args['description']) ? $assoc_args['description'] : '';
39
+
40
+ $album = $mapper->create(array(
41
+ 'name' => $args[0],
42
+ 'albumdesc' => $description,
43
+ 'author' => $user->ID,
44
+ ));
45
+
46
+ if ($album && $album->save())
47
+ {
48
+ $album_id = $retval = $album->id();
49
+ WP_CLI::success("Created album with id #{$album_id}");
50
+ }
51
+ else {
52
+ WP_CLI::error("Unable to create album");
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Deletes the requested album
58
+ * @param $args
59
+ * @param $assoc_args
60
+ * @synopsis <album_id>
61
+ */
62
+ function delete($args, $assoc_args)
63
+ {
64
+ $mapper = C_Album_Mapper::get_instance();
65
+ $album = $mapper->find($args[0]);
66
+ if (!$album)
67
+ WP_CLI::error("Unable to find album {$args[0]}");
68
+
69
+ $mapper->destroy($album);
70
+ WP_CLI::success("Album with id #{$album->id} has been deleted");
71
+ }
72
+
73
+ /**
74
+ * Change album attributes
75
+ * @param $args
76
+ * @param $assoc_args
77
+ * @synopsis <album_id> [--description=<description>] [--name=<name>]
78
+ */
79
+ function edit($args, $assoc_args)
80
+ {
81
+ $mapper = C_Album_Mapper::get_instance();
82
+ $album = $mapper->find($args[0]);
83
+ if (!$album)
84
+ WP_CLI::error("Unable to find album {$args[0]}");
85
+
86
+ if (empty($assoc_args['description']) && empty($assoc_args['name']))
87
+ WP_CLI::error("You must provide a new description or title");
88
+
89
+ if (!empty($assoc_args['description']))
90
+ $album->albumdesc = $assoc_args['description'];
91
+ if (!empty($assoc_args['name']))
92
+ $album->name = $assoc_args['name'];
93
+
94
+ $mapper->save($album);
95
+ WP_CLI::success("Album with id #{$album->id} has been modified");
96
+ }
97
+
98
+ /**
99
+ * @param array $args
100
+ * @param array $assoc_args
101
+ * @subcommand list
102
+ */
103
+ function _list($args, $assoc_args)
104
+ {
105
+ $mapper = C_Album_Mapper::get_instance();
106
+ $display = array();
107
+ foreach ($mapper->find_all() as $album) {
108
+ $display[] = array(
109
+ 'id' => $album->id,
110
+ 'name' => $album->name,
111
+ '# of children' => count($album->sortorder),
112
+ 'description' => $album->albumdesc
113
+ );
114
+ }
115
+
116
+ \WP_CLI\Utils\format_items('table', $display, array('id', 'name', '# of children', 'description'));
117
+ }
118
+
119
+ /**
120
+ * Adds child galleries or albums to an album
121
+ * @param $args
122
+ * @param $assoc_args
123
+ * @synopsis <album_id> [--galleries=<galleries>] [--albums=<albums>]
124
+ */
125
+ function add_children($args, $assoc_args)
126
+ {
127
+ $album_mapper = C_Album_Mapper::get_instance();
128
+ $album = $album_mapper->find($args[0]);
129
+ if (!$album)
130
+ WP_CLI::error("Unable to find album {$args[0]}");
131
+
132
+ if (empty($assoc_args['galleries']) && empty($assoc_args['albums']))
133
+ WP_CLI::error("You must provide new child galleries or albums");
134
+
135
+ if (!empty($assoc_args['galleries']))
136
+ {
137
+ $new = explode(',', $assoc_args['galleries']);
138
+ $gallery_mapper = C_Gallery_Mapper::get_instance();
139
+ foreach ($new as $gallery_id) {
140
+ $gallery = $gallery_mapper->find($gallery_id);
141
+ if (!$gallery)
142
+ WP_CLI::error("Unable to find gallery {$gallery_id}");
143
+ if (in_array($gallery_id, $album->sortorder))
144
+ WP_CLI::error("Gallery with id {$gallery_id} already belongs to this album");
145
+ $album->sortorder[] = $gallery_id;
146
+ }
147
+ }
148
+
149
+ if (!empty($assoc_args['albums']))
150
+ {
151
+ $new = explode(',', $assoc_args['albums']);
152
+ foreach ($new as $album_id) {
153
+ $new_album = $album_mapper->find($album_id);
154
+ if (!$new_album)
155
+ WP_CLI::error("Unable to find album {$album_id}");
156
+ if (in_array($album_id, $album->sortorder))
157
+ WP_CLI::error("Album with id {$album_id} already belongs to this album");
158
+ if ($album_id == $args[0])
159
+ WP_CLI::error("Cannot add an album to itself");
160
+ $album->sortorder[] = 'a' . $album_id;
161
+ }
162
+ }
163
+
164
+ $album_mapper->save($album);
165
+ WP_CLI::success("Album with id #{$album->id} has been modified");
166
+ }
167
+
168
+ /**
169
+ * Removes child galleries or albums attached to an album
170
+ * @param $args
171
+ * @param $assoc_args
172
+ * @synopsis <album_id> [--galleries=<galleries>] [--albums=<albums>]
173
+ */
174
+ function delete_children($args, $assoc_args)
175
+ {
176
+ $album_mapper = C_Album_Mapper::get_instance();
177
+ $parent_album = $album_mapper->find($args[0]);
178
+ if (!$parent_album)
179
+ WP_CLI::error("Unable to find album {$args[0]}");
180
+
181
+ if (empty($assoc_args['galleries']) && empty($assoc_args['albums']))
182
+ WP_CLI::error("You must provide a child gallery or album to remove");
183
+
184
+ $galleries = array();
185
+ $albums = array();
186
+
187
+ if (!empty($assoc_args['galleries']))
188
+ $galleries = explode(',', $assoc_args['galleries']);
189
+ if (!empty($assoc_args['albums']))
190
+ $albums = explode(',', $assoc_args['albums']);
191
+
192
+ foreach ($parent_album->sortorder as $ndx => $child) {
193
+ foreach ($galleries as $gallery) {
194
+ if ($gallery == $child)
195
+ unset($parent_album->sortorder[$ndx]);
196
+ }
197
+ foreach ($albums as $album) {
198
+ if ('a' . $album == $child)
199
+ unset($parent_album->sortorder[$ndx]);
200
+ }
201
+ }
202
+
203
+ $album_mapper->save($parent_album);
204
+ WP_CLI::success("Album with id #{$parent_album->id} has been modified");
205
+ }
206
+
207
+ /**
208
+ * Lists all child galleries and albums belonging to an album
209
+ * @param $args
210
+ * @param $assoc_args
211
+ * @synopsis <album_id>
212
+ */
213
+ function list_children($args, $assoc_args)
214
+ {
215
+ $album_mapper = C_Album_Mapper::get_instance();
216
+ $gallery_mapper = C_Gallery_Mapper::get_instance();
217
+
218
+ $album = $album_mapper->find($args[0]);
219
+ if (!$album)
220
+ WP_CLI::error("Unable to find album {$args[0]}");
221
+
222
+ $display = array();
223
+ foreach ($album->sortorder as $child) {
224
+ $is_album = (strpos($child, 'a') === 0) ? TRUE : FALSE;
225
+ if ($is_album)
226
+ {
227
+ $child = str_replace('a', '', $child);
228
+ $child_album = $album_mapper->find($child);
229
+ $display[] = array(
230
+ 'id' => $child_album->id,
231
+ 'type' => 'album',
232
+ 'title' => $child_album->name,
233
+ 'description' => $child_album->albumdesc
234
+ );
235
+ }
236
+ else {
237
+ $child_gallery = $gallery_mapper->find($child);
238
+ $display[] = array(
239
+ 'id' => $child_gallery->gid,
240
+ 'type' => 'gallery',
241
+ 'title' => $child_gallery->title,
242
+ 'description' => $child_gallery->galdesc
243
+ );
244
+ }
245
+
246
+ }
247
+
248
+ \WP_CLI\Utils\format_items('table', $display, array('id', 'type', 'title', 'description'));
249
+ }
250
+ }
251
+
252
+ class C_NGG_WPCLI_Gallery
253
+ {
254
+ /**
255
+ * Create a new gallery
256
+ * @param array $args
257
+ * @param array $assoc_args
258
+ * @synopsis <gallery_name> [--description=<description>] --author=<user_login>
259
+ */
260
+ function create($args, $assoc_args)
261
+ {
262
+ $mapper = C_Gallery_Mapper::get_instance();
263
+ $user = get_user_by('login', $assoc_args['author']);
264
+ if (!$user)
265
+ WP_CLI::error("Unable to find user {$assoc_args['author']}");
266
+
267
+ $description = !empty($assoc_args['description']) ? $assoc_args['description'] : '';
268
+
269
+ $gallery = $mapper->create(array(
270
+ 'title' => $args[0],
271
+ 'galdesc' => $description,
272
+ 'author' => $user->ID,
273
+ ));
274
+
275
+ if ($gallery && $gallery->save())
276
+ {
277
+ $gallery_id = $retval = $gallery->id();
278
+ WP_CLI::success("Created gallery with id #{$gallery_id}");
279
+ }
280
+ else {
281
+ WP_CLI::error("Unable to create gallery");
282
+ }
283
+ }
284
+
285
+ /**
286
+ * Deletes the requested gallery
287
+ * @param $args
288
+ * @param $assoc_args
289
+ * @synopsis <gallery_id> [--delete-files]
290
+ */
291
+ function delete($args, $assoc_args)
292
+ {
293
+ $mapper = C_Gallery_Mapper::get_instance();
294
+ $gallery = $mapper->find($args[0]);
295
+ if (!$gallery)
296
+ WP_CLI::error("Unable to find gallery {$args[0]}");
297
+
298
+ $remove_files = !empty($assoc_args['delete-files']) ? TRUE : FALSE;
299
+
300
+ $mapper->destroy($gallery, $remove_files);
301
+ WP_CLI::success("Gallery with id #{$gallery->gid} has been deleted");
302
+ }
303
+
304
+ /**
305
+ * Change gallery attributes
306
+ * @param $args
307
+ * @param $assoc_args
308
+ * @synopsis <gallery_id> [--description=<description>] [--title=<title>]
309
+ */
310
+ function edit($args, $assoc_args)
311
+ {
312
+ $mapper = C_Gallery_Mapper::get_instance();
313
+ $gallery = $mapper->find($args[0]);
314
+ if (!$gallery)
315
+ WP_CLI::error("Unable to find gallery {$args[0]}");
316
+
317
+ if (empty($assoc_args['description'] && empty($assoc_args['title'])))
318
+ WP_CLI::error("You must provide a new description or title");
319
+
320
+ if (!empty($assoc_args['description']))
321
+ $gallery->galdesc = $assoc_args['description'];
322
+ if (!empty($assoc_args['title']))
323
+ $gallery->name = $assoc_args['title'];
324
+
325
+ $mapper->save($gallery);
326
+ WP_CLI::success("Gallery with id #{$gallery->gid} has been modified");
327
+ }
328
+
329
+ /**
330
+ * @param array $args
331
+ * @param array $assoc_args
332
+ * @subcommand list
333
+ */
334
+ function _list($args, $assoc_args)
335
+ {
336
+ $mapper = C_Gallery_Mapper::get_instance();
337
+ $display = array();
338
+ foreach ($mapper->find_all() as $gallery) {
339
+ $display[] = array(
340
+ 'id' => $gallery->gid,
341
+ 'title' => $gallery->name,
342
+ 'path' => $gallery->path,
343
+ 'description' => $gallery->galdesc
344
+ );
345
+ }
346
+
347
+ \WP_CLI\Utils\format_items('table', $display, array('id', 'title', 'path', 'description'));
348
+ }
349
+
350
+ /**
351
+ * @param $args
352
+ * @param $assoc_args
353
+ * @synopsis <gallery_id>
354
+ */
355
+ function list_children($args, $assoc_args)
356
+ {
357
+ $gallery_mapper = C_Gallery_Mapper::get_instance();
358
+ $image_mapper = C_Image_Mapper::get_instance();
359
+
360
+ $gallery = $gallery_mapper->find($args[0]);
361
+ if (!$gallery)
362
+ WP_CLI::error("Unable to find gallery {$args[0]}");
363
+
364
+ $images = $image_mapper->select()->where(array('galleryid = %s', $gallery->gid))->run_query();
365
+ $display = array();
366
+
367
+ foreach ($images as $image) {
368
+ $display[] = array(
369
+ 'id' => $image->pid,
370
+ 'title' => $image->alttext,
371
+ 'excluded' => $image->exclude == 0 ? 'no' : 'yes',
372
+ 'sort order' => $image->sortorder,
373
+ 'description' => $image->description
374
+ );
375
+ }
376
+
377
+ \WP_CLI\Utils\format_items('table', $display, array('id', 'title', 'excluded', 'sort order', 'description'));
378
+
379
+ }
380
+ }
381
+
382
+ class C_NGG_WPCLI_Image
383
+ {
384
+ /**
385
+ * Import an image from the filesystem into NextGen
386
+ * @param array $args
387
+ * @param array $assoc_args
388
+ * @synopsis --filename=<absolute-path> --gallery=<gallery-id>
389
+ */
390
+ function import($args, $assoc_args)
391
+ {
392
+ $mapper = C_Gallery_Mapper::get_instance();
393
+ $storage = C_Gallery_Storage::get_instance();
394
+
395
+ if (($gallery = $mapper->find($assoc_args['gallery'], TRUE)))
396
+ {
397
+ $file_data = @file_get_contents($assoc_args['filename']);
398
+ $file_name = M_I18n::mb_basename($assoc_args['filename']);
399
+
400
+ if (empty($file_data))
401
+ WP_CLI::error('Could not load file');
402
+
403
+
404
+ $image_id = $storage->upload_base64_image($gallery, $file_data, $file_name);
405
+
406
+ if (!$image_id)
407
+ WP_CLI::error('Could not import image');
408
+ else
409
+ WP_CLI::success("Imported image with id #{$image_id}");
410
+ }
411
+ else {
412
+ WP_CLI::error("Gallery not found (with id #{$assoc_args['gallery']}");
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Change image attributes
418
+ * @param $args
419
+ * @param $assoc_args
420
+ * @synopsis <image_id> [--description=<description>] [--title=<title>]
421
+ */
422
+ function edit($args, $assoc_args)
423
+ {
424
+ $mapper = C_Image_Mapper::get_instance();
425
+ $image = $mapper->find($args[0]);
426
+ if (!$image)
427
+ WP_CLI::error("Unable to find image {$args[0]}");
428
+
429
+ if (empty($assoc_args['description']) && empty($assoc_args['title']))
430
+ WP_CLI::error("You must provide a new description or title");
431
+
432
+ if (!empty($assoc_args['description']))
433
+ $image->description = $assoc_args['description'];
434
+ if (!empty($assoc_args['title']))
435
+ $image->alttext = $assoc_args['title'];
436
+
437
+ $mapper->save($image);
438
+ WP_CLI::success("Image with id #{$image->pid} has been modified");
439
+ }
440
+ }
441
+
442
+ class C_NGG_WPCLI_Settings
443
+ {
444
+ /**
445
+ * @param array $args
446
+ * @param array $assoc_args
447
+ * @subcommand list
448
+ */
449
+ function _list($args, $assoc_args)
450
+ {
451
+ $settings = C_NextGen_Settings::get_instance();
452
+ $temporary = $settings->to_array();
453
+ $display = array();
454
+ foreach ($temporary as $key => $val) {
455
+ $display[] = array(
456
+ 'key' => $key,
457
+ 'value' => $val
458
+ );
459
+ }
460
+ \WP_CLI\Utils\format_items('table', $display, array('key', 'value'));
461
+ }
462
+
463
+ /**
464
+ * @param array $args
465
+ * @param array $assoc_args
466
+ * @synopsis <key> <value>
467
+ */
468
+ function edit($args, $assoc_args)
469
+ {
470
+ $settings = C_NextGen_Settings::get_instance();
471
+ $settings->set($args[0], $args[1]);
472
+ $settings->save();
473
+ WP_CLI::success("Setting has been updated");
474
+ }
475
+
476
+ /**
477
+ * Export all NextGen settings to a file in JSON format
478
+ * @param $args
479
+ * @param $assoc_args
480
+ * @synopsis <json-file-path>
481
+ */
482
+ function export($args, $assoc_args)
483
+ {
484
+ $settings = C_NextGen_Settings::get_instance();
485
+ file_put_contents($args[0], $settings->to_json());
486
+ WP_CLI::success("Settings have been stored in {$args[0]}");
487
+ }
488
+
489
+ /**
490
+ * Import settings from a JSON file
491
+ * @param array $args
492
+ * @param array $assoc_args
493
+ * @synopsis <json-file-path>
494
+ */
495
+ function import($args, $assoc_args)
496
+ {
497
+ $settings = C_NextGen_Settings::get_instance();
498
+ $file_content = file_get_contents($args[0]);
499
+ $json = json_decode($file_content);
500
+
501
+ if ($json === NULL)
502
+ WP_CLI::error("Could not parse JSON file");
503
+
504
+ foreach ($json as $key => $value) {
505
+ $settings->set($key, $value);
506
+ }
507
+
508
+ $settings->save();
509
+
510
+ WP_CLI::success("Settings have been imported from {$args[0]}");
511
+ }
512
+
513
+ /**
514
+ * Deactivates NextGen and NextGen Pro and resets all settings to their default state
515
+ * @param array $args
516
+ * @param array $assoc_args
517
+ */
518
+ function reset($args, $assoc_args)
519
+ {
520
+ WP_CLI::confirm("Are you sure you want to reset all NextGen settings?", $assoc_args);
521
+
522
+ $settings = C_NextGen_Settings::get_instance();
523
+ C_Photocrati_Transient_Manager::flush();
524
+
525
+ if (defined('NGG_PRO_PLUGIN_VERSION') || defined('NEXTGEN_GALLERY_PRO_VERSION'))
526
+ C_Photocrati_Installer::uninstall('photocrati-nextgen-pro');
527
+ if (defined('NGG_PLUS_PLUGIN_VERSION'))
528
+ C_Photocrati_Installer::uninstall('photocrati-nextgen-plus');
529
+ C_Photocrati_Installer::uninstall('photocrati-nextgen');
530
+
531
+ // removes all ngg_options entry in wp_options
532
+ $settings->reset();
533
+ $settings->destroy();
534
+
535
+ global $wpdb;
536
+ $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->posts} WHERE post_type = %s", 'display_type'));
537
+ $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->posts} WHERE post_type = %s", 'lightbox_library'));
538
+
539
+ WP_CLI::success("All NextGen settings have been reset");
540
+ }
541
+ }
542
+
543
+ class C_NGG_WPCLI_Notifications
544
+ {
545
+ /**
546
+ * Clear all dismissed notifications handled by C_Admin_Notification_Manager
547
+ * @param array $args
548
+ * @param array $assoc_args
549
+ * @synopsis
550
+ */
551
+ function clear_dismissed($args, $assoc_args)
552
+ {
553
+ $settings = C_NextGen_Settings::get_instance();
554
+ $settings->set('dismissed_notifications', array());
555
+ $settings->set('gallery_created_after_reviews_introduced', FALSE);
556
+ $settings->save();
557
+ }
558
+ }
559
+
560
+ WP_CLI::add_command('ngg', 'C_NGG_WPCLI');
561
+ WP_CLI::add_command('ngg album', 'C_NGG_WPCLI_Album');
562
+ WP_CLI::add_command('ngg cache', 'C_NGG_WPCLI_Cache');
563
+ WP_CLI::add_command('ngg gallery', 'C_NGG_WPCLI_Gallery');
564
+ WP_CLI::add_command('ngg image', 'C_NGG_WPCLI_Image');
565
+ WP_CLI::add_command('ngg notifications', 'C_NGG_WPCLI_Notifications');
566
+ WP_CLI::add_command('ngg settings', 'C_NGG_WPCLI_Settings');
products/photocrati_nextgen/modules/wpcli/module.wpcli.php CHANGED
@@ -35,92 +35,11 @@ class M_WPCLI extends C_Base_Module
35
 
36
  new M_WPCLI();
37
 
38
- if (defined('WP_CLI') && WP_CLI && class_exists('WP_CLI_Command', FALSE)) {
39
- /**
40
- * Manage NextGen Gallery
41
- */
42
- class C_NGG_WPCLI extends WP_CLI_Command
43
- {
44
- /**
45
- * Flushes NextGen Gallery caches
46
- * @param array $args
47
- * @param array $assoc_args
48
- */
49
- function flush_cache($args, $assoc_args)
50
- {
51
- C_Photocrati_Transient_Manager::flush();
52
- WP_CLI::success('Flushed all caches');
53
- }
54
-
55
- /**
56
- * Create a new gallery
57
- * @param array $args
58
- * @param array $assoc_args
59
- * @synopsis <gallery-name> --author=<user_login>
60
- */
61
- function create_gallery($args, $assoc_args)
62
- {
63
- $mapper = C_Gallery_Mapper::get_instance();
64
-
65
- $user = get_user_by('login', $assoc_args['author']);
66
- if (!$user)
67
- WP_CLI::error("Unable to find user {$assoc_args['author']}");
68
-
69
- if (($gallery = $mapper->create(array('title' => $args[0], 'author' => $user->ID))) && $gallery->save())
70
- {
71
- $gallery_id = $retval = $gallery->id();
72
- WP_CLI::success("Created gallery with id #{$gallery_id}");
73
- }
74
- else {
75
- WP_CLI::error("Unable to create gallery");
76
- }
77
- }
78
-
79
- /**
80
- * Import an image from the filesystem into NextGen
81
- * @param array $args
82
- * @param array $assoc_args
83
- * @synopsis --filename=<absolute-path> --gallery=<gallery-id>
84
- */
85
- function import_image($args, $assoc_args)
86
- {
87
- $mapper = C_Gallery_Mapper::get_instance();
88
- $storage = C_Gallery_Storage::get_instance();
89
-
90
- if (($gallery = $mapper->find($assoc_args['gallery'], TRUE)))
91
- {
92
- $file_data = @file_get_contents($assoc_args['filename']);
93
- $file_name = M_I18n::mb_basename($assoc_args['filename']);
94
-
95
- if (empty($file_data))
96
- WP_CLI::error('Could not load file');
97
-
98
- $image = $storage->upload_base64_image($gallery, $file_data, $file_name);
99
- $image_id = $image->{$image->id_field};
100
- if (!$image)
101
- WP_CLI::error('Could not import image');
102
- else
103
- WP_CLI::success("Imported image with id #{$image_id}");
104
- }
105
- else {
106
- WP_CLI::error("Gallery not found (with id #{$assoc_args['gallery']}");
107
- }
108
- }
109
-
110
- /**
111
- * Clear all dismissed notifications handled by C_Admin_Notification_Manager
112
- * @param array $args
113
- * @param array $assoc_args
114
- * @synopsis
115
- */
116
- function clear_dismissed_notifications($args, $assoc_args)
117
- {
118
- $settings = C_NextGen_Settings::get_instance();
119
- $settings->set('dismissed_notifications', array());
120
- $settings->set('gallery_created_after_reviews_introduced', FALSE);
121
- $settings->save();
122
- }
123
- }
124
-
125
- WP_CLI::add_command('ngg', 'C_NGG_WPCLI' );
126
  }
35
 
36
  new M_WPCLI();
37
 
38
+ // WP-CLI makes use of namespaces so we must restrict this to PHP 5.3+
39
+ if (defined('WP_CLI')
40
+ && WP_CLI
41
+ && class_exists('WP_CLI_Command', FALSE)
42
+ && version_compare(phpversion(), '5.3.0', '>'))
43
+ {
44
+ include_once('include/ngg_wpcli.php');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  }
readme.txt CHANGED
@@ -2,8 +2,9 @@
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.21
6
  Tested up to: 5.3.0
 
7
  License: GPLv2
8
 
9
  The most popular WordPress gallery plugin and one of the most popular plugins of all time with over 27 million downloads.
@@ -179,6 +180,20 @@ For more information, feel free to visit the official website for the NextGEN Ga
179
 
180
  == Changelog ==
181
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182
  = V3.2.21 - 11.20.2019 =
183
  * Changed: Small branding and color update
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.23
6
  Tested up to: 5.3.0
7
+ Requires PHP: 5.4
8
  License: GPLv2
9
 
10
  The most popular WordPress gallery plugin and one of the most popular plugins of all time with over 27 million downloads.
180
 
181
  == Changelog ==
182
 
183
+ = V3.2.23 - 12.02.2019 =
184
+ * NEW: There is a new setting under Other Options > Misc to disable enqueueing FontAwesome entirely
185
+ * Changed: WP-CLI commands have been namespaced and numerous new commands have been added
186
+ * Fixed: Add Gallery / Images page would instruct users to upload zip files even if the multisite settings disallowed it
187
+ * Fixed: Conflict with Elementor breaking the Attach-To-Post window styling
188
+ * Fixed: Corrected PHP warnings generated when creating the template & static override directory ('ngg') inside WP_CONTENT_DIR if write access isn't available
189
+ * Fixed: Gallery slug generation was broken when the gallery name included special characters and broke those galleries as album children
190
+ * Fixed: Improved performance on Manage Galleries page by simplifying query to count images belonging to galleries
191
+ * Fixed: Manage Galleries could generate a PHP warning when listing galleries created by users that have since been deleted
192
+ * Fixed: Shutter Reloaded's navigation icons were always missing
193
+ * Fixed: Slideshow widget was enqueueing a file that no exists
194
+ * Fixed: Two basic slideshow displays on one page would cause a JS error that broke their display
195
+ * Fixed: URL resolution for paginated galleries and dynamic thumbnails was broken if WordPress was in a sub-directory of a sub-directory install (split home & site url)
196
+
197
  = V3.2.21 - 11.20.2019 =
198
  * Changed: Small branding and color update
199