This commit is contained in:
2024-05-20 15:37:46 +03:00
commit 00b7dbd0b7
10404 changed files with 3285853 additions and 0 deletions

View File

@ -0,0 +1,65 @@
<?php
namespace WebpConverter\Settings;
use WebpConverter\HookableInterface;
use WebpConverter\PluginInfo;
/**
* Initializes loading of assets in admin panel.
*/
class AdminAssetsLoader implements HookableInterface {
const CSS_FILE_PATH = 'assets/build/css/styles.css';
const JS_FILE_PATH = 'assets/build/js/scripts.js';
/**
* @var PluginInfo
*/
private $plugin_info;
public function __construct( PluginInfo $plugin_info ) {
$this->plugin_info = $plugin_info;
}
/**
* {@inheritdoc}
*/
public function init_hooks() {
add_action( 'admin_enqueue_scripts', [ $this, 'load_styles' ] );
add_action( 'admin_enqueue_scripts', [ $this, 'load_scripts' ] );
}
/**
* Loads CSS assets.
*
* @return void
* @internal
*/
public function load_styles() {
wp_register_style(
'converter-for-media',
$this->plugin_info->get_plugin_directory_url() . self::CSS_FILE_PATH,
[],
$this->plugin_info->get_plugin_version()
);
wp_enqueue_style( 'converter-for-media' );
}
/**
* Loads JavaScript assets.
*
* @return void
* @internal
*/
public function load_scripts() {
wp_register_script(
'converter-for-media',
$this->plugin_info->get_plugin_directory_url() . self::JS_FILE_PATH,
[],
$this->plugin_info->get_plugin_version(),
true
);
wp_enqueue_script( 'converter-for-media' );
}
}

View File

@ -0,0 +1,114 @@
<?php
namespace WebpConverter\Settings\Option;
use WebpConverter\Repository\TokenRepository;
/**
* {@inheritdoc}
*/
class AccessTokenOption extends OptionAbstract {
const OPTION_NAME = 'access_token';
/**
* @var TokenRepository
*/
private $token_repository;
public function __construct( TokenRepository $token_repository ) {
$this->token_repository = $token_repository;
}
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_SIDEBAR;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_TOKEN;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Access Token', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
if ( $this->token_repository->get_token()->get_valid_status() ) {
return sprintf(
/* translators: %1$s: open anchor tag, %2$s: close anchor tag */
__( 'To manage your subscriptions, please visit %1$sour website%2$s.', 'webp-converter-for-media' ),
'<a href="https://url.mattplugins.com/converter-field-access-token-management" target="_blank">',
'</a>'
);
}
return sprintf(
/* translators: %1$s: open anchor tag, %2$s: close anchor tag, %3$s: open anchor tag, %4$s: close anchor tag */
__( 'Provide a valid token to access %1$sthe PRO functionalities%2$s. You can find out more about it %3$shere%4$s.', 'webp-converter-for-media' ),
'<a href="https://url.mattplugins.com/converter-field-access-token-pro-features" target="_blank">',
'</a>',
'<a href="https://url.mattplugins.com/converter-field-access-token-find-more" target="_blank">',
'</a>'
);
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
return [];
}
/**
* {@inheritdoc}
*/
public function get_default_value( array $settings = null ): string {
return '';
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ): string {
return sanitize_text_field( $current_value );
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ): string {
return $this->validate_value( $current_value );
}
/**
* {@inheritdoc}
*/
public function get_public_value( $current_value = null ) {
if ( $current_value === null ) {
return $current_value;
}
return substr( $current_value, 0, 32 ) . str_repeat( '*', max( ( strlen( $current_value ) - 32 ), 0 ) );
}
}

View File

@ -0,0 +1,74 @@
<?php
namespace WebpConverter\Settings\Option;
/**
* {@inheritdoc}
*/
class AutoConversionOption extends OptionAbstract {
const OPTION_NAME = 'auto_conversion';
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_BASIC;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_TOGGLE;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Conversion of new images', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
return __( 'Automatically convert new images when uploading to Media Library', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_available_values( array $settings ) {
return null;
}
/**
* {@inheritdoc}
*/
public function get_default_value( array $settings = null ): string {
return 'yes';
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ): string {
return ( $current_value === 'yes' ) ? 'yes' : '';
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ): string {
return $this->validate_value( $current_value );
}
}

View File

@ -0,0 +1,91 @@
<?php
namespace WebpConverter\Settings\Option;
/**
* {@inheritdoc}
*/
class CloudflareApiTokenOption extends OptionAbstract {
const OPTION_NAME = 'cloudflare_api_token';
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_CDN;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_INPUT;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return 'Cloudflare API Token';
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
return sprintf(
/* translators: %s: service name */
__( 'Optionally, fill in if you are using %s.', 'webp-converter-for-media' ),
'Cloudflare'
);
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
return [];
}
/**
* {@inheritdoc}
*/
public function get_default_value( array $settings = null ): string {
return '';
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ): string {
return sanitize_text_field( $current_value );
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ): string {
return $this->validate_value( $current_value );
}
/**
* {@inheritdoc}
*/
public function get_public_value( $current_value = null ) {
if ( $current_value === null ) {
return $current_value;
}
return str_repeat( '*', max( strlen( $current_value ), 0 ) );
}
}

View File

@ -0,0 +1,102 @@
<?php
namespace WebpConverter\Settings\Option;
/**
* {@inheritdoc}
*/
class CloudflareZoneIdOption extends OptionAbstract {
const OPTION_NAME = 'cloudflare_zone_id';
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_CDN;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_INPUT;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return 'Cloudflare Zone ID';
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
return implode(
' ',
[
sprintf(
/* translators: %s: service name */
__( 'Optionally, fill in if you are using %s.', 'webp-converter-for-media' ),
'Cloudflare'
),
sprintf(
/* translators: %1$s: open anchor tag, %2$s: close anchor tag */
__( 'Check out %1$sour documentation%2$s for more information.', 'webp-converter-for-media' ),
'<a href="https://url.mattplugins.com/converter-field-cloudflare-info" target="_blank">',
'</a>'
),
]
);
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
return [];
}
/**
* {@inheritdoc}
*/
public function get_default_value( array $settings = null ): string {
return '';
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ): string {
return sanitize_text_field( $current_value );
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ): string {
return $this->validate_value( $current_value );
}
/**
* {@inheritdoc}
*/
public function get_public_value( $current_value = null ) {
if ( $current_value === null ) {
return $current_value;
}
return str_repeat( '*', max( strlen( $current_value ), 0 ) );
}
}

View File

@ -0,0 +1,130 @@
<?php
namespace WebpConverter\Settings\Option;
use WebpConverter\Conversion\Method\GdMethod;
use WebpConverter\Conversion\Method\ImagickMethod;
use WebpConverter\Conversion\Method\MethodFactory;
use WebpConverter\Conversion\Method\RemoteMethod;
use WebpConverter\Repository\TokenRepository;
/**
* {@inheritdoc}
*/
class ConversionMethodOption extends OptionAbstract {
const OPTION_NAME = 'method';
/**
* @var TokenRepository
*/
private $token_repository;
/**
* @var MethodFactory
*/
private $method_factory;
public function __construct( TokenRepository $token_repository, MethodFactory $method_factory ) {
$this->token_repository = $token_repository;
$this->method_factory = $method_factory;
}
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_ADVANCED;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_RADIO;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Conversion method', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_notice_lines() {
$notice = [
__( 'The remote server allows you to reduce the server load, because your images are converted by our server. This option is also useful when the server does not meet all the technical requirements of the plugin.', 'webp-converter-for-media' ),
];
if ( $this->token_repository->get_token()->get_token_value() === null ) {
$notice[] = sprintf(
/* translators: %1$s: open anchor tag, %2$s: close anchor tag */
__( '%1$sUpgrade to PRO%2$s', 'webp-converter-for-media' ),
'<a href="https://url.mattplugins.com/converter-field-conversion-method-info" target="_blank">',
' <span class="dashicons dashicons-external"></span></a>'
);
}
return $notice;
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
return $this->method_factory->get_methods();
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_disabled_values( array $settings ): array {
$methods = $this->method_factory->get_methods();
$methods_available = $this->method_factory->get_available_methods();
return array_keys( array_diff( $methods, $methods_available ) );
}
/**
* {@inheritdoc}
*/
public function get_default_value( array $settings = null ): string {
$methods_available = $this->method_factory->get_available_methods();
return array_keys( $methods_available )[0] ?? '';
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ) {
if ( ! array_key_exists( $current_value, $available_values ?: [] ) ) {
return null;
}
return $current_value;
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ) {
$values = [ ImagickMethod::METHOD_NAME, GdMethod::METHOD_NAME, RemoteMethod::METHOD_NAME ];
return $this->validate_value(
$current_value,
array_combine( $values, $values )
);
}
}

View File

@ -0,0 +1,85 @@
<?php
namespace WebpConverter\Settings\Option;
/**
* {@inheritdoc}
*/
class ExcludedDirectoriesOption extends OptionAbstract {
const OPTION_NAME = 'excluded_dirs';
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_ADVANCED;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_INPUT;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Excluded directories', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
return __( 'Directory names separated by a comma that will be skipped during image conversion.', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_placeholder() {
return 'directory-1,directory-2';
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
return [];
}
/**
* {@inheritdoc}
*/
public function get_default_value( array $settings = null ): string {
return '';
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ): string {
$valid_values = explode( ',', str_replace( [ '/', '\\' ], '', $current_value ) );
$valid_values = array_map( 'trim', $valid_values );
return implode( ',', $valid_values );
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ): string {
return $this->validate_value( $current_value );
}
}

View File

@ -0,0 +1,148 @@
<?php
namespace WebpConverter\Settings\Option;
use WebpConverter\Conversion\Method\GdMethod;
/**
* {@inheritdoc}
*/
class ExtraFeaturesOption extends OptionAbstract {
const OPTION_NAME = 'features';
const OPTION_VALUE_ONLY_SMALLER = 'only_smaller';
const OPTION_VALUE_KEEP_METADATA = 'keep_metadata';
const OPTION_VALUE_CRON_ENABLED = 'cron_enabled';
const OPTION_VALUE_BACKUP_ENABLED = 'backup_enabled';
const OPTION_VALUE_SERVICE_MODE = 'service_mode';
const OPTION_VALUE_REWRITE_INHERIT = 'rewrite_inherit_disabled';
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_ADVANCED;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_CHECKBOX;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Extra features', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
return __( 'Options allow you to enable new functionalities that will increase the capabilities of the plugin', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
return [
self::OPTION_VALUE_ONLY_SMALLER => __(
'Automatic removal of files in output formats larger than the original ones',
'webp-converter-for-media'
),
self::OPTION_VALUE_KEEP_METADATA => sprintf(
'%1$s (%2$s)',
__( 'Keep images metadata stored in EXIF or XMP formats', 'webp-converter-for-media' ),
__( 'unavailable for the GD conversion method', 'webp-converter-for-media' )
),
self::OPTION_VALUE_CRON_ENABLED => sprintf(
'%1$s (%2$s)',
__( 'Convert automatically images from custom directories', 'webp-converter-for-media' ),
__( 'e.g. from /themes or non-standard in /uploads', 'webp-converter-for-media' )
),
self::OPTION_VALUE_BACKUP_ENABLED => __(
'Save converted images in backups generated by other plugins',
'webp-converter-for-media'
),
self::OPTION_VALUE_SERVICE_MODE => sprintf(
'%1$s (%2$s)',
__( 'Enable the service mode', 'webp-converter-for-media' ),
__( 'only upon the request from plugin\'s technical support', 'webp-converter-for-media' )
),
];
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_disabled_values( array $settings ): array {
$values = [];
if ( ( $settings[ ConversionMethodOption::OPTION_NAME ] ?? GdMethod::METHOD_NAME ) === GdMethod::METHOD_NAME ) {
$values[] = self::OPTION_VALUE_KEEP_METADATA;
}
return $values;
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_default_value( array $settings = null ): array {
return [
self::OPTION_VALUE_ONLY_SMALLER,
];
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ) {
$valid_values = [];
if ( ! $current_value ) {
return $valid_values;
}
foreach ( $current_value as $option_value ) {
if ( array_key_exists( $option_value, $available_values ?: [] )
&& ! in_array( $option_value, $disabled_values ?: [] ) ) {
$valid_values[] = $option_value;
}
}
return $valid_values;
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ) {
$values = [
self::OPTION_VALUE_ONLY_SMALLER,
self::OPTION_VALUE_KEEP_METADATA,
self::OPTION_VALUE_CRON_ENABLED,
self::OPTION_VALUE_BACKUP_ENABLED,
self::OPTION_VALUE_SERVICE_MODE,
];
return $this->validate_value(
$current_value,
array_combine( $values, $values )
);
}
}

View File

@ -0,0 +1,168 @@
<?php
namespace WebpConverter\Settings\Option;
use WebpConverter\Repository\TokenRepository;
/**
* {@inheritdoc}
*/
class ImageResizeOption extends OptionAbstract {
const OPTION_NAME = 'image_resize';
/**
* @var TokenRepository
*/
private $token_repository;
public function __construct( TokenRepository $token_repository ) {
$this->token_repository = $token_repository;
}
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_BASIC;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_IMAGE_SIZE;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Maximum image dimensions', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
$message = __( 'Resize large images to maximum dimensions in pixels during image conversion, keeping the original aspect ratio', 'webp-converter-for-media' );
if ( ! $this->token_repository->get_token()->get_valid_status() ) {
return sprintf(
'%1$s (%2$s)',
$message,
sprintf(
/* translators: %1$s: open anchor tag, %2$s: close anchor tag */
__( 'available in %1$sthe PRO version%2$s', 'webp-converter-for-media' ),
'<a href="https://url.mattplugins.com/converter-field-image-resize-upgrade" target="_blank">',
'</a>'
)
);
}
return $message;
}
/**
* {@inheritdoc}
*/
public function get_notice_lines() {
$size = $this->get_max_image_size();
$notice = [
sprintf(
/* translators: %1$s: width value, %2$s: height value */
__( 'You can further decrease the size of converted images (and thus their weight) that exceed the maximum image size (thumbnail size) used in your theme. The recommended value for you is %1$s x %2$s pixels.', 'webp-converter-for-media' ),
$size['width'],
$size['height']
),
];
if ( $this->token_repository->get_token()->get_token_value() === null ) {
$notice[] = sprintf(
/* translators: %1$s: open anchor tag, %2$s: close anchor tag */
__( '%1$sUpgrade to PRO%2$s', 'webp-converter-for-media' ),
'<a href="https://url.mattplugins.com/converter-field-image-resize-info" target="_blank">',
' <span class="dashicons dashicons-external"></span></a>'
);
}
return $notice;
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
return [];
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_disabled_values( array $settings ): array {
if ( ! $this->token_repository->get_token()->get_valid_status() ) {
return [ 'yes' ];
}
return [];
}
/**
* {@inheritdoc}
*
* @return mixed[]
*/
public function get_default_value( array $settings = null ): array {
return [ '', '', '' ];
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ) {
if ( ! is_array( $current_value ) ) {
return [ '', '', '' ];
}
$value_min = intval( $current_value[1] ?? '' );
$value_max = intval( $current_value[2] ?? '' );
return [
( ( $current_value[0] ?? '' ) === 'yes' ) ? 'yes' : '',
( $value_min <= 1 ) ? '' : (string) $value_min,
( $value_max <= 1 ) ? '' : (string) $value_max,
];
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ) {
return $this->validate_value( $current_value );
}
/**
* @return int[]
*/
private function get_max_image_size(): array {
$sizes = ( function_exists( 'wp_get_registered_image_subsizes' ) )
? wp_get_registered_image_subsizes()
: wp_get_additional_image_sizes();
$column_width = array_column( $sizes, 'width' );
$column_height = array_column( $sizes, 'height' );
return [
'width' => ( $column_width ) ? max( $column_width ) : 0,
'height' => ( $column_height ) ? max( $column_height ) : 0,
];
}
}

View File

@ -0,0 +1,115 @@
<?php
namespace WebpConverter\Settings\Option;
/**
* {@inheritdoc}
*/
class ImagesQualityOption extends OptionAbstract {
const OPTION_NAME = 'quality';
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_BASIC;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_QUALITY;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Conversion strategy', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
return implode(
'',
[
sprintf(
/* translators: %s: level name */
__( 'The "%s" value is the most optimal choice for most websites.', 'webp-converter-for-media' ),
__( 'Optimal', 'webp-converter-for-media' )
),
sprintf(
' <span class="dashicons dashicons-info-outline" title="%s"></span>',
esc_attr(
sprintf(
/* translators: %1$s: button label, %2$s: option label */
__( 'After saving the change to this setting, remember to click the "%1$s" button with the "%2$s" option checked if you want to apply the change to already converted images.', 'webp-converter-for-media' ),
__( 'Start Bulk Optimization', 'webp-converter-for-media' ),
__( 'Force the conversion of all images again', 'webp-converter-for-media' )
)
)
),
]
);
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
$levels = apply_filters( 'webpc_option_quality_levels', [ '75', '80', '85', '90', '95' ] );
$values = [];
foreach ( $levels as $level ) {
$level_value = (int) $level;
if ( ( $level_value > 0 ) && ( $level_value <= 100 ) ) {
$values[ $level_value ] = sprintf( '%s%%', $level_value );
}
}
ksort( $values );
return $values;
}
/**
* {@inheritdoc}
*/
public function get_default_value( array $settings = null ): string {
return '85';
}
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ) {
if ( $current_value === '100' ) {
return '95';
} elseif ( ! array_key_exists( $current_value, $available_values ?: [] )
|| in_array( $current_value, $disabled_values ?: [] ) ) {
return null;
}
return $current_value;
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ): string {
$values = apply_filters( 'webpc_option_quality_levels', [ '75', '80', '85', '90', '95' ] );
return $this->validate_value(
$current_value,
array_combine( $values, $values )
);
}
}

View File

@ -0,0 +1,119 @@
<?php
namespace WebpConverter\Settings\Option;
use WebpConverter\Error\Notice\BypassingApacheNotice;
use WebpConverter\Loader\HtaccessBypassingLoader;
use WebpConverter\Loader\HtaccessLoader;
use WebpConverter\Loader\PassthruLoader;
/**
* {@inheritdoc}
*/
class LoaderTypeOption extends OptionAbstract {
const OPTION_NAME = 'loader_type';
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_ADVANCED;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_RADIO;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Image loading mode', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
return implode(
' ',
[
__( 'By changing this mode, you can bypass some of the server configuration problems.', 'webp-converter-for-media' ),
sprintf(
/* translators: %1$s: open anchor tag, %2$s: close anchor tag */
__( 'Check out %1$sour documentation%2$s for more information.', 'webp-converter-for-media' ),
'<a href="https://url.mattplugins.com/converter-field-loader-type-info" target="_blank">',
'</a>'
),
]
);
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
return [
HtaccessLoader::LOADER_TYPE => sprintf(
/* translators: %s: loader type */
__( '%s (recommended)', 'webp-converter-for-media' ),
__( 'via .htaccess', 'webp-converter-for-media' ) . ' / Nginx'
),
HtaccessBypassingLoader::LOADER_TYPE => sprintf(
/* translators: %1$s: loader type, %2$S: error name */
__( '%1$s (use when you have a problem with the %2$s error)', 'webp-converter-for-media' ),
__( 'Bypassing Nginx', 'webp-converter-for-media' ),
BypassingApacheNotice::ERROR_KEY
),
PassthruLoader::LOADER_TYPE => sprintf(
/* translators: %s: loader type */
__( '%s (without rewrites in .htaccess files or the Nginx configuration)', 'webp-converter-for-media' ),
'Pass Thru'
),
];
}
/**
* {@inheritdoc}
*/
public function get_default_value( array $settings = null ): string {
return HtaccessLoader::LOADER_TYPE;
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ) {
if ( ! array_key_exists( $current_value, $available_values ?: [] )
|| in_array( $current_value, $disabled_values ?: [] ) ) {
return null;
}
return $current_value;
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ) {
$values = [ HtaccessLoader::LOADER_TYPE, HtaccessBypassingLoader::LOADER_TYPE, PassthruLoader::LOADER_TYPE ];
return $this->validate_value(
$current_value,
array_combine( $values, $values )
);
}
}

View File

@ -0,0 +1,79 @@
<?php
namespace WebpConverter\Settings\Option;
/**
* {@inheritdoc}
*/
class MediaStatsOption extends OptionAbstract {
const OPTION_NAME = 'media_stats';
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_ADVANCED;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_TOGGLE;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Optimization statistics', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
return sprintf(
/* translators: %1$s: open anchor tag, %2$s: close anchor tag */
__( 'Show the statistics in %1$sMedia Library%2$s', 'webp-converter-for-media' ),
'<a href="' . admin_url( 'upload.php?mode=list' ) . '">',
'</a>'
);
}
/**
* {@inheritdoc}
*/
public function get_available_values( array $settings ) {
return null;
}
/**
* {@inheritdoc}
*/
public function get_default_value( array $settings = null ): string {
return 'yes';
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ): string {
return ( $current_value === 'yes' ) ? 'yes' : '';
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ): string {
return $this->validate_value( $current_value );
}
}

View File

@ -0,0 +1,63 @@
<?php
namespace WebpConverter\Settings\Option;
/**
* Abstract class for class that supports notice displayed in admin panel.
*/
abstract class OptionAbstract implements OptionInterface {
const OPTION_TYPE_CHECKBOX = 'checkbox';
const OPTION_TYPE_RADIO = 'radio';
const OPTION_TYPE_QUALITY = 'quality';
const OPTION_TYPE_INPUT = 'input';
const OPTION_TYPE_TOKEN = 'token';
const OPTION_TYPE_IMAGE_SIZE = 'image_size';
const OPTION_TYPE_TOGGLE = 'toggle';
const FORM_TYPE_BASIC = 'basic';
const FORM_TYPE_ADVANCED = 'settings_advanced';
const FORM_TYPE_CDN = 'settings_cdn';
const FORM_TYPE_SIDEBAR = 'settings_sidebar';
/**
* {@inheritdoc}
*/
public function get_notice_lines() {
return null;
}
/**
* {@inheritdoc}
*/
public function get_info() {
return null;
}
/**
* {@inheritdoc}
*/
public function get_placeholder() {
return '';
}
/**
* {@inheritdoc}
*/
public function get_debug_value( array $settings ) {
return $this->get_default_value( $settings );
}
/**
* {@inheritdoc}
*/
public function get_public_value( $current_value = null ) {
return $current_value;
}
/**
* {@inheritdoc}
*/
public function get_disabled_values( array $settings ) {
return null;
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace WebpConverter\Settings\Option;
/**
* Allows to integrate with field in plugin settings by specifying its settings and value.
*/
class OptionIntegrator {
/**
* Objects of supported settings options.
*
* @var OptionInterface
*/
private $option;
/**
* @param OptionInterface $option .
*/
public function __construct( OptionInterface $option ) {
$this->option = $option;
}
/**
* Returns data of option based on plugin settings.
*
* @param mixed[] $settings Plugin settings.
* @param bool $is_debug Is debugging?
* @param bool $is_save Is saving?
*
* @return mixed[] Data of option.
*/
public function get_option_data( array $settings, bool $is_debug, bool $is_save ): array {
$option_name = $this->option->get_name();
$option_type = $this->option->get_type();
$values = $this->option->get_available_values( $settings );
$disabled_values = $this->option->get_disabled_values( $settings );
if ( $is_debug ) {
$value = $this->option->get_debug_value( $settings );
} else {
$value = ( isset( $settings[ $option_name ] ) || $is_save )
? $this->option->validate_value( $settings[ $option_name ] ?? null, $values, $disabled_values )
: null;
}
$value = ( $value !== null ) ? $value : $this->option->get_default_value( $settings );
return [
'name' => $this->option->get_name(),
'type' => $option_type,
'label' => $this->option->get_label(),
'notice_lines' => $this->option->get_notice_lines(),
'info' => $this->option->get_info(),
'placeholder' => $this->option->get_placeholder(),
'values' => $values,
'disabled' => $disabled_values ?: [],
'value' => $value,
'value_public' => $this->option->get_public_value( $value ),
];
}
}

View File

@ -0,0 +1,113 @@
<?php
namespace WebpConverter\Settings\Option;
/**
* Interface for class that supports data field in plugin settings.
*/
interface OptionInterface {
/**
* Returns name of option.
*
* @return string
*/
public function get_name(): string;
/**
* @return string
*/
public function get_form_name(): string;
/**
* Returns type of field.
*
* @return string
*/
public function get_type(): string;
/**
* Returns label of option.
*
* @return string|null
*/
public function get_label();
/**
* @return string[]|null
*/
public function get_notice_lines();
/**
* Returns additional information of field.
*
* @return string|null
*/
public function get_info();
/**
* @return string|null
*/
public function get_placeholder();
/**
* @param mixed[] $settings Plugin settings.
*
* @return string[]|null
*/
public function get_available_values( array $settings );
/**
* @param mixed[] $settings Plugin settings.
*
* @return string[]|null
*/
public function get_disabled_values( array $settings );
/**
* Returns default value of field.
*
* @param mixed[]|null $settings Plugin settings.
*
* @return string|string[]
*/
public function get_default_value( array $settings = null );
/**
* Returns verified value of field.
*
* @param mixed|null $current_value .
* @param string[]|null $available_values .
* @param string[]|null $disabled_values .
*
* @return mixed|null
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null );
/**
* Returns sanitized value of field.
*
* @param mixed|null $current_value .
*
* @return mixed|null
*/
public function sanitize_value( $current_value );
/**
* Returns value of field without sensitive data.
*
* @param mixed|null $current_value .
*
* @return mixed|null
*/
public function get_public_value( $current_value = null );
/**
* Returns default value of field when debugging.
*
* @param mixed[] $settings Plugin settings.
*
* @return string|string[]
*/
public function get_debug_value( array $settings );
}

View File

@ -0,0 +1,98 @@
<?php
namespace WebpConverter\Settings\Option;
use WebpConverter\Conversion\Directory\DirectoryFactory;
use WebpConverter\Conversion\Format\FormatFactory;
use WebpConverter\Conversion\Method\MethodFactory;
use WebpConverter\Repository\TokenRepository;
/**
* .
*/
class OptionsAggregator {
/**
* Objects of supported options.
*
* @var OptionInterface[]
*/
private $options = [];
public function __construct(
TokenRepository $token_repository,
MethodFactory $method_factory,
FormatFactory $format_factory,
DirectoryFactory $directory_factory
) {
$conversion_method = new ConversionMethodOption( $token_repository, $method_factory );
$this->set_option( new ImagesQualityOption() );
$this->set_option( new OutputFormatsOption( $token_repository, $format_factory, $conversion_method ) );
$this->set_option( new SupportedDirectoriesOption( $directory_factory ) );
$this->set_option( new ImageResizeOption( $token_repository ) );
$this->set_option( new AutoConversionOption() );
$this->set_option( new AccessTokenOption( $token_repository ) );
$this->set_option( new SupportedExtensionsOption() );
$this->set_option( $conversion_method );
$this->set_option( new LoaderTypeOption() );
$this->set_option( new RewriteInheritanceOption() );
$this->set_option( new ExcludedDirectoriesOption() );
$this->set_option( new ExtraFeaturesOption() );
$this->set_option( new MediaStatsOption() );
$this->set_option( new CloudflareZoneIdOption() );
$this->set_option( new CloudflareApiTokenOption() );
}
/**
* @param string|null $form_name .
*
* @return OptionInterface[]
*/
public function get_options( string $form_name = null ): array {
$options = [];
foreach ( $this->options as $option ) {
if ( ( $form_name === null ) || ( $form_name === $option->get_form_name() ) ) {
$options[] = $option;
}
}
return apply_filters( 'webpc_settings_options', $options );
}
/**
* @param string $option_name .
*
* @return OptionInterface|null
*/
public function get_option( string $option_name ) {
$options = $this->get_options();
foreach ( $options as $option ) {
if ( $option->get_name() === $option_name ) {
return $option;
}
}
return null;
}
/**
* @param OptionInterface $new_option .
*
* @return void
*/
private function set_option( OptionInterface $new_option ) {
foreach ( $this->options as $option_index => $option ) {
if ( $option->get_name() === $new_option->get_name() ) {
$this->options[ $option_index ] = $new_option;
return;
}
}
$this->options[] = $new_option;
}
}

View File

@ -0,0 +1,164 @@
<?php
namespace WebpConverter\Settings\Option;
use WebpConverter\Conversion\Format\AvifFormat;
use WebpConverter\Conversion\Format\FormatFactory;
use WebpConverter\Conversion\Format\WebpFormat;
use WebpConverter\Repository\TokenRepository;
/**
* {@inheritdoc}
*/
class OutputFormatsOption extends OptionAbstract {
const OPTION_NAME = 'output_formats';
/**
* @var TokenRepository
*/
private $token_repository;
/**
* @var ConversionMethodOption
*/
private $conversion_method_option;
/**
* @var FormatFactory
*/
private $format_factory;
public function __construct( TokenRepository $token_repository, FormatFactory $format_factory, ConversionMethodOption $conversion_method_option ) {
$this->token_repository = $token_repository;
$this->conversion_method_option = $conversion_method_option;
$this->format_factory = $format_factory;
}
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_BASIC;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_CHECKBOX;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Supported output formats', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_notice_lines() {
$notice = [
__( 'The AVIF format is the successor to the WebP format. Images converted to the AVIF format weigh about 50% less than images converted only to the WebP format, while maintaining better image quality.', 'webp-converter-for-media' ),
];
if ( $this->token_repository->get_token()->get_token_value() === null ) {
$notice[] = sprintf(
/* translators: %1$s: open anchor tag, %2$s: close anchor tag */
__( '%1$sUpgrade to PRO%2$s', 'webp-converter-for-media' ),
'<a href="https://url.mattplugins.com/converter-field-output-formats-info" target="_blank">',
' <span class="dashicons dashicons-external"></span></a>'
);
}
return $notice;
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
return $this->format_factory->get_formats();
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_disabled_values( array $settings ): array {
$method = $settings[ ConversionMethodOption::OPTION_NAME ] ?? null;
if ( ! $method || in_array( $method, $this->conversion_method_option->get_disabled_values( $settings ) ) ) {
$method = $this->conversion_method_option->get_default_value( $settings );
}
$formats = $this->format_factory->get_formats();
$formats_available = $this->format_factory->get_available_formats( $method );
return array_keys( array_diff( $formats, $formats_available ) );
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_default_value( array $settings = null ): array {
$method = $settings[ ConversionMethodOption::OPTION_NAME ] ?? null;
if ( ! $method ) {
$method = $this->conversion_method_option->get_default_value( $settings );
}
$formats = array_keys( $this->format_factory->get_available_formats( $method ) );
return ( in_array( WebpFormat::FORMAT_EXTENSION, $formats ) ) ? [ WebpFormat::FORMAT_EXTENSION ] : [];
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ) {
$valid_values = [];
if ( ! $current_value ) {
return $valid_values;
}
foreach ( $current_value as $option_value ) {
if ( array_key_exists( $option_value, $available_values ?: [] )
&& ! in_array( $option_value, $disabled_values ?: [] ) ) {
$valid_values[] = $option_value;
}
}
return $valid_values;
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ) {
$values = [ WebpFormat::FORMAT_EXTENSION, AvifFormat::FORMAT_EXTENSION ];
return $this->validate_value(
$current_value,
array_combine( $values, $values )
);
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_debug_value( array $settings ): array {
return [ WebpFormat::FORMAT_EXTENSION, AvifFormat::FORMAT_EXTENSION ];
}
}

View File

@ -0,0 +1,85 @@
<?php
namespace WebpConverter\Settings\Option;
/**
* {@inheritdoc}
*/
class RewriteInheritanceOption extends OptionAbstract {
const OPTION_NAME = 'rewrite_inherit_disabled';
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_ADVANCED;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_TOGGLE;
}
/**
* {@inheritdoc}
*/
public function get_label() {
return null;
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
return sprintf(
'%1$s (%2$s)',
__( 'Disable rewrite inheritance in .htaccess files', 'webp-converter-for-media' ),
__( 'use if you have a problem with, e.g., loading CSS or JS files', 'webp-converter-for-media' )
);
}
/**
* {@inheritdoc}
*/
public function get_available_values( array $settings ) {
return null;
}
/**
* {@inheritdoc}
*/
public function get_default_value( array $settings = null ): string {
$features = ( $settings ) ? $settings[ ExtraFeaturesOption::OPTION_NAME ] : [];
if ( in_array( ExtraFeaturesOption::OPTION_VALUE_REWRITE_INHERIT, $features ) ) {
return 'yes';
} elseif ( strpos( $_SERVER['DOCUMENT_ROOT'] ?? '', '/home/strato/' ) === 0 ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
return 'yes'; /* support for Strato AG */
}
return '';
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ): string {
return ( $current_value === 'yes' ) ? 'yes' : '';
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ): string {
return $this->validate_value( $current_value );
}
}

View File

@ -0,0 +1,113 @@
<?php
namespace WebpConverter\Settings\Option;
use WebpConverter\Conversion\Directory\DirectoryFactory;
/**
* {@inheritdoc}
*/
class SupportedDirectoriesOption extends OptionAbstract {
const OPTION_NAME = 'dirs';
/**
* @var DirectoryFactory
*/
private $directory_factory;
public function __construct( DirectoryFactory $directory_factory ) {
$this->directory_factory = $directory_factory;
}
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_BASIC;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_CHECKBOX;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Supported directories', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
return __( 'Files from these directories will be converted to output formats.', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
return $this->directory_factory->get_directories();
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_default_value( array $settings = null ): array {
return [ 'uploads' ];
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ) {
$valid_values = [];
if ( ! $current_value ) {
return $valid_values;
}
foreach ( $current_value as $option_value ) {
if ( array_key_exists( $option_value, $available_values ?: [] )
&& ! in_array( $option_value, $disabled_values ?: [] ) ) {
$valid_values[] = $option_value;
}
}
return $valid_values;
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ) {
return $this->validate_value(
$current_value,
$this->get_available_values( [] )
);
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_debug_value( array $settings ): array {
return [ 'uploads' ];
}
}

View File

@ -0,0 +1,116 @@
<?php
namespace WebpConverter\Settings\Option;
/**
* {@inheritdoc}
*/
class SupportedExtensionsOption extends OptionAbstract {
const OPTION_NAME = 'extensions';
/**
* {@inheritdoc}
*/
public function get_name(): string {
return self::OPTION_NAME;
}
/**
* {@inheritdoc}
*/
public function get_form_name(): string {
return OptionAbstract::FORM_TYPE_ADVANCED;
}
/**
* {@inheritdoc}
*/
public function get_type(): string {
return OptionAbstract::OPTION_TYPE_CHECKBOX;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Supported files extensions', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_info(): string {
return __( 'Files from supported directories that will be converted to output formats.', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_available_values( array $settings ): array {
return [
'jpg' => '.jpg / .jpeg',
'png' => '.png',
'gif' => '.gif',
'webp' => sprintf(
/* translators: %s: file extension */
__( '%s (converting to AVIF only)', 'webp-converter-for-media' ),
'.webp'
),
];
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_default_value( array $settings = null ): array {
return [ 'jpg', 'jpeg', 'png', 'webp' ];
}
/**
* {@inheritdoc}
*/
public function validate_value( $current_value, array $available_values = null, array $disabled_values = null ) {
$valid_values = [];
if ( ! $current_value ) {
return $valid_values;
}
foreach ( $current_value as $option_value ) {
if ( array_key_exists( $option_value, $available_values ?: [] )
&& ! in_array( $option_value, $disabled_values ?: [] ) ) {
$valid_values[] = $option_value;
}
}
if ( in_array( 'jpg', $current_value ) ) {
$valid_values[] = 'jpeg';
}
return array_unique( $valid_values );
}
/**
* {@inheritdoc}
*/
public function sanitize_value( $current_value ) {
$values = [ 'jpg', 'jpeg', 'png', 'gif', 'webp', 'png2' ];
return $this->validate_value(
$current_value,
array_combine( $values, $values )
);
}
/**
* {@inheritdoc}
*
* @return string[]
*/
public function get_debug_value( array $settings ): array {
return [ 'png2', 'png' ];
}
}

View File

@ -0,0 +1,97 @@
<?php
namespace WebpConverter\Settings;
use WebpConverter\Conversion\Directory\DirectoryFactory;
use WebpConverter\Conversion\Format\FormatFactory;
use WebpConverter\Conversion\Method\MethodFactory;
use WebpConverter\Repository\TokenRepository;
use WebpConverter\Service\OptionsAccessManager;
use WebpConverter\Settings\Option\OptionIntegrator;
use WebpConverter\Settings\Option\OptionsAggregator;
/**
* Allows to integration with plugin settings by providing list of settings fields and saved values.
*/
class OptionsManager {
/**
* @var OptionsAggregator
*/
private $options_aggregator;
public function __construct(
TokenRepository $token_repository,
MethodFactory $method_factory,
FormatFactory $format_factory,
DirectoryFactory $directory_factory
) {
$this->options_aggregator = new OptionsAggregator( $token_repository, $method_factory, $format_factory, $directory_factory );
}
/**
* @param string|null $form_name .
* @param bool $is_debug Is debugging?
* @param mixed[]|null $posted_settings Settings submitted in form.
*
* @return mixed[] Options of plugin settings.
*/
public function get_options( string $form_name = null, bool $is_debug = false, array $posted_settings = null ): array {
$is_save = ( $posted_settings !== null );
$settings = ( $is_save ) ? $posted_settings : OptionsAccessManager::get_option( SettingsManager::SETTINGS_OPTION, [] );
$options = [];
foreach ( $this->options_aggregator->get_options( $form_name ) as $option_object ) {
$options[] = ( new OptionIntegrator( $option_object ) )->get_option_data( $settings, $is_debug, $is_save );
}
return $options;
}
/**
* @param bool $is_debug Is debugging?
*
* @return mixed[] Values of plugin settings.
*/
public function get_values( bool $is_debug = false ): array {
$settings = OptionsAccessManager::get_option( SettingsManager::SETTINGS_OPTION, [] );
$values = [];
foreach ( $this->options_aggregator->get_options() as $option_object ) {
$values[ $option_object->get_name() ] = $option_object->sanitize_value(
( ! $is_debug )
? ( $settings[ $option_object->get_name() ] ?? $option_object->get_default_value( $settings ) )
: $option_object->get_debug_value( $settings )
);
}
return $values;
}
/**
* @return mixed[] Values of plugin settings.
*/
public function get_public_values(): array {
$settings = $this->get_values();
$values = [];
foreach ( $this->options_aggregator->get_options() as $option_object ) {
$values[ $option_object->get_name() ] = $option_object->get_public_value(
$settings[ $option_object->get_name() ]
);
}
return $values;
}
/**
* @param mixed[]|null $posted_settings Settings submitted in form.
* @param string|null $form_name .
*
* @return mixed[] Values of plugin settings.
*/
public function get_validated_values( array $posted_settings = null, string $form_name = null ): array {
$values = [];
foreach ( $this->get_options( $form_name, false, $posted_settings ) as $option ) {
$values[ $option['name'] ] = $option['value'];
}
return $values;
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace WebpConverter\Settings\Page;
use WebpConverter\Settings\Option\OptionAbstract;
/**
* {@inheritdoc}
*/
class AdvancedSettingsPage extends GeneralSettingsPage {
const PAGE_SLUG = 'advanced';
/**
* {@inheritdoc}
*/
public function get_slug(): string {
return self::PAGE_SLUG;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Advanced Settings', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_template_vars(): array {
return array_merge(
parent::get_template_vars(),
[
'form_options' => $this->plugin_data->get_plugin_options( OptionAbstract::FORM_TYPE_ADVANCED ),
'form_input_value' => OptionAbstract::FORM_TYPE_ADVANCED,
]
);
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace WebpConverter\Settings\Page;
/**
* {@inheritdoc}
*/
class BulkOptimizationPage extends GeneralSettingsPage {
/**
* {@inheritdoc}
*/
public function get_slug() {
return null;
}
/**
* {@inheritdoc}
*/
public function get_menu_parent(): string {
return PageIntegrator::UPLOAD_MENU_PAGE;
}
/**
* {@inheritdoc}
*/
public function get_menu_url() {
if ( ( $_GET['page'] ?? '' ) !== PageIntegrator::UPLOAD_MENU_PAGE ) { // phpcs:ignore WordPress.Security
return null;
}
return admin_url( 'upload.php?page=' . PageIntegrator::UPLOAD_MENU_PAGE );
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Bulk Optimization', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_template_vars(): array {
return array_merge(
parent::get_template_vars(),
[
'form_options' => null,
'form_input_value' => null,
]
);
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace WebpConverter\Settings\Page;
use WebpConverter\Settings\Option\OptionAbstract;
/**
* {@inheritdoc}
*/
class CdnSettingsPage extends GeneralSettingsPage {
const PAGE_SLUG = 'cdn';
/**
* {@inheritdoc}
*/
public function get_slug(): string {
return self::PAGE_SLUG;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'CDN Settings', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_template_vars(): array {
return array_merge(
parent::get_template_vars(),
[
'form_options' => $this->plugin_data->get_plugin_options( OptionAbstract::FORM_TYPE_CDN ),
'form_input_value' => OptionAbstract::FORM_TYPE_CDN,
'api_paths_url' => null,
'api_paths_nonce' => null,
'api_regenerate_url' => null,
'api_regenerate_nonce' => null,
]
);
}
}

View File

@ -0,0 +1,125 @@
<?php
namespace WebpConverter\Settings\Page;
use WebpConverter\Error\Detector\RewritesErrorsDetector;
use WebpConverter\Loader\LoaderAbstract;
use WebpConverter\PluginData;
use WebpConverter\PluginInfo;
use WebpConverter\Service\FileLoader;
/**
* {@inheritdoc}
*/
class DebugPage extends PageAbstract {
const PAGE_SLUG = 'debug';
const PAGE_VIEW_PATH = 'views/settings-debug.php';
/**
* @var PluginInfo
*/
private $plugin_info;
/**
* @var PluginData
*/
private $plugin_data;
/**
* @var FileLoader
*/
private $file_loader;
public function __construct(
PluginInfo $plugin_info,
PluginData $plugin_data,
FileLoader $file_loader = null
) {
$this->plugin_info = $plugin_info;
$this->plugin_data = $plugin_data;
$this->file_loader = $file_loader ?: new FileLoader();
}
/**
* {@inheritdoc}
*/
public function get_slug(): string {
return self::PAGE_SLUG;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'Help Center', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_template_path(): string {
return self::PAGE_VIEW_PATH;
}
/**
* {@inheritdoc}
*/
public function get_template_vars(): array {
$uploads_url = apply_filters( 'webpc_dir_url', '', 'uploads' );
$uploads_path = apply_filters( 'webpc_dir_path', '', 'uploads' );
$ver_param = uniqid();
$errors_messages = apply_filters( 'webpc_server_errors_messages', [] );
$errors_codes = apply_filters( 'webpc_server_errors', [] );
do_action( LoaderAbstract::ACTION_NAME, true, true );
return [
'logo_url' => $this->plugin_info->get_plugin_directory_url() . 'assets/img/logo-headline.png',
'size_png_path' => $this->file_loader->get_file_size_by_path(
$uploads_path . RewritesErrorsDetector::PATH_OUTPUT_FILE_PNG
),
'size_png2_path' => $this->file_loader->get_file_size_by_path(
$uploads_path . RewritesErrorsDetector::PATH_OUTPUT_FILE_PNG2
),
'size_png_url' => $this->file_loader->get_file_size_by_url(
$uploads_url . RewritesErrorsDetector::PATH_OUTPUT_FILE_PNG,
false,
$ver_param
),
'size_png2_url' => $this->file_loader->get_file_size_by_url(
$uploads_url . RewritesErrorsDetector::PATH_OUTPUT_FILE_PNG2,
false,
$ver_param
),
'size_png_as_webp_url' => $this->file_loader->get_file_size_by_url(
$uploads_url . RewritesErrorsDetector::PATH_OUTPUT_FILE_PNG,
true,
$ver_param
),
'size_png2_as_webp_url' => $this->file_loader->get_file_size_by_url(
$uploads_url . RewritesErrorsDetector::PATH_OUTPUT_FILE_PNG2,
true,
$ver_param
),
'plugin_settings' => $this->plugin_data->get_public_settings(),
'url_debug_page' => PageIntegrator::get_settings_page_url( self::PAGE_SLUG ),
'errors_messages' => $errors_messages,
'errors_codes' => $errors_codes,
];
}
/**
* {@inheritdoc}
*/
public function do_action_before_load() {
}
/**
* {@inheritdoc}
*/
public function do_action_after_load() {
do_action( LoaderAbstract::ACTION_NAME, true );
}
}

View File

@ -0,0 +1,149 @@
<?php
namespace WebpConverter\Settings\Page;
use WebpConverter\Conversion\Cron\CronEventGenerator;
use WebpConverter\Conversion\Endpoint\FilesStatsEndpoint;
use WebpConverter\Conversion\Endpoint\PathsEndpoint;
use WebpConverter\Conversion\Endpoint\RegenerateEndpoint;
use WebpConverter\Conversion\Format\FormatFactory;
use WebpConverter\Loader\LoaderAbstract;
use WebpConverter\PluginData;
use WebpConverter\PluginInfo;
use WebpConverter\Repository\TokenRepository;
use WebpConverter\Settings\Option\OptionAbstract;
use WebpConverter\Settings\SettingsManager;
/**
* {@inheritdoc}
*/
class GeneralSettingsPage extends PageAbstract {
const PAGE_VIEW_PATH = 'views/settings.php';
/**
* @var PluginInfo
*/
private $plugin_info;
/**
* @var PluginData
*/
protected $plugin_data;
/**
* @var TokenRepository
*/
private $token_repository;
/**
* @var FormatFactory
*/
private $format_factory;
public function __construct(
PluginInfo $plugin_info,
PluginData $plugin_data,
TokenRepository $token_repository,
FormatFactory $format_factory
) {
$this->plugin_info = $plugin_info;
$this->plugin_data = $plugin_data;
$this->token_repository = $token_repository;
$this->format_factory = $format_factory;
}
/**
* {@inheritdoc}
*/
public function get_slug() {
return null;
}
/**
* {@inheritdoc}
*/
public function get_label(): string {
return __( 'General Settings', 'webp-converter-for-media' );
}
/**
* {@inheritdoc}
*/
public function get_template_path(): string {
return self::PAGE_VIEW_PATH;
}
/**
* {@inheritdoc}
*/
public function get_template_vars(): array {
$token = $this->token_repository->get_token();
return [
'logo_url' => $this->plugin_info->get_plugin_directory_url() . 'assets/img/logo-headline.png',
'author_image_url' => $this->plugin_info->get_plugin_directory_url() . 'assets/img/author.png',
'form_options' => $this->plugin_data->get_plugin_options( OptionAbstract::FORM_TYPE_BASIC ),
'form_sidebar_options' => $this->plugin_data->get_plugin_options( OptionAbstract::FORM_TYPE_SIDEBAR ),
'form_input_name' => SettingsManager::FORM_TYPE_PARAM_KEY,
'form_input_value' => OptionAbstract::FORM_TYPE_BASIC,
'form_sidebar_input_value' => OptionAbstract::FORM_TYPE_SIDEBAR,
'nonce_input_name' => SettingsManager::NONCE_PARAM_KEY,
'nonce_input_value' => wp_create_nonce( SettingsManager::NONCE_PARAM_VALUE ),
'token_valid_status' => $token->get_valid_status(),
'token_active_status' => $token->is_active(),
'api_paths_url' => PathsEndpoint::get_route_url(),
'api_paths_nonce' => PathsEndpoint::get_route_nonce(),
'api_regenerate_url' => RegenerateEndpoint::get_route_url(),
'api_regenerate_nonce' => RegenerateEndpoint::get_route_nonce(),
'api_stats_url' => FilesStatsEndpoint::get_route_url(),
'api_stats_nonce' => FilesStatsEndpoint::get_route_nonce(),
'url_debug_page' => PageIntegrator::get_settings_page_url( DebugPage::PAGE_SLUG ),
'output_formats' => [
'webp' => [
'label' => 'WebP',
'desc' => ( ! $token->get_valid_status() )
? __( 'available in the free version', 'webp-converter-for-media' )
: null,
],
'avif' => [
'label' => 'AVIF',
'desc' => ( ! $token->get_valid_status() )
? sprintf(
/* translators: %1$s: open anchor tag, %2$s: close anchor tag */
__( 'available in %1$sthe PRO version%2$s', 'webp-converter-for-media' ),
'<a href="https://url.mattplugins.com/converter-regeneration-widget-avif-upgrade" target="_blank">',
'</a>'
)
: null,
],
],
'errors_messages' => apply_filters( 'webpc_server_errors_messages', [] ),
'errors_codes' => apply_filters( 'webpc_server_errors', [] ),
];
}
/**
* {@inheritdoc}
*/
public function do_action_before_load() {
$post_data = $_POST; // phpcs:ignore WordPress.Security.NonceVerification.Missing
if ( isset( $post_data[ SettingsManager::FORM_TYPE_PARAM_KEY ] )
&& wp_verify_nonce( $post_data[ SettingsManager::NONCE_PARAM_KEY ] ?? '', SettingsManager::NONCE_PARAM_VALUE ) ) {
( new SettingsManager( $this->plugin_data, $this->token_repository ) )->save_settings( $post_data );
}
do_action( LoaderAbstract::ACTION_NAME, true );
wp_clear_scheduled_hook( CronEventGenerator::CRON_PATHS_ACTION );
$this->format_factory->reset_available_formats();
}
/**
* {@inheritdoc}
*/
public function do_action_after_load() {
do_action( LoaderAbstract::ACTION_NAME, true );
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace WebpConverter\Settings\Page;
/**
* Abstract class for class that supports tab in plugin settings page.
*/
abstract class PageAbstract implements PageInterface {
/**
* {@inheritdoc}
*/
public function get_menu_parent(): string {
return PageIntegrator::SETTINGS_MENU_PAGE;
}
/**
* {@inheritdoc}
*/
public function get_menu_url() {
return PageIntegrator::get_settings_page_url( $this->get_slug() );
}
}

View File

@ -0,0 +1,185 @@
<?php
namespace WebpConverter\Settings\Page;
use WebpConverter\HookableInterface;
use WebpConverter\Notice\NoticeIntegrator;
use WebpConverter\Notice\WelcomeNotice;
use WebpConverter\PluginInfo;
use WebpConverter\Service\ViewLoader;
/**
* Adds plugin settings page in admin panel.
*/
class PageIntegrator implements HookableInterface {
const SETTINGS_MENU_PAGE = 'webpc_admin_page';
const UPLOAD_MENU_PAGE = 'webpc_optimization_page';
/**
* @var PluginInfo
*/
private $plugin_info;
/**
* @var ViewLoader
*/
private $view_loader;
public function __construct( PluginInfo $plugin_info, ViewLoader $view_loader = null ) {
$this->plugin_info = $plugin_info;
$this->view_loader = $view_loader ?: new ViewLoader( $plugin_info );
}
/**
* Objects of supported plugin settings pages.
*
* @var PageInterface[]
*/
private $pages = [];
/**
* {@inheritdoc}
*/
public function init_hooks() {
add_action( 'admin_menu', [ $this, 'add_settings_page_for_admin' ] );
add_action( 'network_admin_menu', [ $this, 'add_settings_page_for_network' ] );
}
/**
* @return PageInterface|null
*/
private function get_current_page() {
$page_name = $_GET['page'] ?? null; // phpcs:ignore WordPress.Security
$tab_name = $_GET['action'] ?? null; // phpcs:ignore WordPress.Security
foreach ( $this->pages as $page ) {
if ( ( $page->get_menu_parent() === $page_name ) && ( $page->get_slug() === $tab_name ) ) {
return $page;
}
}
return null;
}
/**
* Sets integration for page.
*
* @param PageInterface $page .
*
* @return self
*/
public function set_page_integration( PageInterface $page ) {
$this->pages[] = $page;
return $this;
}
/**
* Returns URL of plugin settings page.
*
* @param string|null $action .
*
* @return string
*/
public static function get_settings_page_url( string $action = null ): string {
if ( ! is_multisite() ) {
$page_url = admin_url( 'options-general.php?page=' . self::SETTINGS_MENU_PAGE );
} else {
$page_url = network_admin_url( 'settings.php?page=' . self::SETTINGS_MENU_PAGE );
}
if ( $action !== null ) {
$page_url .= '&action=' . $action;
}
return $page_url;
}
/**
* Adds settings page to menu for non-multisite websites.
*
* @return void
* @internal
*/
public function add_settings_page_for_admin() {
if ( is_multisite() ) {
return;
}
$this->add_settings_page( 'options-general.php', self::SETTINGS_MENU_PAGE );
$this->add_settings_page( 'upload.php', self::UPLOAD_MENU_PAGE );
}
/**
* Adds settings page to menu for multisite websites.
*
* @return void
* @internal
*/
public function add_settings_page_for_network() {
$this->add_settings_page( 'settings.php', self::SETTINGS_MENU_PAGE );
}
/**
* Creates plugin settings page in WordPress Admin Dashboard.
*
* @param string $parent_page Parent menu page.
* @param string $menu_page .
*
* @return void
*/
private function add_settings_page( string $parent_page, string $menu_page ) {
$page = add_submenu_page(
$parent_page,
'Converter for Media',
'Converter for Media',
'manage_options',
$menu_page,
[ $this, 'load_plugin_page' ]
);
add_action( 'load-' . $page, [ $this, 'load_scripts_for_page' ] );
}
/**
* @return void
* @internal
*/
public function load_plugin_page() {
$page = $this->get_current_page();
if ( $page === null ) {
return;
}
$page->do_action_before_load();
do_action( 'webpc_settings_page_loaded', $page->get_menu_parent(), $page->get_slug() );
$this->view_loader->load_view(
$page->get_template_path(),
array_merge(
$page->get_template_vars(),
[
'menu_items' => array_map(
function ( PageInterface $settings_page ) use ( $page ) {
return [
'url' => $settings_page->get_menu_url(),
'title' => $settings_page->get_label(),
'is_active' => ( $settings_page === $page ),
];
},
$this->pages
),
]
)
);
$page->do_action_after_load();
}
/**
* Loads assets on plugin settings page.
*
* @return void
* @internal
*/
public function load_scripts_for_page() {
( new NoticeIntegrator( $this->plugin_info, new WelcomeNotice() ) )->set_disable_value();
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace WebpConverter\Settings\Page;
/**
* Interface for class that supports tab in plugin settings page.
*/
interface PageInterface {
/**
* @return string|null
*/
public function get_slug();
/**
* @return string
*/
public function get_menu_parent(): string;
/**
* @return string|null
*/
public function get_menu_url();
/**
* @return string
*/
public function get_label(): string;
/**
* @return string
*/
public function get_template_path(): string;
/**
* @return mixed[]
*/
public function get_template_vars(): array;
/**
* @return void
*/
public function do_action_before_load();
/**
* @return void
*/
public function do_action_after_load();
}

View File

@ -0,0 +1,79 @@
<?php
namespace WebpConverter\Settings;
use WebpConverter\Conversion\Format\AvifFormat;
use WebpConverter\Conversion\Format\WebpFormat;
use WebpConverter\Conversion\Method\RemoteMethod;
use WebpConverter\PluginData;
use WebpConverter\Repository\TokenRepository;
use WebpConverter\Service\OptionsAccessManager;
use WebpConverter\Service\TokenValidator;
use WebpConverter\Settings\Option\AccessTokenOption;
use WebpConverter\Settings\Option\ConversionMethodOption;
use WebpConverter\Settings\Option\OutputFormatsOption;
/**
* Supports saving plugin settings on plugin settings page.
*/
class SettingsManager {
const SETTINGS_OPTION = 'webpc_settings';
const FORM_TYPE_PARAM_KEY = 'webpc_form_type';
const NONCE_PARAM_KEY = 'webpc_nonce';
const NONCE_PARAM_VALUE = 'webpc-save';
/**
* @var PluginData
*/
private $plugin_data;
/**
* @var TokenValidator
*/
private $token_validator;
public function __construct(
PluginData $plugin_data,
TokenRepository $token_repository,
TokenValidator $token_validator = null
) {
$this->plugin_data = $plugin_data;
$this->token_validator = $token_validator ?: new TokenValidator( $token_repository );
}
/**
* @param mixed[]|null $post_data .
*
* @return void
*/
public function save_settings( array $post_data = null ) {
$previous_settings = $this->plugin_data->get_plugin_settings();
$posted_settings = ( $post_data !== null )
? $this->plugin_data->validate_plugin_settings( $post_data, $post_data[ self::FORM_TYPE_PARAM_KEY ] ?? null )
: [];
$plugin_settings = array_merge( $previous_settings, $posted_settings );
$token = $this->token_validator->validate_token( $plugin_settings[ AccessTokenOption::OPTION_NAME ] );
if ( $token->get_valid_status() ) {
$plugin_settings[ ConversionMethodOption::OPTION_NAME ] = RemoteMethod::METHOD_NAME;
if ( isset( $posted_settings[ AccessTokenOption::OPTION_NAME ] ) || ! $plugin_settings[ OutputFormatsOption::OPTION_NAME ] ) {
$plugin_settings[ OutputFormatsOption::OPTION_NAME ] = [
AvifFormat::FORMAT_EXTENSION,
WebpFormat::FORMAT_EXTENSION,
];
}
} elseif ( ( $plugin_settings[ ConversionMethodOption::OPTION_NAME ] === RemoteMethod::METHOD_NAME )
&& ! $plugin_settings[ AccessTokenOption::OPTION_NAME ] ) {
$plugin_settings[ ConversionMethodOption::OPTION_NAME ] = '';
}
$plugin_settings = $this->plugin_data->validate_plugin_settings( $plugin_settings );
OptionsAccessManager::update_option( self::SETTINGS_OPTION, $plugin_settings );
$this->plugin_data->invalidate_plugin_settings();
do_action( 'webpc_settings_updated', $plugin_settings, $previous_settings );
}
}