File Manager
<?php
/**
* Plugin Name: NextGEN Gallery
* Description: The most popular gallery plugin for WordPress and one of the most popular plugins of all time with over 30 million downloads.
* Version: 3.55
* Author: Imagely
* Plugin URI: https://www.imagely.com/wordpress-gallery-plugin/nextgen-gallery/
* Author URI: https://www.imagely.com
* License: GPLv3
* Text Domain: nggallery
* Domain Path: /static/I18N/
* Requires PHP: 7.0
*
* @package Nextgen Gallery
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use Imagely\NGG\Admin\AMNotifications;
use Imagely\NGG\Admin\About;
use Imagely\NGG\Admin\Ecommerce_Preview;
/**
* @deprecated
*/
class E_Clean_Exit extends RuntimeException {}
/**
* @deprecated
*/
class E_NggErrorException extends RuntimeException {}
/**
* Thrown when a datamapper entity does not exist
*
* @deprecated
*/
class E_EntityNotFoundException extends RuntimeException {}
/**
* @deprecated
*/
class E_ColumnsNotDefinedException extends RuntimeException {}
/**
* Thrown when an invalid data type is used as an entity, such as an associative array which is not supported.
*/
class E_InvalidEntityException extends RuntimeException {
public function __construct( $message = false, $code = 0 ) {
// If no message was provided, create a default message.
if ( ! $message ) {
$message = 'Invalid data type used for entity. Please use stdClass or a subclass of \Imagely\NGG\DataMapper\Model';
}
parent::__construct( $message, $code );
}
}
class E_UploadException extends RuntimeException {
public function __construct( $message = '', $code = 0, $previous = null ) {
if ( ! $message ) {
$message = 'There was a problem uploading the file.';
}
parent::__construct( $message, $code, $previous );
}
}
class E_InsufficientWriteAccessException extends RuntimeException {
public function __construct( $message = false, $filename = null, $code = 0, $previous = null ) {
if ( ! $message ) {
$message = 'Could not write to file. Please check filesystem permissions.';
}
if ( $filename ) {
$message .= " Filename: {$filename}";
}
parent::__construct( $message, $code, $previous );
}
}
class E_NoSpaceAvailableException extends RuntimeException {
public function __construct( $message = '', $code = 0, $previous = null ) {
if ( ! $message ) {
$message = 'You have exceeded your storage capacity. Please remove some files and try again.';
}
parent::__construct( $message, $code, $previous );
}
}
class E_No_Image_Library_Exception extends RuntimeException {
public function __construct( $message = '', $code = 0, $previous = null ) {
if ( ! $message ) {
$message = 'The site does not support the GD Image library. Please ask your hosting provider to enable it.';
}
parent::__construct( $message, $code, $previous );
}
}
/**
* Initializes all plugin hooks, actions, namespace autoloader, and defines constants.
*/
class C_NextGEN_Bootstrap {
protected static $pope_loaded = false;
public static $debug = false;
public $minimum_ngg_pro_version = '2.0.5';
public $minimum_ngg_plus_version = '1.0.1';
/**
* Holds Notifications Object
*/
public $notifications = null;
public function __construct() {
if ( defined( 'NGG_ENABLE_SHUTDOWN_EXCEPTION_HANDLER' ) && NGG_ENABLE_SHUTDOWN_EXCEPTION_HANDLER ) {
set_exception_handler( __CLASS__ . '::shutdown' );
}
// NextGEN Pro still throws E_Clean_Exit rather than calling exit(), which must be handled by the shutdown handler.
elseif ( self::get_pro_api_version() < 4.0 && ( ! defined( 'NGG_DISABLE_SHUTDOWN_EXCEPTION_HANDLER' ) || ! NGG_DISABLE_SHUTDOWN_EXCEPTION_HANDLER ) ) {
set_exception_handler( __CLASS__ . '::shutdown' );
}
spl_autoload_register( [ $this, 'autoloader' ] );
// Allow Composer dependencies to be found and loaded.
require_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor/autoload.php';
// If another plugin or theme with the POPE library (such as the legacy Photocrati theme) is active during.
// the NextGEN activation process, it may produce warnings that can stop this plugin from activating.
if ( ! $this->is_activating() && ! $this->is_topscorer_request() ) {
$this->define_constants();
$this->add_legacy_pro_compat();
$this->register_hooks();
include_once NGG_PLUGIN_DIR . '/src/Functions/deprecated.php';
include_once NGG_PLUGIN_DIR . '/src/Functions/admin.php';
include_once NGG_PLUGIN_DIR . '/src/Functions/compat.php';
// Legacy NGG 1x code was not namespaced and must be loaded manually before POPE.
include_once NGG_PLUGIN_DIR . '/src/Legacy/nggallery.php';
$this->notifications = new AMNotifications();
$this->notifications->hooks();
if ( is_admin() ) {
( new About() )->hooks();
( new Ecommerce_Preview() )->hooks();
}
$this->load_pope();
do_action( 'ngg_initialized' );
}
}
/**
* @deprecated This class will be removed if there's no complaints made after defaulting to the NGG_ENABLE_SHUTDOWN_EXCEPTION_HANDLER constant
* @param Exception $exception
*/
public static function shutdown( $exception = null ) {
if ( is_null( $exception ) ) {
$name = php_sapi_name();
if ( false === strpos( $name, 'cgi' )
&& version_compare( PHP_VERSION, '5.3.3' ) >= 0 ) {
$status = session_status();
if ( in_array( $status, [ PHP_SESSION_DISABLED, PHP_SESSION_NONE ], true ) ) {
session_write_close();
}
fastcgi_finish_request();
} else {
exit();
}
} elseif ( ! ( $exception instanceof E_Clean_Exit ) ) {
if ( ob_get_level() > 0 ) {
ob_end_clean();
}
self::print_exception( $exception );
}
}
public static function print_exception( $exception ) {
$klass = get_class( $exception );
echo "<h1>{$klass} thrown</h1>";
echo "<p>{$exception->getMessage()}</p>";
if ( self::$debug or ( defined( 'NGG_DEBUG' ) and NGG_DEBUG == true ) ) {
echo '<h3>Where:</h3>';
echo "<p>On line <strong>{$exception->getLine()}</strong> of <strong>{$exception->getFile()}</strong></p>";
echo '<h3>Trace:</h3>';
echo "<pre>{$exception->getTraceAsString()}</pre>";
if ( method_exists( $exception, 'getPrevious' ) ) {
if ( ( $previous = $exception->getPrevious() ) ) {
self::print_exception( $previous );
}
}
}
}
public function autoloader( $class ) {
$prefix = 'Imagely\\NGG\\';
$base_dir = __DIR__ . '/src/';
$len = strlen( $prefix );
if ( strncmp( $prefix, $class, $len ) !== 0 ) {
return;
}
$relative_class = substr( $class, $len );
$file = $base_dir . str_replace( '\\', DIRECTORY_SEPARATOR, $relative_class ) . '.php';
if ( file_exists( $file ) ) {
require $file;
}
}
public function is_topscorer_request() {
// Nonce verification is not necessary here: NextGEN skips loading certain components based on the URL in order
// to maintain compatibility with the Top Scorer plugin.
//
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
return strpos( $_SERVER['REQUEST_URI'], 'topscorer/v1' ) !== false;
}
public function is_activating(): bool {
// Nonce verification is not necessary here: NextGEN will not load various components if the current URL
// indicates that WordPress is in the process of activating a plugin.
//
// phpcs:disable WordPress.Security.NonceVerification.Recommended
$retval = strpos( $_SERVER['REQUEST_URI'], 'plugins.php' ) !== false && isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], [ 'activate-selected' ] );
if ( ! $retval && strpos( $_SERVER['REQUEST_URI'], 'update.php' ) !== false && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'install-plugin' && isset( $_REQUEST['plugin'] ) && strpos( $_REQUEST['plugin'], 'nextgen-gallery' ) === 0 ) {
$retval = true;
}
if ( ! $retval && strpos( $_SERVER['REQUEST_URI'], 'update.php' ) !== false && isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'activate-plugin' && isset( $_REQUEST['plugin'] ) && strpos( $_REQUEST['plugin'], 'nextgen-gallery' ) === 0 ) {
$retval = true;
}
return $retval;
// phpcs:enable WordPress.Security.NonceVerification.Recommended
}
/**
* These methods will be removed over time once the announcement of their deprecation has been made public. In
* order to allow third party code to remain compatible this is not being placed behind a compatibility level
* check.
*/
public function add_legacy_pro_compat() {
class_alias( '\Imagely\NGG\Admin\FormManager', 'C_Form_Manager' );
class_alias( '\Imagely\NGG\Admin\Notifications\Manager', 'C_Admin_Notification_Manager' );
class_alias( '\Imagely\NGG\Admin\RequirementsManager', 'C_Admin_Requirements_Manager' );
class_alias( '\Imagely\NGG\DataMappers\Album', 'C_Album_Mapper' );
class_alias( '\Imagely\NGG\DataMappers\Gallery', 'C_Gallery_Mapper' );
class_alias( '\Imagely\NGG\DataMappers\Image', 'C_Image_Mapper' );
class_alias( '\Imagely\NGG\DataStorage\MetaData', 'C_NextGen_Metadata' );
class_alias( '\Imagely\NGG\DataTypes\LegacyImage', 'C_Image_Wrapper' );
class_alias( '\Imagely\NGG\DataTypes\Lightbox', 'C_NGG_Lightbox' );
class_alias( '\Imagely\NGG\DisplayType\Installer', 'C_Display_Type_Installer' );
class_alias( '\Imagely\NGG\DisplayType\InstallerProxy', 'C_Gallery_Display_Installer' );
class_alias( '\Imagely\NGG\DisplayTypes\Taxonomy', 'C_Taxonomy_Controller' );
class_alias( '\Imagely\NGG\Display\I18N', 'M_I18N' );
class_alias( '\Imagely\NGG\Display\LightboxManager', 'C_Lightbox_Library_Manager' );
class_alias( '\Imagely\NGG\Display\Shortcodes', 'C_NextGen_Shortcode_Manager' );
class_alias( '\Imagely\NGG\DisplayedGallery\Renderer', 'C_Displayed_Gallery_Renderer' );
class_alias( '\Imagely\NGG\DisplayedGallery\TriggerManager', 'C_Displayed_Gallery_Trigger_Manager' );
class_alias( '\Imagely\NGG\DynamicStylesheets\Manager', 'C_Dynamic_Stylesheet_Controller' );
class_alias( '\Imagely\NGG\DynamicThumbnails\Manager', 'C_Dynamic_Thumbnails_Manager' );
class_alias( '\Imagely\NGG\IGW\ATPManager', 'M_Attach_To_Post' );
class_alias( '\Imagely\NGG\IGW\Controller', 'C_Attach_Controller' );
class_alias( '\Imagely\NGG\Settings\Settings', 'C_NextGen_Settings' );
class_alias( '\Imagely\NGG\Settings\Settings', 'C_Photocrati_Settings_Manager' );
class_alias( '\Imagely\NGG\Util\Filesystem', 'C_Fs' );
class_alias( '\Imagely\NGG\Util\Installer', 'C_Photocrati_Installer' );
class_alias( '\Imagely\NGG\Util\Router', 'C_Router' );
class_alias( '\Imagely\NGG\Util\RoutingApp', 'C_Routing_App' );
class_alias( '\Imagely\NGG\Util\Serializable', 'C_NextGen_Serializable' );
class_alias( '\Imagely\NGG\Util\Transient', 'C_Photocrati_Transient_Manager' );
}
public function fix_loading_order() {
// If a plugin wasn't activated/deactivated siliently, we can listen for these things.
if ( did_action( 'activate_plugin' ) || did_action( 'deactivate_plugin' ) ) {
return;
} elseif ( strpos( $_SERVER['REQUEST_URI'], 'plugins' ) !== false ) {
return;
} elseif ( ! $this->is_page_request() ) {
return;
}
$plugins = get_option( 'active_plugins' );
// Remove NGG from the list.
$ngg = basename( __DIR__ ) . '/' . basename( __FILE__ );
$order = [];
foreach ( $plugins as $plugin ) {
if ( $plugin != $ngg ) {
$order[] = $plugin;
}
}
// Get the position of either NGG Pro or NGG Plus.
$insert_at = false;
for ( $i = 0; $i < count( $order ); $i++ ) {
$plugin = $order[ $i ];
if ( strpos( $plugin, 'nggallery-pro' ) !== false ) {
$insert_at = $i + 1;
} elseif ( strpos( $plugin, 'ngg-plus' ) !== false ) {
$insert_at = $i + 1;
}
}
// Re-insert NGG after Pro or Plus.
if ( $insert_at === false || $insert_at === count( $order ) ) {
$order[] = $ngg;
} elseif ( $insert_at === 0 ) {
array_unshift( $order, $ngg );
} else {
array_splice( $order, $insert_at, 0, [ $ngg ] );
}
if ( $order != $plugins ) {
$order = array_filter( $order );
update_option( 'active_plugins', $order );
}
}
public static function get_legacy_module_directory( $module_id ) {
// POPE is not loaded; return the result from a manual mapping of id -> directory name.
$module_dir = null;
if ( $module_id === 'photocrati-attach_to_post' ) {
$module_dir = 'attach_to_post';
}
if ( $module_id === 'photocrati-cache' ) {
$module_dir = 'cache';
}
if ( $module_id === 'photocrati-dynamic_stylesheet' ) {
$module_dir = 'dynamic_stylesheet';
}
if ( $module_id === 'photocrati-dynamic_thumbnails' ) {
$module_dir = 'dynamic_thumbnails';
}
if ( $module_id === 'photocrati-frame_communication' ) {
$module_dir = 'frame_communication';
}
if ( $module_id === 'photocrati-fs' ) {
$module_dir = 'fs';
}
if ( $module_id === 'photocrati-i18n' ) {
$module_dir = 'i18n';
}
if ( $module_id === 'photocrati-lightbox' ) {
$module_dir = 'lightbox';
}
if ( $module_id === 'photocrati-nextgen-data' ) {
$module_dir = 'nextgen_data';
}
if ( $module_id === 'photocrati-nextgen-legacy' ) {
$module_dir = 'ngglegacy';
}
if ( $module_id === 'photocrati-nextgen_basic_gallery' ) {
$module_dir = 'nextgen_basic_gallery';
}
if ( $module_id === 'photocrati-nextgen_basic_thumbnails' ) {
$module_dir = 'nextgen_basic_gallery';
}
if ( $module_id === 'photocrati-nextgen_basic_slideshow' ) {
$module_dir = 'nextgen_basic_gallery';
}
if ( $module_id === 'photocrati-nextgen_basic_imagebrowser' ) {
$module_dir = 'nextgen_basic_imagebrowser';
}
if ( $module_id === 'photocrati-nextgen_basic_singlepic' ) {
$module_dir = 'nextgen_basic_singlepic';
}
if ( $module_id === 'photocrati-nextgen_basic_tagcloud' ) {
$module_dir = 'nextgen_basic_tagcloud';
}
if ( $module_id === 'photocrati-nextgen_basic_templates' ) {
$module_dir = 'nextgen_basic_templates';
}
if ( $module_id === 'photocrati-nextgen_block' ) {
$module_dir = 'nextgen_block';
}
if ( $module_id === 'photocrati-nextgen_gallery_display' ) {
$module_dir = 'nextgen_gallery_display';
}
if ( $module_id === 'photocrati-ajax' ) {
$module_dir = 'ajax';
}
if ( $module_dir ) {
return NGG_MODULE_DIR . DIRECTORY_SEPARATOR . $module_dir;
}
if ( defined( 'NGG_PRO_MODULES_DIR' ) ) {
// This is a bit of a hack, but it's easiest to just dump all of these here in one place.
// The following are all Starter/Plus/Pro modules.
if ( $module_id === 'photocrati-nextgen_pro_captions' ) {
$module_dir = 'nextgen_pro_captions';
}
if ( $module_id === 'photocrati-nextgen_pro_ecommerce' ) {
$module_dir = 'ecommerce';
}
if ( $module_id === 'photocrati-auto_update' ) {
$module_dir = 'autoupdate';
}
if ( $module_id === 'photocrati-auto_update-admin' ) {
$module_dir = 'autoupdate_admin';
}
if ( $module_id === 'imagely-braintree' ) {
$module_dir = 'braintree';
}
if ( $module_id === 'photocrati-cheque' ) {
$module_dir = 'cheque';
}
if ( $module_id === 'photocrati-comments' ) {
$module_dir = 'comments';
}
if ( $module_id === 'photocrati-coupons' ) {
$module_dir = 'coupons';
}
if ( $module_id === 'photocrati-free_gateway' ) {
$module_dir = 'free_gateway';
}
if ( $module_id === 'photocrati-galleria' ) {
$module_dir = 'galleria';
}
if ( $module_id === 'photocrati-image_protection' ) {
$module_dir = 'image_protection';
}
if ( $module_id === 'imagely-licensing' ) {
$module_dir = 'licensing';
}
if ( $module_id === 'photocrati-nextgen_pro_albums' ) {
$module_dir = 'nextgen_pro_albums';
}
if ( $module_id === 'photocrati-nextgen_pro_blog_gallery' ) {
$module_dir = 'nextgen_pro_blog_gallery';
}
if ( $module_id === 'photocrati-nextgen_pro_film' ) {
$module_dir = 'nextgen_pro_film';
}
if ( $module_id === 'photocrati-nextgen_pro_horizontal_filmstrip' ) {
$module_dir = 'nextgen_pro_horizontal_filmstrip';
}
if ( $module_id === 'photocrati-nextgen_pro_i18n' ) {
$module_dir = 'nextgen_pro_i18n';
}
if ( $module_id === 'photocrati-nextgen_pro_imagebrowser' ) {
$module_dir = 'nextgen_pro_imagebrowser';
}
if ( $module_id === 'photocrati-nextgen_pro_lightbox' ) {
$module_dir = 'nextgen_pro_lightbox';
}
if ( $module_id === 'photocrati-nextgen_pro_marketing' ) {
$module_dir = 'nextgen_pro_marketing';
}
if ( $module_id === 'photocrati-nextgen_pro_masonry' ) {
$module_dir = 'nextgen_pro_masonry';
}
if ( $module_id === 'photocrati-nextgen_pro_mosaic' ) {
$module_dir = 'nextgen_pro_mosaic';
}
if ( $module_id === 'photocrati-nextgen_pro_proofing' ) {
$module_dir = 'nextgen_pro_proofing';
}
if ( $module_id === 'photocrati-nextgen_pro_settings' ) {
$module_dir = 'nextgen_pro_settings';
}
if ( $module_id === 'photocrati-nextgen_pro_sidescroll' ) {
$module_dir = 'nextgen_pro_sidescroll';
}
if ( $module_id === 'photocrati-nextgen_pro_slideshow' ) {
$module_dir = 'nextgen_pro_slideshow';
}
if ( $module_id === 'photocrati-nextgen_pro_thumbnail_grid' ) {
$module_dir = 'nextgen_pro_thumbnail_grid';
}
if ( $module_id === 'photocrati-nextgen_pro_tile' ) {
$module_dir = 'nextgen_pro_tile';
}
if ( $module_id === 'photocrati-pro-wpcli' ) {
$module_dir = 'nextgen_pro_wpcli';
}
if ( $module_id === 'photocrati-paypal_checkout' ) {
$module_dir = 'paypal_checkout';
}
if ( $module_id === 'photocrati-paypal_express_checkout' ) {
$module_dir = 'paypal_express_checkout';
}
if ( $module_id === 'photocrati-paypal_standard' ) {
$module_dir = 'paypal_standard';
}
if ( $module_id === 'photocrati-nextgen_picturefill' ) {
$module_dir = 'picturefill';
}
if ( $module_id === 'imagely-pro-search' ) {
$module_dir = 'search';
}
if ( $module_id === 'photocrati-stripe' ) {
$module_dir = 'stripe';
}
if ( $module_id === 'photocrati-test_gateway' ) {
$module_dir = 'test_gateway';
}
if ( $module_dir ) {
return NGG_PRO_MODULES_DIR . DIRECTORY_SEPARATOR . $module_dir;
}
}
// The module was not in the list above, consult POPE if possible.
if ( self::$pope_loaded ) {
return \C_Component_Registry::get_instance()->get_module_dir( $module_id );
}
return $module_dir;
}
public function load_pope( $force = false ) {
// We allow POPE to load if the requested URL/POST includes photocrati_ajax as it is still used by a few NextGEN
// modules for XHR such as uploading images.
//
// Nonce verification is not necessary here.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( ! $force
&& empty( $_REQUEST['photocrati_ajax'] )
&& ( self::get_pro_api_version() >= 4.0 && ! is_admin() )
&& ! defined( 'EWWW_IMAGE_OPTIMIZER_VERSION' ) // EWWW uses I_Gallery_Storage.
&& ! defined( 'WP_SMUSH_VERSION' ) // WP_SMUSH_VERSION uses I_Gallery_Storage.
&& ! defined( 'IMAGIFY_VERSION' ) // Imagify adds their own mixin to C_Gallery_Storage.
|| self::$pope_loaded ) {
return;
}
// Pope requires a higher limit.
$tmp = ini_get( 'xdebug.max_nesting_level' );
if ( $tmp && (int) $tmp <= 300 ) {
@ini_set( 'xdebug.max_nesting_level', 300 );
}
// Enforce interfaces.
if ( property_exists( 'ExtensibleObject', 'enforce_interfaces' ) ) {
ExtensibleObject::$enforce_interfaces = EXTENSIBLE_OBJECT_ENFORCE_INTERFACES;
}
// Get the component registry.
$registry = C_Component_Registry::get_instance();
// Add the default Pope factory utility, C_Component_Factory.
$registry->add_utility( 'I_Component_Factory', 'C_Component_Factory' );
// Load embedded products. Each product is expected to load any modules required.
$registry->add_module_path( NGG_PRODUCT_DIR, 2 );
$registry->load_all_products();
// Give third-party plugins that opportunity to include their own products and modules.
do_action( 'load_nextgen_gallery_modules', $registry );
// Initializes all loaded modules.
$registry->initialize_all_modules();
self::$pope_loaded = true;
}
public function is_pro_compatible() {
$retval = true;
if ( defined( 'NEXTGEN_GALLERY_PRO_VERSION' ) ) {
$retval = false;
}
if ( defined( 'NEXTGEN_GALLERY_PRO_PLUGIN_BASENAME' ) && ! defined( 'NGG_PRO_PLUGIN_VERSION' ) ) {
$retval = false; // 1.0 - 1.0.6
}
if ( defined( 'NGG_PRO_PLUGIN_VERSION' ) && version_compare( NGG_PRO_PLUGIN_VERSION, $this->minimum_ngg_pro_version ) < 0 ) {
$retval = false;
}
if ( defined( 'NGG_PLUS_PLUGIN_VERSION' ) && version_compare( NGG_PLUS_PLUGIN_VERSION, $this->minimum_ngg_plus_version ) < 0 ) {
$retval = false;
}
return $retval;
}
public function render_incompatibility_warning() {
echo '<div class="updated error"><p>';
echo esc_html(
sprintf(
__(
'NextGEN Gallery %1$s is incompatible with this version of NextGEN Pro. Please update NextGEN Pro to version %2$s or higher to restore NextGEN Pro functionality.',
'nggallery'
),
NGG_PLUGIN_VERSION,
$this->minimum_ngg_pro_version
)
);
echo '</p></div>';
}
public function render_jquery_wp_55_warning() {
$render = false;
global $wp_version;
$message = '';
$account_msg = '';
if ( defined( 'NGG_PRO_PLUGIN_VERSION' ) && version_compare( NGG_PRO_PLUGIN_VERSION, '3.1' ) < 0 ) {
$render = true;
$message = __( 'Your version of NextGEN Pro is known to have some issues with NextGEN Gallery 3.4 and later.', 'nggallery' );
$account_msg = preg_match( '#photocrati#i', wp_get_theme()->get( 'Name' ) )
? sprintf( __( "Please download the latest version of NextGEN Pro from your <a href='%s' target='_blank'>account area</a>", 'nggallery' ), 'https://members.photocrati.com/account/' )
: sprintf( __( "Please download the latest version of NextGEN Pro from your <a href='%s' target='_blank'>account area</a>", 'nggallery' ), 'https://www.imagely.com/account/' );
}
if ( defined( 'NGG_PLUS_PLUGIN_VERSION' ) && version_compare( NGG_PLUS_PLUGIN_VERSION, '1.7' ) < 0 ) {
$render = true;
$message = __( 'Your version of NextGEN Plus is known to have some issues with NextGEN Gallery 3.4 and later.', 'nggallery' );
$account_msg = preg_match( '#photocrati#i', wp_get_theme()->get( 'Name' ) )
? sprintf( __( "Please download the latest version of NextGEN Plus from your <a href='%s' target='_blank'>account area</a>", 'nggallery' ), 'https://members.photocrati.com/account/' )
: sprintf( __( "Please download the latest version of NextGEN Plus from your <a href='%s' target='_blank'>account area</a>", 'nggallery' ), 'https://www.imagely.com/account/' );
}
if ( ! $render ) {
return;
}
print '<div class="updated error"><p>';
print $message;
print ' ';
print $account_msg;
if ( version_compare( $wp_version, '5.5', '>=' ) && version_compare( $wp_version, '5.5.9', '<=' ) ) {
$note = __( "NOTE: The autoupdater doesn't work on the version of WordPress you have installed.", 'ngallery' );
print "<div style='font-weight: bold;'>";
print $note;
print '</div>';
}
print '</p></div>';
}
public function register_hooks() {
// The core installers must be registered before the rest of the initialization is processed.
\Imagely\NGG\Util\Installer::add_handler( 'legacy-core', 'C_NGG_Legacy_Installer' );
\Imagely\NGG\Util\Installer::add_handler( 'settings', '\Imagely\NGG\Settings\Installer' );
\Imagely\NGG\Util\Installer::add_handler( 'pro_display_types', '\Imagely\NGG\DisplayType\Installer' );
// Register the (de)activation routines.
add_action( 'deactivate_' . NGG_PLUGIN_BASENAME, [ $this, 'deactivate' ] );
add_action( 'activate_' . NGG_PLUGIN_BASENAME, [ $this, 'activate' ], -10 );
// Handle activation redirect to overview page.
add_action( 'init', [ $this, 'handle_activation_redirect' ] );
// Ensure that settings manager is saved as an array.
add_filter( 'pre_update_option_ngg_options', [ $this, 'persist_settings' ] );
add_filter( 'pre_update_site_option_ngg_options', [ $this, 'persist_settings' ] );
// Delete displayed gallery transients periodically.
if ( NGG_CRON_ENABLED ) {
add_filter( 'cron_schedules', [ $this, 'add_ngg_schedule' ] );
add_action( 'ngg_delete_expired_transients', [ $this, 'delete_expired_transients' ] );
add_action( 'wp', [ $this, 'schedule_cron_jobs' ] );
}
// Start the plugin!
add_action( 'init', [ $this, 'update' ], ( PHP_INT_MAX - 2 ) );
add_action( 'init', [ $this, 'route' ], 5 );
// NGG extension plugins should be loaded in a specific order.
add_action( 'shutdown', [ $this, 'fix_loading_order' ] );
if ( ! $this->is_pro_compatible() ) {
add_action( 'all_admin_notices', [ $this, 'render_incompatibility_warning' ] );
}
add_action( 'admin_init', [ '\Imagely\NGG\Admin\RequirementsManager', 'register_requirements' ], -20 );
add_action( 'all_admin_notices', [ $this, 'render_jquery_wp_55_warning' ] );
// Necessary hack for the datamapper to order query results.
add_filter( 'posts_orderby', [ '\Imagely\NGG\DataStorage\Manager', 'wp_query_order_by' ], 10, 2 );
add_filter( 'init', [ '\Imagely\NGG\DataStorage\Manager', 'register_custom_post_types' ] );
add_action( 'rest_api_init', [ '\Imagely\NGG\REST\Manager', 'rest_api_init' ] );
// Widgets registration.
add_action(
'widgets_init',
function () {
register_widget( '\Imagely\NGG\Widget\Gallery' );
register_widget( '\Imagely\NGG\Widget\Slideshow' );
register_widget( '\Imagely\NGG\Widget\MediaRSS' );
}
);
add_action( 'wp_enqueue_scripts', [ \Imagely\NGG\Display\LightboxManager::get_instance(), 'maybe_enqueue' ] );
add_action(
'ngg_delete_image',
function () {
\Imagely\NGG\Util\Transient::flush( 'random_widget_gallery_ids' );
}
);
add_filter( 'xmlrpc_methods', [ '\Imagely\NGG\XMLRPC\Manager', 'add_methods' ] );
// Nonce verification is not necessary here: it is performed by the notification manager's serve_ajax_request() method.
// phpcs:disable WordPress.Security.NonceVerification.Recommended
add_action(
'init',
function () {
if ( isset( $_REQUEST['ngg_dismiss_notice'] ) ) {
// Admin notification handlers are registered in the nextgen_admin module.
$this->load_pope( true );
\Imagely\NGG\Admin\Notifications\Manager::get_instance()->serve_ajax_request();
}
}
);
// phpcs:enable WordPress.Security.NonceVerification.Recommended
// The following is a hack: we cannot move the Lightroom XHR requests to the REST API because the URL are coded
// into the lightroom plugin and have no autodiscovery. To avoid dependencies on the deprecated ajax POPE module
// we only add the 'init' hook here if the URL matches.
$lightroom_actions = [
'enqueue_nextgen_api_task_list',
'get_nextgen_api_path_list',
'execute_nextgen_api_task_list',
'get_nextgen_api_token',
];
// Nonce verification is not necessary here: authentication is handled by the Lightroom\Controller class.
//
// phpcs:disable WordPress.Security.NonceVerification.Recommended
if ( ! empty( $_REQUEST['photocrati_ajax'] )
&& ! empty( $_REQUEST['action'] )
&& '1' === (string) ( $_REQUEST['photocrati_ajax'] )
&& in_array( $_REQUEST['action'], $lightroom_actions, true ) ) {
add_action( 'init', [ '\Imagely\NGG\Lightroom\Controller', 'run' ], 0 );
}
// phpcs:enable WordPress.Security.NonceVerification.Recommended
if ( defined( 'WP_CLI' ) && WP_CLI ) {
\Imagely\NGG\WPCLI\Manager::register();
}
// This is necessary because NextGEN can insert singlepicture images as pre-rendered HTML without a shortcode.
// This requires we inspect the site content and enqueue the display type's CSS if necessary.
add_filter(
'the_content',
function ( $content ) {
if ( preg_match( '#<img.*ngg-singlepic.*>#', $content, $matches ) ) {
wp_enqueue_style(
'nextgen_basic_singlepic_style',
\Imagely\NGG\Display\StaticAssets::get_url(
'SinglePicture/nextgen_basic_singlepic.css',
'photocrati-nextgen_basic_singlepic#nextgen_basic_singlepic.css'
),
[],
NGG_SCRIPT_VERSION
);
}
return $content;
},
PHP_INT_MAX,
1
);
// Component registration.
\Imagely\NGG\DataMapper\Manager::register_hooks();
\Imagely\NGG\DisplayType\Manager::register();
\Imagely\NGG\Display\DisplayManager::register_hooks();
\Imagely\NGG\Display\I18N::get_instance()->register_hooks();
\Imagely\NGG\Display\ResourceManager::init();
\Imagely\NGG\Display\Shortcodes::get_instance()->register_hooks();
\Imagely\NGG\IGW\ATPManager::get_instance()->register_hooks();
\Imagely\NGG\IGW\BlockManager::get_instance()->register_hooks();
\Imagely\NGG\IGW\EventPublisher::get_instance()->register_hooks();
\Imagely\NGG\Util\Router::get_instance()->register_hooks();
\Imagely\NGG\Util\ThirdPartyCompatibility::get_instance()->register_hooks();
}
public function handle_activation_redirect() {
if ( get_transient( 'ngg-activated' ) ) {
delete_transient( 'ngg-activated' );
wp_redirect( admin_url( '?page=nextgen-gallery' ) );
}
}
public function schedule_cron_jobs() {
if ( ! wp_next_scheduled( 'ngg_delete_expired_transients' ) ) {
wp_schedule_event( time(), 'ngg_custom', 'ngg_delete_expired_transients' );
}
}
public function add_ngg_schedule( $schedules ) {
$schedules['ngg_custom'] = [
'interval' => NGG_CRON_SCHEDULE,
// Translators: %d - NGG_CRON_SCHEDULE constant -- do not translate.
'display' => sprintf( esc_html__( 'Every %d seconds', 'nggallery' ), NGG_CRON_SCHEDULE ),
];
return $schedules;
}
public function delete_expired_transients() {
\Imagely\NGG\Util\Transient::get_instance()->flush_expired();
}
/**
* Ensure that settings are persisted as an array
*
* @param Imagely\NGG\Settings\Settings|array $settings
* @return array
*/
public function persist_settings( $settings = [] ) {
if ( $settings instanceof \Imagely\NGG\Settings\ManagerBase ) {
$settings = $settings->to_array();
}
return $settings;
}
public function update() {
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
return;
}
// Nonce verification is not necessary here.
//
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( isset( $_REQUEST['doing_wp_cron'] ) ) {
return;
}
$this->load_pope();
\Imagely\NGG\Util\Installer::update();
}
public function route() {
$this->load_pope();
$router = \Imagely\NGG\Util\Router::get_instance();
// Set context to path if subdirectory install.
$parts = parse_url( $router->get_base_url( false ) );
$siteparts = parse_url( get_option( 'home' ) );
if ( isset( $parts['path'] ) && isset( $siteparts['path'] ) ) {
if ( strpos( $parts['path'], '/index.php' ) === false ) {
$router->context = $siteparts['path'];
} else {
$new_parts = explode( '/index.php', $parts['path'] );
if ( ! empty( $new_parts[0] ) && $new_parts[0] == $siteparts['path'] ) {
$router->context = array_shift( $new_parts );
}
}
}
$dynamic_thumbs_app = $router->create_app( '/nextgen-image' );
$dynamic_thumbs_app->rewrite( '/{*}', '/' );
$dynamic_thumbs_app->route(
[ '/' ],
[
'controller' => '\Imagely\NGG\DynamicThumbnails\Controller',
'action' => 'index_action',
]
);
$dynamic_styles_app = $router->create_app( '/nextgen-dcss' );
$dynamic_styles_app->rewrite( '/{\d}/{*}', '/index--{1}/data--{2}' );
$dynamic_styles_app->route(
[ '/' ],
[
'controller' => '\Imagely\NGG\DynamicStylesheets\Controller',
'action' => 'index_action',
]
);
$igw_app = $router->create_app( '/' . NGG_ATTACH_TO_POST_SLUG );
$igw_app->rewrite( '/preview/{id}', '/preview/id--{id}' );
$igw_app->rewrite( '/display_tab_js/{id}', '/display_tab_js/id--{id}' );
$igw_app->route(
[ '/' ],
[
'controller' => '\Imagely\NGG\IGW\Controller',
'action' => 'index_action',
]
);
// Provide a means for modules/third-parties to configure routes.
do_action_ref_array( 'ngg_routes', [ $router ] );
// Serve the routes.
if ( ! $router->serve_request() && $router->has_parameter_segments() ) {
$router->passthru();
}
}
public function is_page_request() {
return ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) && ! ( defined( 'DOING_CRON' ) && DOING_CRON ) && ! ( defined( 'NGG_AJAX_SLUG' ) && strpos( $_SERVER['REQUEST_URI'], NGG_AJAX_SLUG ) !== false );
}
public function deactivate() {
include_once 'products/photocrati_nextgen/class.nextgen_product_installer.php';
\Imagely\NGG\Util\Installer::add_handler( NGG_PLUGIN_BASENAME, 'C_NextGen_Product_Installer' );
\Imagely\NGG\Util\Installer::uninstall( NGG_PLUGIN_BASENAME );
}
public function activate() {
\Imagely\NGG\Util\Installer::set_role_caps();
set_transient( 'ngg-activated', time(), 30 );
}
public function define_constants() {
define( 'NGG_PLUGIN', basename( $this->directory_path() ) );
define( 'NGG_PLUGIN_SLUG', 'nextgen-gallery' );
define( 'NGG_PLUGIN_FILE', __FILE__ );
define( 'NGG_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
define( 'NGG_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'NGG_PLUGIN_URI', plugin_dir_url( __FILE__ ) );
define( 'NGG_PRODUCT_DIR', implode( DIRECTORY_SEPARATOR, [ rtrim( NGG_PLUGIN_DIR, '/\\' ), 'products' ] ) );
define( 'NGG_MODULE_DIR', implode( DIRECTORY_SEPARATOR, [ rtrim( NGG_PRODUCT_DIR, '/\\' ), 'photocrati_nextgen', 'modules' ] ) );
define( 'NGG_PLUGIN_STARTED_AT', microtime() );
define( 'NGG_PLUGIN_VERSION', '3.55' );
define( 'NGG_SCRIPT_VERSION', defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? (string) mt_rand( 0, mt_getrandmax() ) : NGG_PLUGIN_VERSION );
// Should we display NGG debugging information?
if ( ! defined( 'NGG_DEBUG' ) ) {
define( 'NGG_DEBUG', false );
}
self::$debug = NGG_DEBUG;
// User definable constants.
if ( ! defined( 'NGG_IMPORT_ROOT' ) ) {
$path = WP_CONTENT_DIR;
if ( defined( 'NEXTGEN_GALLERY_IMPORT_ROOT' ) ) {
$path = NEXTGEN_GALLERY_IMPORT_ROOT;
}
define( 'NGG_IMPORT_ROOT', $path );
}
// Should the Photocrati cache be enabled.
if ( ! defined( 'PHOTOCRATI_CACHE' ) ) {
define( 'PHOTOCRATI_CACHE', true );
}
if ( ! defined( 'PHOTOCRATI_CACHE_TTL' ) ) {
define( 'PHOTOCRATI_CACHE_TTL', 1800 );
}
// Cron job.
if ( ! defined( 'NGG_CRON_SCHEDULE' ) ) {
define( 'NGG_CRON_SCHEDULE', 900 );
}
if ( ! defined( 'NGG_CRON_ENABLED' ) ) {
define( 'NGG_CRON_ENABLED', true );
}
// Don't enforce interfaces.
if ( ! defined( 'EXTENSIBLE_OBJECT_ENFORCE_INTERFACES' ) ) {
define( 'EXTENSIBLE_OBJECT_ENFORCE_INTERFACES', false );
}
// Where are galleries restricted to?
if ( ! defined( 'NGG_GALLERY_ROOT_TYPE' ) ) {
define( 'NGG_GALLERY_ROOT_TYPE', 'site' ); // "content" is the other possible value.
}
// Define what file extensions and mime are accepted, with optional WebP.
$default_extensions_list = 'jpeg,jpg,png,gif';
$default_mime_list = 'image/gif,image/jpg,image/jpeg,image/pjpeg,image/png';
if ( function_exists( 'imagewebp' ) ) {
$default_extensions_list .= ',webp';
$default_mime_list .= ',image/webp';
}
if ( ! defined( 'NGG_DEFAULT_ALLOWED_FILE_TYPES' ) ) {
define( 'NGG_DEFAULT_ALLOWED_FILE_TYPES', $default_extensions_list );
}
if ( ! defined( 'NGG_DEFAULT_ALLOWED_MIME_TYPES' ) ) {
define( 'NGG_DEFAULT_ALLOWED_MIME_TYPES', $default_mime_list );
}
add_filter(
'ngg_allowed_file_types',
function ( $string ) {
return explode( ',', $string );
},
-10
);
add_filter(
'ngg_allowed_mime_types',
function ( $string ) {
return explode( ',', $string );
},
-10
);
define( 'NGG_LIGHTBOX_OPTIONS_SLUG', 'ngg_lightbox_options' );
define( 'NGG_ATTACH_TO_POST_SLUG', 'nextgen-attach_to_post' );
define( 'NGG_DISPLAY_SETTINGS_SLUG', 'ngg_display_settings' );
define( 'NGG_DISPLAY_PRIORITY_BASE', 10000 );
define( 'NGG_DISPLAY_PRIORITY_STEP', 2000 );
define( 'NGG_BASIC_IMAGEBROWSER', 'photocrati-nextgen_basic_imagebrowser' );
define( 'NGG_BASIC_SINGLEPIC', 'photocrati-nextgen_basic_singlepic' );
define( 'NGG_BASIC_TAGCLOUD', 'photocrati-nextgen_basic_tagcloud' );
define( 'NGG_BASIC_THUMBNAILS', 'photocrati-nextgen_basic_thumbnails' );
define( 'NGG_BASIC_SLIDESHOW', 'photocrati-nextgen_basic_slideshow' );
define( 'NGG_BASIC_COMPACT_ALBUM', 'photocrati-nextgen_basic_compact_album' );
define( 'NGG_BASIC_EXTENDED_ALBUM', 'photocrati-nextgen_basic_extended_album' );
define( 'NGG_BASIC_ALBUM', 'photocrati-nextgen_basic_album' );
if ( ! defined( 'NGG_RENDERING_CACHE_TTL' ) ) {
define( 'NGG_RENDERING_CACHE_TTL', PHOTOCRATI_CACHE_TTL );
}
if ( ! defined( 'NGG_DISPLAYED_GALLERY_CACHE_TTL' ) ) {
define( 'NGG_DISPLAYED_GALLERY_CACHE_TTL', PHOTOCRATI_CACHE_TTL );
}
if ( ! defined( 'NGG_RENDERING_CACHE_ENABLED' ) ) {
define( 'NGG_RENDERING_CACHE_ENABLED', PHOTOCRATI_CACHE );
}
if ( ! defined( 'NGG_SHOW_DISPLAYED_GALLERY_ERRORS' ) ) {
define( 'NGG_SHOW_DISPLAYED_GALLERY_ERRORS', NGG_DEBUG );
}
define( 'NGG_AJAX_SLUG', 'photocrati_ajax' );
}
/**
* Returns the path to a file within the plugin root folder
*
* @param string $file_name
* @return string
*/
public function file_path( $file_name = null ) {
$path = __DIR__;
if ( $file_name != null ) {
$path .= '/' . $file_name;
}
return str_replace( [ '/', '\\' ], DIRECTORY_SEPARATOR, $path );
}
/**
* Gets the directory path used by the plugin
*
* @param string|null $dir (optional)
* @return string
*/
public function directory_path( $dir = null ) {
return $this->file_path( $dir );
}
/**
* Returns the level of support for the POPE removal that Pro contains if active. Zero means Pro has not been
* updated at all and must rely on hacks in NextGEN for basic features. As POPE is removed, the level of support
* will rise, with the oldest checks in NextGEN being phased out the first.
*
* @return int
*/
public static function get_pro_api_version() {
if ( ! defined( 'NGG_PRO_API_VERSION' ) && ( defined( 'NGG_PLUS_PLUGIN_VERSION' ) || defined( 'NGG_STARTER_PLUGIN_VERSION' ) || defined( 'NGG_PRO_PLUGIN_VERSION' ) ) ) {
return 3;
}
if ( defined( 'NGG_PRO_API_VERSION' ) ) {
return NGG_PRO_API_VERSION;
}
return 10000;
}
}
new C_NextGEN_Bootstrap();
File Manager Version 1.0, Coded By Lucas
Email: hehe@yahoo.com