no wp
This commit is contained in:
@@ -1,230 +0,0 @@
|
||||
<?php
|
||||
namespace Imagify\ThirdParty\NGG\Bulk;
|
||||
|
||||
use C_Gallery_Storage;
|
||||
use Imagify\Bulk\AbstractBulk;
|
||||
use Imagify\ThirdParty\NGG\DB;
|
||||
|
||||
/**
|
||||
* Class to use for bulk for NextGen Gallery.
|
||||
*
|
||||
* @since 1.9
|
||||
*/
|
||||
class NGG extends AbstractBulk {
|
||||
/**
|
||||
* Context "short name".
|
||||
*
|
||||
* @var string
|
||||
* @since 1.9
|
||||
*/
|
||||
protected $context = 'ngg';
|
||||
|
||||
/**
|
||||
* Get all unoptimized media ids.
|
||||
*
|
||||
* @since 1.9
|
||||
*
|
||||
* @param int $optimization_level The optimization level.
|
||||
* @return array A list of unoptimized media IDs.
|
||||
*/
|
||||
public function get_unoptimized_media_ids( $optimization_level ) {
|
||||
global $wpdb;
|
||||
|
||||
$this->set_no_time_limit();
|
||||
|
||||
$storage = C_Gallery_Storage::get_instance();
|
||||
$ngg_table = $wpdb->prefix . 'ngg_pictures';
|
||||
$data = [];
|
||||
$images = $wpdb->get_results( $wpdb->prepare( // WPCS: unprepared SQL ok.
|
||||
"
|
||||
SELECT DISTINCT picture.pid as id, picture.filename, idata.optimization_level, idata.status, idata.data
|
||||
FROM $ngg_table as picture
|
||||
LEFT JOIN $wpdb->ngg_imagify_data as idata
|
||||
ON picture.pid = idata.pid
|
||||
WHERE idata.pid IS NULL
|
||||
OR idata.optimization_level != %d
|
||||
OR idata.status = 'error'
|
||||
LIMIT %d",
|
||||
$optimization_level,
|
||||
imagify_get_unoptimized_attachment_limit()
|
||||
), ARRAY_A );
|
||||
|
||||
if ( ! $images ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ( $images as $image ) {
|
||||
$id = absint( $image['id'] );
|
||||
$file_path = $storage->get_image_abspath( $id );
|
||||
|
||||
if ( ! $file_path || ! $this->filesystem->exists( $file_path ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attachment_data = maybe_unserialize( $image['data'] );
|
||||
$attachment_error = '';
|
||||
|
||||
if ( isset( $attachment_data['sizes']['full']['error'] ) ) {
|
||||
$attachment_error = $attachment_data['sizes']['full']['error'];
|
||||
}
|
||||
|
||||
$attachment_error = trim( $attachment_error );
|
||||
$attachment_status = $image['status'];
|
||||
$attachment_optimization_level = $image['optimization_level'];
|
||||
$attachment_backup_path = get_imagify_ngg_attachment_backup_path( $file_path );
|
||||
|
||||
// Don't try to re-optimize if the optimization level is still the same.
|
||||
if ( $optimization_level === $attachment_optimization_level && is_string( $attachment_error ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't try to re-optimize if there is no backup file.
|
||||
if ( 'success' === $attachment_status && $optimization_level !== $attachment_optimization_level && ! $this->filesystem->exists( $attachment_backup_path ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't try to re-optimize images already compressed.
|
||||
if ( 'already_optimized' === $attachment_status && $attachment_optimization_level >= $optimization_level ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't try to re-optimize images with an empty error message.
|
||||
if ( 'error' === $attachment_status && empty( $attachment_error ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data[] = $id;
|
||||
} // End foreach().
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ids of all optimized media without WebP versions.
|
||||
*
|
||||
* @since 1.9
|
||||
* @since 1.9.5 The method doesn't return the IDs directly anymore.
|
||||
*
|
||||
* @return array {
|
||||
* @type array $ids A list of media IDs.
|
||||
* @type array $errors {
|
||||
* @type array $no_file_path A list of media IDs.
|
||||
* @type array $no_backup A list of media IDs.
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public function get_optimized_media_ids_without_webp() {
|
||||
global $wpdb;
|
||||
|
||||
$this->set_no_time_limit();
|
||||
|
||||
$storage = C_Gallery_Storage::get_instance();
|
||||
$ngg_table = $wpdb->prefix . 'ngg_pictures';
|
||||
$data_table = DB::get_instance()->get_table_name();
|
||||
$webp_suffix = constant( imagify_get_optimization_process_class_name( 'ngg' ) . '::WEBP_SUFFIX' );
|
||||
$files = $wpdb->get_col( $wpdb->prepare( // WPCS: unprepared SQL ok.
|
||||
"
|
||||
SELECT ngg.pid
|
||||
FROM $ngg_table as ngg
|
||||
INNER JOIN $data_table AS data
|
||||
ON ( ngg.pid = data.pid )
|
||||
WHERE
|
||||
( data.status = 'success' OR data.status = 'already_optimized' )
|
||||
AND data.data NOT LIKE %s
|
||||
ORDER BY ngg.pid DESC",
|
||||
'%' . $wpdb->esc_like( $webp_suffix . '";a:4:{s:7:"success";b:1;' ) . '%'
|
||||
) );
|
||||
|
||||
$wpdb->flush();
|
||||
unset( $ngg_table, $data_table, $webp_suffix );
|
||||
|
||||
$data = [
|
||||
'ids' => [],
|
||||
'errors' => [
|
||||
'no_file_path' => [],
|
||||
'no_backup' => [],
|
||||
],
|
||||
];
|
||||
|
||||
if ( ! $files ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
foreach ( $files as $file_id ) {
|
||||
$file_id = absint( $file_id );
|
||||
$file_path = $storage->get_image_abspath( $file_id );
|
||||
|
||||
if ( ! $file_path ) {
|
||||
// Problem.
|
||||
$data['errors']['no_file_path'][] = $file_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
$backup_path = get_imagify_ngg_attachment_backup_path( $file_path );
|
||||
|
||||
if ( ! $this->filesystem->exists( $backup_path ) ) {
|
||||
// No backup, no WebP.
|
||||
$data['errors']['no_backup'][] = $file_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
$data['ids'][] = $file_id;
|
||||
} // End foreach().
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if there are optimized media without WebP versions.
|
||||
*
|
||||
* @since 1.9
|
||||
*
|
||||
* @return int The number of media.
|
||||
*/
|
||||
public function has_optimized_media_without_webp() {
|
||||
global $wpdb;
|
||||
|
||||
$ngg_table = $wpdb->prefix . 'ngg_pictures';
|
||||
$data_table = DB::get_instance()->get_table_name();
|
||||
$webp_suffix = constant( imagify_get_optimization_process_class_name( 'ngg' ) . '::WEBP_SUFFIX' );
|
||||
|
||||
return (int) $wpdb->get_var( $wpdb->prepare( // WPCS: unprepared SQL ok.
|
||||
"
|
||||
SELECT COUNT(ngg.pid)
|
||||
FROM $ngg_table as ngg
|
||||
INNER JOIN $data_table AS data
|
||||
ON ( ngg.pid = data.pid )
|
||||
WHERE
|
||||
( data.status = 'success' OR data.status = 'already_optimized' )
|
||||
AND data.data NOT LIKE %s",
|
||||
'%' . $wpdb->esc_like( $webp_suffix . '";a:4:{s:7:"success";b:1;' ) . '%'
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the context data.
|
||||
*
|
||||
* @since 1.9
|
||||
*
|
||||
* @return array {
|
||||
* The formated data.
|
||||
*
|
||||
* @type string $count-optimized Number of media optimized.
|
||||
* @type string $count-errors Number of media having an optimization error, with a link to the page listing the optimization errors.
|
||||
* @type string $optimized-size Optimized filesize.
|
||||
* @type string $original-size Original filesize.
|
||||
* }
|
||||
*/
|
||||
public function get_context_data() {
|
||||
$total_saving_data = imagify_count_saving_data();
|
||||
$data = [
|
||||
'count-optimized' => imagify_ngg_count_optimized_attachments(),
|
||||
'count-errors' => imagify_ngg_count_error_attachments(),
|
||||
'optimized-size' => $total_saving_data['optimized_size'],
|
||||
'original-size' => $total_saving_data['original_size'],
|
||||
'errors_url' => get_imagify_admin_url( 'folder-errors', $this->context ),
|
||||
];
|
||||
|
||||
return $this->format_context_data( $data );
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
<?php
|
||||
namespace Imagify\ThirdParty\NGG\Context;
|
||||
|
||||
use Imagify\Context\AbstractContext;
|
||||
use Imagify\Traits\InstanceGetterTrait;
|
||||
|
||||
/**
|
||||
* Context class used for the WP media library.
|
||||
*
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
class NGG extends AbstractContext {
|
||||
use InstanceGetterTrait;
|
||||
|
||||
/**
|
||||
* Context "short name".
|
||||
*
|
||||
* @var string
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected $context = 'ngg';
|
||||
|
||||
/**
|
||||
* Type of files this context allows.
|
||||
*
|
||||
* @var string Possible values are:
|
||||
* - 'all' to allow all types.
|
||||
* - 'image' to allow only images.
|
||||
* - 'not-image' to allow only pdf files.
|
||||
* @since 1.9
|
||||
* @see imagify_get_mime_types()
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected $allowed_mime_types = 'image';
|
||||
|
||||
/**
|
||||
* The thumbnail sizes for this context, except the full size.
|
||||
*
|
||||
* @var array {
|
||||
* Data for the currently registered thumbnail sizes.
|
||||
* Size names are used as array keys.
|
||||
*
|
||||
* @type int $width The image width.
|
||||
* @type int $height The image height.
|
||||
* @type bool $crop True to crop, false to resize.
|
||||
* @type string $name The size name.
|
||||
* }
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected $thumbnail_sizes = [];
|
||||
|
||||
/**
|
||||
* Tell if the optimization process is allowed to backup in this context.
|
||||
*
|
||||
* @var bool
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected $can_backup = true;
|
||||
|
||||
/**
|
||||
* Get images max width for this context. This is used when resizing.
|
||||
* 0 means to not resize.
|
||||
*
|
||||
* @since 1.9.8
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_resizing_threshold() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user capacity to operate Imagify in this context.
|
||||
*
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param string $describer Capacity describer. Possible values are like 'manage', 'bulk-optimize', 'manual-optimize', 'auto-optimize'.
|
||||
* @return string
|
||||
*/
|
||||
public function get_capacity( $describer = 'manage' ) {
|
||||
switch ( $describer ) {
|
||||
case 'manage':
|
||||
$capacity = 'NextGEN Change options';
|
||||
break;
|
||||
|
||||
case 'bulk-optimize':
|
||||
$capacity = 'NextGEN Manage others gallery';
|
||||
break;
|
||||
|
||||
case 'optimize':
|
||||
case 'restore':
|
||||
case 'manual-optimize':
|
||||
case 'manual-restore':
|
||||
$capacity = 'NextGEN Manage gallery';
|
||||
break;
|
||||
|
||||
case 'auto-optimize':
|
||||
$capacity = 'NextGEN Upload images';
|
||||
break;
|
||||
|
||||
default:
|
||||
$capacity = $describer;
|
||||
}
|
||||
|
||||
return $this->filter_capacity( $capacity, $describer );
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
<?php
|
||||
namespace Imagify\ThirdParty\NGG;
|
||||
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Imagify NextGen Gallery DB class.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Jonathan Buttigieg
|
||||
*/
|
||||
class DB extends \Imagify_Abstract_DB {
|
||||
|
||||
/**
|
||||
* Class version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '1.1.1';
|
||||
|
||||
/**
|
||||
* The single instance of the class.
|
||||
*
|
||||
* @var object
|
||||
* @since 1.5
|
||||
* @access protected
|
||||
*/
|
||||
protected static $_instance;
|
||||
|
||||
/**
|
||||
* The suffix used in the name of the database table (so, without the wpdb prefix).
|
||||
*
|
||||
* @var string
|
||||
* @since 1.7
|
||||
* @access protected
|
||||
*/
|
||||
protected $table = 'ngg_imagify_data';
|
||||
|
||||
/**
|
||||
* The version of our database table.
|
||||
*
|
||||
* @var int
|
||||
* @since 1.5
|
||||
* @since 1.7 Not public anymore, now an integer.
|
||||
* @access protected
|
||||
*/
|
||||
protected $table_version = 100;
|
||||
|
||||
/**
|
||||
* Tell if the table is the same for each site of a Multisite.
|
||||
*
|
||||
* @var bool
|
||||
* @since 1.7
|
||||
* @access protected
|
||||
*/
|
||||
protected $table_is_global = false;
|
||||
|
||||
/**
|
||||
* The name of the primary column.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.5
|
||||
* @since 1.7 Not public anymore.
|
||||
* @access protected
|
||||
*/
|
||||
protected $primary_key = 'pid';
|
||||
|
||||
/**
|
||||
* Get the main Instance.
|
||||
*
|
||||
* @since 1.6.5
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return object Main instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! isset( self::$_instance ) ) {
|
||||
self::$_instance = new self();
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whitelist of columns.
|
||||
*
|
||||
* @since 1.5
|
||||
* @access public
|
||||
* @author Jonathan Buttigieg
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'data_id' => '%d',
|
||||
'pid' => '%d',
|
||||
'optimization_level' => '%s',
|
||||
'status' => '%s',
|
||||
'data' => '%s',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Default column values.
|
||||
*
|
||||
* @since 1.5
|
||||
* @access public
|
||||
* @author Jonathan Buttigieg
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_column_defaults() {
|
||||
return array(
|
||||
'data_id' => 0,
|
||||
'pid' => 0,
|
||||
'optimization_level' => '',
|
||||
'status' => '',
|
||||
'data' => array(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query to create the table fields.
|
||||
*
|
||||
* @since 1.7
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_table_schema() {
|
||||
return "
|
||||
data_id int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
pid int(11) unsigned NOT NULL default 0,
|
||||
optimization_level varchar(1) NOT NULL default '',
|
||||
status varchar(30) NOT NULL default '',
|
||||
data longtext NOT NULL default '',
|
||||
PRIMARY KEY (data_id),
|
||||
KEY pid (pid)";
|
||||
}
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
<?php
|
||||
namespace Imagify\ThirdParty\NGG;
|
||||
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Class that handles the optimization of thumbnails dynamically generated.
|
||||
*
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
class DynamicThumbnails {
|
||||
use \Imagify\Traits\InstanceGetterTrait;
|
||||
|
||||
/**
|
||||
* The queue containing the sizes, grouped by image ID.
|
||||
*
|
||||
* @var array
|
||||
* @since 1.9
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected static $sizes = [];
|
||||
|
||||
/**
|
||||
* A list of NGG image objects, grouped by image ID.
|
||||
*
|
||||
* @var array
|
||||
* @since 1.9
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected static $images = [];
|
||||
|
||||
/**
|
||||
* Add a dynamically generated thumbnail to the background process queue.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param object $image A NGG image object.
|
||||
* @param string $size The thumbnail size name.
|
||||
*/
|
||||
public function push_to_queue( $image, $size ) {
|
||||
static $done = false;
|
||||
|
||||
if ( empty( $image->pid ) ) {
|
||||
// WUT?
|
||||
return;
|
||||
}
|
||||
|
||||
if ( empty( static::$sizes[ $image->pid ] ) ) {
|
||||
static::$sizes[ $image->pid ] = [];
|
||||
}
|
||||
|
||||
static::$sizes[ $image->pid ][] = $size;
|
||||
|
||||
if ( empty( static::$images[ $image->pid ] ) ) {
|
||||
static::$images[ $image->pid ] = $image;
|
||||
}
|
||||
|
||||
if ( $done ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$done = true;
|
||||
|
||||
add_action( 'shutdown', [ $this, 'optimize' ], 555 ); // Must come before 666 (see Imagify_Abstract_Background_Process->init()).
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the optimizations.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
public function optimize() {
|
||||
if ( empty( static::$sizes ) ) {
|
||||
// ¯\(°_o)/¯
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( static::$sizes as $image_id => $sizes ) {
|
||||
if ( empty( static::$images[ $image_id ] ) ) {
|
||||
// ¯\(°_o)/¯
|
||||
continue;
|
||||
}
|
||||
|
||||
$sizes = array_filter( $sizes );
|
||||
|
||||
if ( empty( $sizes ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$process = imagify_get_optimization_process( static::$images[ $image_id ], 'ngg' );
|
||||
|
||||
if ( ! $process->is_valid() || ! $process->get_media()->is_supported() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data = $process->get_data();
|
||||
|
||||
if ( ! $data->is_optimized() ) {
|
||||
// The main image is not optimized.
|
||||
continue;
|
||||
}
|
||||
|
||||
$sizes = array_unique( $sizes );
|
||||
|
||||
foreach ( $sizes as $i => $size ) {
|
||||
$size_status = $data->get_size_data( $size, 'success' );
|
||||
|
||||
if ( $size_status ) {
|
||||
// This thumbnail has already been processed.
|
||||
unset( $sizes[ $i ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $sizes ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$optimization_level = $process->get_data()->get_optimization_level();
|
||||
$args = [
|
||||
'hook_suffix' => 'optimize_generated_image',
|
||||
];
|
||||
|
||||
$process->optimize_sizes( $sizes, $optimization_level, $args );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
<?php
|
||||
namespace Imagify\ThirdParty\NGG;
|
||||
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Imagify NextGen Gallery class.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Jonathan Buttigieg
|
||||
*/
|
||||
class Main {
|
||||
use \Imagify\Traits\InstanceGetterTrait;
|
||||
|
||||
/**
|
||||
* Class version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '1.1';
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @since 1.5
|
||||
* @since 1.6.5 Doesn't launch the hooks anymore.
|
||||
* @since 1.9 Visibility set to public.
|
||||
* @access public
|
||||
* @author Jonathan Buttigieg
|
||||
*/
|
||||
public function __construct() {}
|
||||
|
||||
/**
|
||||
* Launch the hooks.
|
||||
*
|
||||
* @since 1.6.5
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
public function init() {
|
||||
static $done = false;
|
||||
|
||||
if ( $done ) {
|
||||
return;
|
||||
}
|
||||
$done = true;
|
||||
|
||||
add_filter( 'imagify_register_context', [ $this, 'register_context' ] );
|
||||
add_filter( 'imagify_context_class_name', [ $this, 'add_context_class_name' ], 10, 2 );
|
||||
add_filter( 'imagify_process_class_name', [ $this, 'add_process_class_name' ], 10, 2 );
|
||||
add_filter( 'imagify_bulk_class_name', [ $this, 'add_bulk_class_name' ], 10, 2 );
|
||||
add_action( 'init', [ $this, 'add_mixin' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the context used for NGG.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $contexts An array of context names.
|
||||
* @return array
|
||||
*/
|
||||
public function register_context( $contexts ) {
|
||||
$contexts[] = 'ngg';
|
||||
return $contexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the name of the class to use to define a context.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $class_name The class name.
|
||||
* @param string $context The context name.
|
||||
* @return string
|
||||
*/
|
||||
public function add_context_class_name( $class_name, $context ) {
|
||||
if ( 'ngg' === $context ) {
|
||||
return '\\Imagify\\ThirdParty\\NGG\\Context\\NGG';
|
||||
}
|
||||
|
||||
return $class_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the name of the class to use for the optimization.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $class_name The class name.
|
||||
* @param string $context The context name.
|
||||
* @return string
|
||||
*/
|
||||
public function add_process_class_name( $class_name, $context ) {
|
||||
if ( 'ngg' === $context ) {
|
||||
return '\\Imagify\\ThirdParty\\NGG\\Optimization\\Process\\NGG';
|
||||
}
|
||||
|
||||
return $class_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the name of the class to use for the bulk optimization.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int $class_name The class name.
|
||||
* @param string $context The context name.
|
||||
* @return string
|
||||
*/
|
||||
public function add_bulk_class_name( $class_name, $context ) {
|
||||
if ( 'ngg' === $context ) {
|
||||
return '\\Imagify\\ThirdParty\\NGG\\Bulk\\NGG';
|
||||
}
|
||||
|
||||
return $class_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom NGG mixin to override its functions.
|
||||
*
|
||||
* @since 1.5
|
||||
* @access public
|
||||
* @author Jonathan Buttigieg
|
||||
*/
|
||||
public function add_mixin() {
|
||||
\C_Gallery_Storage::get_instance()->get_wrapped_instance()->add_mixin( '\\Imagify\\ThirdParty\\NGG\\NGGStorage' );
|
||||
}
|
||||
}
|
||||
@@ -1,543 +0,0 @@
|
||||
<?php
|
||||
namespace Imagify\ThirdParty\NGG\Media;
|
||||
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Media class for the medias from NextGen Gallery.
|
||||
*
|
||||
* @since 1.9
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
class NGG extends \Imagify\Media\AbstractMedia {
|
||||
use \Imagify\Deprecated\Traits\Media\NGGDeprecatedTrait;
|
||||
|
||||
/**
|
||||
* Context (where the media "comes from").
|
||||
*
|
||||
* @var string
|
||||
* @since 1.9
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected $context = 'ngg';
|
||||
|
||||
/**
|
||||
* The image object.
|
||||
*
|
||||
* @var object A \nggImage object.
|
||||
* @since 1.9
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected $image;
|
||||
|
||||
/**
|
||||
* The storage object used by NGG.
|
||||
*
|
||||
* @var object A \C_Gallery_Storage object (by default).
|
||||
* @since 1.8.
|
||||
* @access protected
|
||||
*/
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param int|\nggImage|\nggdb|\StdClass $id The NGG image ID, \nggImage object, \nggdb object, or an anonym object containing a pid property.
|
||||
*/
|
||||
public function __construct( $id ) {
|
||||
if ( ! static::constructor_accepts( $id ) ) {
|
||||
parent::__construct( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( is_numeric( $id ) ) {
|
||||
$this->image = \nggdb::find_image( (int) $id );
|
||||
$id = ! empty( $this->image->pid ) ? (int) $this->image->pid : 0;
|
||||
} elseif ( $id instanceof \nggImage ) {
|
||||
$this->image = $id;
|
||||
$id = (int) $id->pid;
|
||||
} elseif ( is_object( $id ) ) {
|
||||
$this->image = \nggdb::find_image( (int) $id->pid );
|
||||
$id = ! empty( $this->image->pid ) ? (int) $this->image->pid : 0;
|
||||
} else {
|
||||
$id = 0;
|
||||
}
|
||||
|
||||
if ( ! $id ) {
|
||||
$this->image = null;
|
||||
|
||||
parent::__construct( 0 );
|
||||
return;
|
||||
}
|
||||
|
||||
parent::__construct( $id );
|
||||
|
||||
// NGG storage.
|
||||
if ( ! empty( $this->image->_ngiw ) ) {
|
||||
$this->storage = $this->image->_ngiw->get_storage()->object;
|
||||
} else {
|
||||
$this->storage = \C_Gallery_Storage::get_instance()->object;
|
||||
}
|
||||
|
||||
// Load nggAdmin class.
|
||||
$ngg_admin_functions_path = WP_PLUGIN_DIR . '/' . NGGFOLDER . '/products/photocrati_nextgen/modules/ngglegacy/admin/functions.php';
|
||||
|
||||
if ( ! class_exists( 'nggAdmin' ) && $this->filesystem->exists( $ngg_admin_functions_path ) ) {
|
||||
require_once $ngg_admin_functions_path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell if the given entry can be accepted in the constructor.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param mixed $id Whatever.
|
||||
* @return bool
|
||||
*/
|
||||
public static function constructor_accepts( $id ) {
|
||||
if ( ! $id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( is_numeric( $id ) || $id instanceof \nggImage ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return is_object( $id ) && ! empty( $id->pid ) && is_numeric( $id->pid );
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** NGG SPECIFICS =========================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Get the NGG image object.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return \nggImage
|
||||
*/
|
||||
public function get_ngg_image() {
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NGG storage object.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return \C_Gallery_Storage
|
||||
*/
|
||||
public function get_ngg_storage() {
|
||||
return $this->storage;
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** ORIGINAL FILE =========================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Get the original file path, even if the file doesn't exist.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string|bool The file path. False on failure.
|
||||
*/
|
||||
public function get_raw_original_path() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->get_cdn() ) {
|
||||
return $this->get_cdn()->get_file_path( 'original' );
|
||||
}
|
||||
|
||||
return ! empty( $this->image->imagePath ) ? $this->image->imagePath : false;
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** FULL SIZE FILE ========================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Get the URL of the media’s full size file.
|
||||
*
|
||||
* @since 1.9.8
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string|bool The file URL. False on failure.
|
||||
*/
|
||||
public function get_fullsize_url() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->get_cdn() ) {
|
||||
return $this->get_cdn()->get_file_url();
|
||||
}
|
||||
|
||||
return ! empty( $this->image->imageURL ) ? $this->image->imageURL : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path to the media’s full size file, even if the file doesn't exist.
|
||||
*
|
||||
* @since 1.9.8
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string|bool The file path. False on failure.
|
||||
*/
|
||||
public function get_raw_fullsize_path() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $this->get_cdn() ) {
|
||||
return $this->get_cdn()->get_file_path();
|
||||
}
|
||||
|
||||
return ! empty( $this->image->imagePath ) ? $this->image->imagePath : false;
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** BACKUP FILE ============================================================================= */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Get the backup URL, even if the file doesn't exist.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string|bool The file URL. False on failure.
|
||||
*/
|
||||
public function get_backup_url() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return site_url( '/' . $this->filesystem->make_path_relative( $this->get_raw_backup_path() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the backup file path, even if the file doesn't exist.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return string|bool The file path. False on failure.
|
||||
*/
|
||||
public function get_raw_backup_path() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return get_imagify_ngg_attachment_backup_path( $this->get_raw_original_path() );
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** THUMBNAILS ============================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Create the media thumbnails.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return bool|WP_Error True on success. A \WP_Error instance on failure.
|
||||
*/
|
||||
public function generate_thumbnails() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return new \WP_Error( 'invalid_media', __( 'This media is not valid.', 'imagify' ) );
|
||||
}
|
||||
|
||||
$image_data = $this->storage->_image_mapper->find( $this->get_id() ); // stdClass Object.
|
||||
|
||||
if ( ! $image_data ) {
|
||||
// ¯\(°_o)/¯
|
||||
return new \WP_Error( 'no_ngg_image', __( 'Image not found in NextGen Gallery data.', 'imagify' ) );
|
||||
}
|
||||
|
||||
if ( empty( $image_data->meta_data['backup'] ) || ! is_array( $image_data->meta_data['backup'] ) ) {
|
||||
$full_path = $this->storage->get_image_abspath( $image_data );
|
||||
|
||||
$image_data->meta_data['backup'] = [
|
||||
'filename' => $this->filesystem->file_name( $full_path ), // Yes, $full_path.
|
||||
'width' => $image_data->meta_data['width'], // Original image width.
|
||||
'height' => $image_data->meta_data['height'], // Original image height.
|
||||
'generated' => microtime(),
|
||||
];
|
||||
}
|
||||
|
||||
$backup_path = $this->storage->get_image_abspath( $image_data, 'backup' );
|
||||
$failed = [];
|
||||
|
||||
foreach ( $this->get_media_files() as $size_name => $size_data ) {
|
||||
if ( 'full' === $size_name ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$params = $this->storage->get_image_size_params( $image_data, $size_name );
|
||||
$thumbnail = @$this->storage->generate_image_clone( // Don't remove this @ or the sky will fall.
|
||||
$backup_path,
|
||||
$this->storage->get_image_abspath( $image_data, $size_name ),
|
||||
$params
|
||||
);
|
||||
|
||||
if ( ! $thumbnail ) {
|
||||
// Failed.
|
||||
$failed[] = $size_name;
|
||||
unset( $image_data->meta_data[ $size_name ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
$size_meta = [
|
||||
'width' => 0,
|
||||
'height' => 0,
|
||||
'filename' => \M_I18n::mb_basename( $thumbnail->fileName ),
|
||||
'generated' => microtime(),
|
||||
];
|
||||
|
||||
$dimensions = $this->filesystem->get_image_size( $thumbnail->fileName );
|
||||
|
||||
if ( $dimensions ) {
|
||||
$size_meta['width'] = $dimensions['width'];
|
||||
$size_meta['height'] = $dimensions['height'];
|
||||
}
|
||||
|
||||
if ( isset( $params['crop_frame'] ) ) {
|
||||
$size_meta['crop_frame'] = $params['crop_frame'];
|
||||
}
|
||||
|
||||
$image_data->meta_data[ $size_name ] = $size_meta;
|
||||
} // End foreach().
|
||||
|
||||
// Keep our property up to date.
|
||||
$this->image->_ngiw->_cache['meta_data'] = $image_data->meta_data;
|
||||
$this->image->_ngiw->_orig_image = $image_data;
|
||||
|
||||
$post_id = $this->storage->_image_mapper->save( $image_data );
|
||||
|
||||
if ( ! $post_id ) {
|
||||
return new \WP_Error( 'meta_data_not_saved', __( 'Related NextGen Gallery data could not be saved.', 'imagify' ) );
|
||||
}
|
||||
|
||||
if ( $failed ) {
|
||||
return new \WP_Error(
|
||||
'thumbnail_restore_failed',
|
||||
sprintf( _n( '%n thumbnail could not be restored.', '%n thumbnails could not be restored.', count( $failed ), 'imagify' ), count( $failed ) ),
|
||||
[ 'failed_thumbnails' => $failed ]
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** MEDIA DATA ============================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Tell if the current media has the required data (the data containing the file paths and thumbnails).
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_required_media_data() {
|
||||
static $sizes;
|
||||
|
||||
if ( ! $this->is_valid() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $sizes ) ) {
|
||||
$sizes = $this->get_media_files();
|
||||
}
|
||||
|
||||
return $sizes && ! empty( $this->image->imagePath );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of the files of this media, including the full size file.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return array {
|
||||
* An array with the size names as keys ('full' is used for the full size file), and arrays of data as values:
|
||||
*
|
||||
* @type string $size The size name.
|
||||
* @type string $path Absolute path to the file.
|
||||
* @type int $width The file width.
|
||||
* @type int $height The file height.
|
||||
* @type string $mime-type The file mime type.
|
||||
* @type bool $disabled True if the size is disabled in the plugin’s settings.
|
||||
* }
|
||||
*/
|
||||
public function get_media_files() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$fullsize_path = $this->get_raw_fullsize_path();
|
||||
|
||||
if ( ! $fullsize_path ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$dimensions = $this->get_dimensions();
|
||||
$all_sizes = [
|
||||
'full' => [
|
||||
'size' => 'full',
|
||||
'path' => $fullsize_path,
|
||||
'width' => $dimensions['width'],
|
||||
'height' => $dimensions['height'],
|
||||
'mime-type' => $this->get_mime_type(),
|
||||
'disabled' => false,
|
||||
],
|
||||
];
|
||||
|
||||
if ( ! $this->is_image() ) {
|
||||
return $this->filter_media_files( $all_sizes );
|
||||
}
|
||||
|
||||
// Remove common values (that have no value for us here, lol). Also remove 'full' and 'backup'.
|
||||
$image_data = array_diff_key( $this->image->meta_data, [
|
||||
'full' => 1,
|
||||
'backup' => 1,
|
||||
'width' => 1,
|
||||
'height' => 1,
|
||||
'md5' => 1,
|
||||
'aperture' => 1,
|
||||
'credit' => 1,
|
||||
'camera' => 1,
|
||||
'caption' => 1,
|
||||
'created_timestamp' => 1,
|
||||
'copyright' => 1,
|
||||
'focal_length' => 1,
|
||||
'iso' => 1,
|
||||
'shutter_speed' => 1,
|
||||
'flash' => 1,
|
||||
'title' => 1,
|
||||
'keywords' => 1,
|
||||
'saved' => 1,
|
||||
] );
|
||||
|
||||
if ( ! $image_data ) {
|
||||
return $this->filter_media_files( $all_sizes );
|
||||
}
|
||||
|
||||
$ngg_data = $this->storage->_image_mapper->find( $this->get_id() );
|
||||
|
||||
foreach ( $image_data as $size => $size_data ) {
|
||||
if ( ! isset( $size_data['width'], $size_data['height'], $size_data['filename'], $size_data['generated'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$file_type = (object) wp_check_filetype( $size_data['filename'], $this->get_allowed_mime_types() );
|
||||
|
||||
if ( ! $file_type->type ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$all_sizes[ $size ] = [
|
||||
'size' => $size,
|
||||
'path' => $this->storage->get_image_abspath( $ngg_data, $size ),
|
||||
'width' => (int) $size_data['width'],
|
||||
'height' => (int) $size_data['height'],
|
||||
'mime-type' => $file_type->type,
|
||||
'disabled' => false,
|
||||
];
|
||||
}
|
||||
|
||||
return $this->filter_media_files( $all_sizes );
|
||||
}
|
||||
|
||||
/**
|
||||
* If the media is an image, get its width and height.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_dimensions() {
|
||||
if ( ! $this->is_image() ) {
|
||||
return [
|
||||
'width' => 0,
|
||||
'height' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'width' => ! empty( $this->image->meta_data['width'] ) ? (int) $this->image->meta_data['width'] : 0,
|
||||
'height' => ! empty( $this->image->meta_data['height'] ) ? (int) $this->image->meta_data['height'] : 0,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the media data dimensions.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $dimensions {
|
||||
* An array containing width and height.
|
||||
*
|
||||
* @type int $width The image width.
|
||||
* @type int $height The image height.
|
||||
* }
|
||||
*/
|
||||
protected function update_media_data_dimensions( $dimensions ) {
|
||||
$changed = false;
|
||||
$data = [
|
||||
'width' => $dimensions['width'],
|
||||
'height' => $dimensions['height'],
|
||||
'md5' => md5_file( $this->get_raw_fullsize_path() ),
|
||||
];
|
||||
|
||||
foreach ( $data as $k => $v ) {
|
||||
if ( ! isset( $this->image->meta_data[ $k ] ) || $this->image->meta_data[ $k ] !== $v ) {
|
||||
$this->image->meta_data[ $k ] = $v;
|
||||
$changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $changed ) {
|
||||
\nggdb::update_image_meta( $this->id, $this->image->meta_data );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
<?php
|
||||
namespace Imagify\ThirdParty\NGG;
|
||||
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Imagify NextGen Gallery storage class.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Jonathan Buttigieg
|
||||
*/
|
||||
class NGGStorage extends \Mixin {
|
||||
|
||||
/**
|
||||
* Class version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const VERSION = '1.1';
|
||||
|
||||
/**
|
||||
* Delete a gallery AND all the pictures associated to this gallery!
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Jonathan Buttigieg
|
||||
*
|
||||
* @param int|object $gallery A gallery ID or object.
|
||||
* @return bool Whetther tha gallery was been deleted or not.
|
||||
*/
|
||||
public function delete_gallery( $gallery ) {
|
||||
$gallery_id = is_numeric( $gallery ) ? $gallery : $gallery->{$gallery->id_field};
|
||||
$images_id = \nggdb::get_ids_from_gallery( $gallery_id );
|
||||
|
||||
foreach ( $images_id as $pid ) {
|
||||
$process = imagify_get_optimization_process( $pid, 'ngg' );
|
||||
|
||||
if ( $process->is_valid() && $process->get_data()->is_optimized() ) {
|
||||
$process->get_data()->delete_optimization_data();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->call_parent( 'delete_gallery', $gallery );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a specific size for an image.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Jonathan Buttigieg
|
||||
*
|
||||
* @param int|object $image An image ID or NGG object.
|
||||
* @param string $size An image size.
|
||||
* @param array $params An array of parameters.
|
||||
* @param bool $skip_defaults Whatever NGG does with default settings.
|
||||
* @return bool|object An object on success. False on failure.
|
||||
*/
|
||||
public function generate_image_size( $image, $size, $params = null, $skip_defaults = false ) {
|
||||
// $image could be an object or an (int) image ID.
|
||||
if ( is_numeric( $image ) ) {
|
||||
$image = $this->object->_image_mapper->find( $image );
|
||||
}
|
||||
|
||||
// If a user adds a watermark, rotates or resizes an image, we restore it.
|
||||
// TO DO - waiting for a hook to be able to re-optimize the original size after restoring.
|
||||
if ( isset( $image->pid ) && ( true === $params['watermark'] || ( isset( $params['rotation'] ) || isset( $params['flip'] ) ) || ( ! empty( $params['width'] ) || ! empty( $params['height'] ) ) ) ) {
|
||||
$process = imagify_get_optimization_process( $image->pid, 'ngg' );
|
||||
|
||||
if ( $process->is_valid() && $process->get_data()->is_optimized() ) {
|
||||
$process->get_data()->delete_optimization_data();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->call_parent( 'generate_image_size', $image, $size, $params, $skip_defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Recover image from backup.
|
||||
*
|
||||
* @since 1.5
|
||||
* @author Jonathan Buttigieg
|
||||
*
|
||||
* @param int|object $image An image ID or NGG object.
|
||||
* @return string|bool Result code on success. False on failure.
|
||||
*/
|
||||
public function recover_image( $image ) {
|
||||
// $image could be an object or an (int) image ID.
|
||||
if ( is_numeric( $image ) ) {
|
||||
$image = $this->object->_image_mapper->find( $image );
|
||||
}
|
||||
|
||||
if ( ! $image ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove Imagify data.
|
||||
if ( isset( $image->pid ) ) {
|
||||
$process = imagify_get_optimization_process( $image->pid, 'ngg' );
|
||||
|
||||
if ( $process->is_valid() && $process->get_data()->is_optimized() ) {
|
||||
$process->get_data()->delete_optimization_data();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->call_parent( 'recover_image', $image );
|
||||
}
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
<?php
|
||||
namespace Imagify\ThirdParty\NGG\Optimization\Data;
|
||||
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Optimization data class for the custom folders.
|
||||
* This class constructor accepts:
|
||||
* - A NGG image ID (int).
|
||||
* - A \nggImage object.
|
||||
* - A \nggdb object.
|
||||
* - An anonym object containing a pid property (and everything else).
|
||||
* - A \Imagify\Media\MediaInterface object.
|
||||
*
|
||||
* @since 1.9
|
||||
* @see Imagify\ThirdParty\NGG\Media\NGG
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
class NGG extends \Imagify\Optimization\Data\AbstractData {
|
||||
use \Imagify\Traits\MediaRowTrait;
|
||||
|
||||
/**
|
||||
* The attachment SQL DB class.
|
||||
*
|
||||
* @var string
|
||||
* @since 1.9
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
protected $db_class_name = '\\Imagify\\ThirdParty\\NGG\\DB';
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param mixed $id An ID, or whatever type the "Media" class constructor accepts.
|
||||
*/
|
||||
public function __construct( $id ) {
|
||||
parent::__construct( $id );
|
||||
|
||||
if ( ! $this->is_valid() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is required by MediaRowTrait.
|
||||
$this->id = $this->get_media()->get_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the whole media optimization data.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return array The data. See parent method for details.
|
||||
*/
|
||||
public function get_optimization_data() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return $this->default_optimization_data;
|
||||
}
|
||||
|
||||
$row = array_merge( $this->get_row_db_instance()->get_column_defaults(), $this->get_row() );
|
||||
$data = $this->default_optimization_data;
|
||||
|
||||
$data['status'] = $row['status'];
|
||||
$data['level'] = $row['optimization_level'];
|
||||
$data['level'] = is_numeric( $data['level'] ) ? (int) $data['level'] : false;
|
||||
$data['stats'] = [
|
||||
'original_size' => 0,
|
||||
'optimized_size' => 0,
|
||||
'percent' => 0,
|
||||
];
|
||||
|
||||
if ( ! empty( $row['data']['sizes'] ) && is_array( $row['data']['sizes'] ) ) {
|
||||
$data['sizes'] = $row['data']['sizes'];
|
||||
$data['sizes'] = array_filter( $data['sizes'], 'is_array' );
|
||||
}
|
||||
|
||||
if ( empty( $data['sizes']['full'] ) ) {
|
||||
if ( 'success' === $row['status'] ) {
|
||||
$data['sizes']['full'] = [
|
||||
'success' => true,
|
||||
'original_size' => 0,
|
||||
'optimized_size' => 0,
|
||||
'percent' => 0,
|
||||
];
|
||||
} elseif ( ! empty( $row['status'] ) ) {
|
||||
$data['sizes']['full'] = [
|
||||
'success' => false,
|
||||
'error' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $data['sizes'] ) ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
foreach ( $data['sizes'] as $size_data ) {
|
||||
// Cast.
|
||||
if ( isset( $size_data['original_size'] ) ) {
|
||||
$size_data['original_size'] = (int) $size_data['original_size'];
|
||||
}
|
||||
if ( isset( $size_data['optimized_size'] ) ) {
|
||||
$size_data['optimized_size'] = (int) $size_data['optimized_size'];
|
||||
}
|
||||
if ( isset( $size_data['percent'] ) ) {
|
||||
$size_data['percent'] = round( $size_data['percent'], 2 );
|
||||
}
|
||||
// Stats.
|
||||
if ( ! empty( $size_data['original_size'] ) && ! empty( $size_data['optimized_size'] ) ) {
|
||||
$data['stats']['original_size'] += $size_data['original_size'];
|
||||
$data['stats']['optimized_size'] += $size_data['optimized_size'];
|
||||
}
|
||||
}
|
||||
|
||||
if ( $data['stats']['original_size'] && $data['stats']['optimized_size'] ) {
|
||||
$data['stats']['percent'] = $data['stats']['original_size'] - $data['stats']['optimized_size'];
|
||||
$data['stats']['percent'] = round( $data['stats']['percent'] / $data['stats']['original_size'] * 100, 2 );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the optimization data, level, and status for a size.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param string $size The size name.
|
||||
* @param array $data The optimization data. See parent method for details.
|
||||
*/
|
||||
public function update_size_optimization_data( $size, array $data ) {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$old_data = array_merge( $this->get_reset_data(), $this->get_row() );
|
||||
|
||||
$old_data['data']['sizes'] = ! empty( $old_data['data']['sizes'] ) && is_array( $old_data['data']['sizes'] ) ? $old_data['data']['sizes'] : [];
|
||||
|
||||
if ( 'full' === $size ) {
|
||||
/**
|
||||
* Original file.
|
||||
*/
|
||||
$old_data['optimization_level'] = $data['level'];
|
||||
$old_data['status'] = $data['status'];
|
||||
}
|
||||
|
||||
if ( ! $data['success'] ) {
|
||||
/**
|
||||
* Error.
|
||||
*/
|
||||
$old_data['data']['sizes'][ $size ] = [
|
||||
'success' => false,
|
||||
'error' => $data['error'],
|
||||
];
|
||||
} else {
|
||||
/**
|
||||
* Success.
|
||||
*/
|
||||
$old_data['data']['sizes'][ $size ] = [
|
||||
'success' => true,
|
||||
'original_size' => $data['original_size'],
|
||||
'optimized_size' => $data['optimized_size'],
|
||||
'percent' => round( ( $data['original_size'] - $data['optimized_size'] ) / $data['original_size'] * 100, 2 ),
|
||||
];
|
||||
}
|
||||
|
||||
$this->update_row( $old_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the media optimization data, level, and status.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
public function delete_optimization_data() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->delete_row();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the optimization data for the given sizes.
|
||||
* If all sizes are removed, all optimization data is deleted.
|
||||
* Status and level are not modified nor removed if the "full" size is removed. This leaves the media in a Schrödinger state.
|
||||
*
|
||||
* @since 1.9.8
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $sizes A list of sizes to remove.
|
||||
*/
|
||||
public function delete_sizes_optimization_data( array $sizes ) {
|
||||
if ( ! $sizes || ! $this->is_valid() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$data = array_merge( $this->get_reset_data(), $this->get_row() );
|
||||
|
||||
$data['data']['sizes'] = ! empty( $data['data']['sizes'] ) && is_array( $data['data']['sizes'] ) ? $data['data']['sizes'] : [];
|
||||
|
||||
if ( ! $data['data']['sizes'] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$remaining_sizes_data = array_diff_key( $data['data']['sizes'], array_flip( $sizes ) );
|
||||
|
||||
if ( ! $remaining_sizes_data ) {
|
||||
// All sizes have been removed: delete everything.
|
||||
$this->delete_optimization_data();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( count( $remaining_sizes_data ) === count( $data['data']['sizes'] ) ) {
|
||||
// Nothing has been removed.
|
||||
return;
|
||||
}
|
||||
|
||||
$data['data']['sizes'] = $remaining_sizes_data;
|
||||
|
||||
$this->update_row( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default values used to reset optimization data.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access protected
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return array {
|
||||
* The default values related to the optimization.
|
||||
*
|
||||
* @type string $optimization_level The optimization level.
|
||||
* @type string $status The status: success, already_optimized, error.
|
||||
* @type array $data Data related to the thumbnails.
|
||||
* }
|
||||
*/
|
||||
protected function get_reset_data() {
|
||||
$db_instance = $this->get_row_db_instance();
|
||||
$primary_key = $db_instance->get_primary_key();
|
||||
$column_defaults = $db_instance->get_column_defaults();
|
||||
|
||||
return array_diff_key( $column_defaults, [
|
||||
'data_id' => 0,
|
||||
$primary_key => 0,
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the row.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @param array $data The data to update.
|
||||
*/
|
||||
public function update_row( $data ) {
|
||||
if ( ! $this->db_class_name || $this->id <= 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$primary_key = $this->get_row_db_instance()->get_primary_key();
|
||||
// This is needed in case the row doesn't exist yet.
|
||||
$data[ $primary_key ] = $this->id;
|
||||
|
||||
$this->get_row_db_instance()->update( $this->id, $data );
|
||||
|
||||
$this->reset_row_cache();
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
<?php
|
||||
namespace Imagify\ThirdParty\NGG\Optimization\Process;
|
||||
|
||||
use Imagify\Optimization\File;
|
||||
|
||||
defined( 'ABSPATH' ) || die( 'Cheatin’ uh?' );
|
||||
|
||||
/**
|
||||
* Optimization class for NextGen Gallery.
|
||||
* This class constructor accepts:
|
||||
* - A NGG image ID (int).
|
||||
* - A \nggImage object.
|
||||
* - A \nggdb object.
|
||||
* - An anonym object containing a pid property (and everything else).
|
||||
* - A \Imagify\Media\MediaInterface object.
|
||||
*
|
||||
* @since 1.9
|
||||
* @see Imagify\ThirdParty\NGG\Media\NGG
|
||||
* @author Grégory Viguier
|
||||
*/
|
||||
class NGG extends \Imagify\Optimization\Process\AbstractProcess {
|
||||
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
/** MISSING THUMBNAILS ====================================================================== */
|
||||
/** ----------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Get the sizes for this media that have not get through optimization.
|
||||
* Since this context doesn't handle this feature, this will always return an empty array, unless an error is triggered.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return array|WP_Error A WP_Error object on failure. An empty array on success: this context has no thumbnails.
|
||||
* The tests are kept for consistency.
|
||||
*/
|
||||
public function get_missing_sizes() {
|
||||
// The media must have been optimized once and have a backup.
|
||||
if ( ! $this->is_valid() ) {
|
||||
return new \WP_Error( 'invalid_media', __( 'This media is not valid.', 'imagify' ) );
|
||||
}
|
||||
|
||||
$media = $this->get_media();
|
||||
|
||||
if ( ! $media->is_supported() ) {
|
||||
return new \WP_Error( 'media_not_supported', __( 'This media is not supported.', 'imagify' ) );
|
||||
}
|
||||
|
||||
$data = $this->get_data();
|
||||
|
||||
if ( ! $data->is_optimized() ) {
|
||||
return new \WP_Error( 'media_not_optimized', __( 'This media is not optimized yet.', 'imagify' ) );
|
||||
}
|
||||
|
||||
if ( ! $media->has_backup() ) {
|
||||
return new \WP_Error( 'no_backup', __( 'This file has no backup file.', 'imagify' ) );
|
||||
}
|
||||
|
||||
if ( ! $media->is_image() ) {
|
||||
return new \WP_Error( 'media_not_an_image', __( 'This media is not an image.', 'imagify' ) );
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimize missing thumbnail sizes.
|
||||
* Since this context doesn't handle this feature, this will always return a \WP_Error object.
|
||||
*
|
||||
* @since 1.9
|
||||
* @access public
|
||||
* @author Grégory Viguier
|
||||
*
|
||||
* @return bool|WP_Error True if successfully launched. A \WP_Error instance on failure.
|
||||
*/
|
||||
public function optimize_missing_thumbnails() {
|
||||
if ( ! $this->is_valid() ) {
|
||||
return new \WP_Error( 'invalid_media', __( 'This media is not valid.', 'imagify' ) );
|
||||
}
|
||||
|
||||
if ( ! $this->get_media()->is_supported() ) {
|
||||
return new \WP_Error( 'media_not_supported', __( 'This media is not supported.', 'imagify' ) );
|
||||
}
|
||||
|
||||
return new \WP_Error( 'no_sizes', __( 'No thumbnails seem to be missing.', 'imagify' ) );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user