This commit is contained in:
User A0264400
2026-04-19 15:38:03 +03:00
parent 7b24f58aeb
commit bbfa5766ae
1669 changed files with 894 additions and 177073 deletions

View File

@@ -0,0 +1,95 @@
<?php
/**
* Activator for the Robin image optimizer
*
* @see Factory600_Activator
* @version 1.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
class WIO_Activation extends Wbcr_Factory600_Activator {
/**
* Runs activation actions.
*
* @since 1.0.0
* @throws \Exception
*/
public function activate() {
WRIO_Plugin::app()->logger->info( 'Parent plugin start installation!' );
WRIO_Plugin::app()->updatePopulateOption( 'backup_origin_images', 1 );
WRIO_Plugin::app()->updatePopulateOption( 'save_exif_data', 1 );
// Enable auto-optimize on upload by default for new installations only.
if ( 0 === $this->get_plugin_version_in_db() ) {
WRIO_Plugin::app()->updatePopulateOption( 'auto_optimize_when_upload', 1 );
WRIO_Plugin::app()->updatePopulateOption( 'convert_webp_format', 1 );
}
if ( function_exists( 'wrio_is_license_activate' ) && wrio_is_license_activate() ) {
WRIO_Plugin::app()->logger->info( 'Premium plugin start installation!' );
require_once WRIO_PLUGIN_DIR . '/libs/addons/robin-image-optimizer-premium.php';
wrio_premium_activate();
WRIO_Plugin::app()->logger->info( 'Premium plugin installation complete!' );
}
$db_version = RIO_Process_Queue::get_db_version();
$plugin_version_in_db = $this->get_plugin_version_in_db();
$current_plugin_version = $this->plugin->getPluginVersion();
$create_table_log_message = "Plugin installation: try create plugin tables.\r\n";
$create_table_log_message .= "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t-DB Version: {$db_version}\r\n";
$create_table_log_message .= "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t-Plugin Version in DB: {$plugin_version_in_db}\r\n";
$create_table_log_message .= "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t-Current Plugin Version: {$current_plugin_version}";
WRIO_Plugin::app()->logger->info( $create_table_log_message );
RIO_Process_Queue::try_create_plugin_tables();
WBCR\Factory_Templates_759\Helpers::flushPageCache();
WRIO_Plugin::app()->logger->info( 'Parent plugin installation complete!' );
}
/**
* Get previous plugin version
*
* @since 1.3.8
* @return number
*/
public function get_plugin_version_in_db() {
if ( WRIO_Plugin::app()->isNetworkActive() ) {
return get_site_option( WRIO_Plugin::app()->getOptionName( 'plugin_version' ), 0 );
}
return get_option( WRIO_Plugin::app()->getOptionName( 'plugin_version' ), 0 );
}
/**
* Runs activation actions.
*
* @since 1.0.0
*/
public function deactivate() {
WRIO_Plugin::app()->logger->info( 'Parent plugin start deactivation!' );
if ( class_exists( 'WRIO_Cron' ) ) {
WRIO_Cron::stop();
}
if ( function_exists( 'wrio_is_license_activate' ) && wrio_is_license_activate() ) {
WRIO_Plugin::app()->logger->info( 'Premium plugin start deactivation!' );
require_once WRIO_PLUGIN_DIR . '/libs/addons/robin-image-optimizer-premium.php';
wrio_premium_deactivate();
WRIO_Plugin::app()->logger->info( 'Premium plugin deactivation complete!' );
}
WRIO_Plugin::app()->logger->info( 'Parent plugin deactivation complete!' );
}
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* Back-up related filters.
*
* @version 1.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* AJAX обработчик восстановления из резервной копии
*/
add_action(
'wp_ajax_wio_restore_backup',
function () {
check_admin_referer( 'wio-iph' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( - 1 );
}
$max_process_per_request = 25;
// $blog_id = WRIO_Plugin::app()->request->post( 'blog_id', null, true );
/*
if ( $blog_id !== null ) {
switch_to_blog( $blog_id );
}*/
// Total number of remained images to restore
$remane_count = 0;
$total = 0;
$filter_results = apply_filters( 'wbcr/rio/backup/restore_filter', $max_process_per_request );
if ( isset( $filter_results['remane'] ) ) {
$remane_count += $filter_results['remane'];
}
if ( isset( $filter_results['total'] ) ) {
$total += $filter_results['total'];
}
$media_library = WRIO_Media_Library::get_instance();
$total += $media_library->getOptimizedCount();
$restored_data = $media_library->restoreAllFromBackup( $max_process_per_request );
if ( isset( $restored_data['remain'] ) ) {
$remane_count += $restored_data['remain'];
}
/*
if ( $blog_id !== null ) {
restore_current_blog();
}*/
$restored_data['total'] = $total;
if ( $total > 0 ) {
$restored_data['percent'] = 100 - ( $remane_count * 100 / $total );
} else {
$restored_data['percent'] = 0;
}
// если изображения закончились - посылаем команду завершения
if ( $remane_count <= 0 ) {
$restored_data['end'] = true;
}
wp_send_json( $restored_data );
}
);
/**
* AJAX обработчик очистки папки с бекапами
*/
add_action(
'wp_ajax_wio_clear_backup',
function () {
check_admin_referer( 'wio-iph' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( - 1 );
}
$backup = WIO_Backup::get_instance();
$blogs = WRIO_Plugin::app()->request->post( 'blogs', [], true );
if ( ! empty( $blogs ) ) {
foreach ( $blogs as $blog_id ) {
switch_to_blog( intval( $blog_id ) );
$backup->removeBlogBackupDir();
restore_current_blog();
}
} else {
$backup->removeBackupDir();
}
wp_send_json( true );
}
);

View File

@@ -0,0 +1,2 @@
<?php
// silence is golden

View File

@@ -0,0 +1,31 @@
<?php
/**
* Used to clean-up logs.
*/
add_action(
'wp_ajax_wrio_logs_cleanup',
function () {
check_admin_referer( 'wrio_clean_logs', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( - 1 );
}
if ( ! WRIO_Plugin::app()->logger->clean_up() ) {
wp_send_json_error(
[
'message' => esc_html__( 'Failed to clear logs. Please try again later.', 'robin-image-optimizer' ),
'type' => 'danger',
]
);
}
wp_send_json(
[
'message' => esc_html__( 'Logs cleared successfully.', 'robin-image-optimizer' ),
'type' => 'success',
]
);
}
);

View File

@@ -0,0 +1,171 @@
<?php
/**
* Ajax action to migrate old architecture based on post meta into new table.
*
* @see RIO_Process_Queue for further information.
*
* @version 1.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
add_action( 'wp_ajax_wrio_meta_migrations', 'wbcr_rio_migrate_postmeta_to_process_queue' );
/**
* Migrating postmeta to newly created table.
*
* @since 1.3.0
* @see RIO_Process_Queue as referce for new table.
*/
function wbcr_rio_migrate_postmeta_to_process_queue() {
global $wpdb;
check_admin_referer( 'wrio-meta-migrations' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( - 1 );
}
$error = (int) WRIO_Plugin::app()->request->post( 'error', 0 );
if ( $error ) {
WRIO_Plugin::app()->logger->error( 'Previous migration was not completed due to an error.' );
}
$limit = (int) WRIO_Plugin::app()->request->post( 'limit', 150 );
$processed_items = 0;
WRIO_Plugin::app()->logger->info( 'Start meta migration. Limit ' . $limit );
WRIO_Plugin::app()->logger->memory_usage();
$attachments = wbcr_rio_get_meta_to_migrate();
if ( isset( $attachments->posts ) && ( $attachments_total = count( $attachments->posts ) ) > 0 ) {
if ( $attachments_total < $limit ) {
$limit = $attachments_total;
}
WRIO_Plugin::app()->logger->info( 'Finded ' . $attachments_total . ' attachments for migration.' );
if ( function_exists( 'wp_raise_memory_limit' ) ) {
wp_raise_memory_limit( 'image' );
}
WRIO_Plugin::app()->logger->memory_usage();
/**
* @var WP_Post $attachment
*/
for ( $i = 0; $i < $limit; $i++ ) {
$attachment = $attachments->posts[ $i ];
$post_meta = get_post_custom( $attachment->ID );
$extra_data = new RIO_Attachment_Extra_Data();
$is_backed_up = false;
$original_size = 0;
$final_size = 0;
if ( isset( $post_meta['wio_backuped'][0] ) && $post_meta['wio_backuped'][0] ) {
$is_backed_up = true;
}
if ( isset( $post_meta['wio_thumbnails_count'][0] ) ) {
$extra_data->set_thumbnails_count( intval( $post_meta['wio_thumbnails_count'][0] ) );
}
if ( isset( $post_meta['wio_original_size'][0] ) ) {
$original_size = intval( $post_meta['wio_original_size'][0] );
}
if ( isset( $post_meta['wio_optimized_size'][0] ) ) {
$final_size = intval( $post_meta['wio_optimized_size'][0] );
}
if ( isset( $post_meta['wio_original_main_size'][0] ) ) {
$extra_data->set_original_main_size( intval( $post_meta['wio_original_main_size'][0] ) );
}
if ( isset( $post_meta['wio_error'][0] ) ) {
$extra_data->set_error( 'optimization' );
$extra_data->set_error_msg( $post_meta['wio_error'][0] );
}
$level = 'normal';
if ( isset( $post_meta['wio_optimization_level'][0] ) && ! empty( $post_meta['wio_optimization_level'][0] ) ) {
$level = $post_meta['wio_optimization_level'][0];
}
$data = [
'server_id' => null,
'object_id' => $attachment->ID,
'object_name' => $wpdb->posts,
'item_type' => 'attachment',
'result_status' => ! $final_size ? 'error' : 'success',
'processing_level' => $level,
'is_backed_up' => $is_backed_up,
'original_size' => $original_size,
'final_size' => $final_size,
'original_mime_type' => $attachment->post_mime_type,
'final_mime_type' => $attachment->post_mime_type,
'extra_data' => (string) $extra_data,
'created_at' => time(),
];
$format = [
'%s',
'%d',
'%s',
'%s',
'%s',
'%s',
'%d',
'%d',
'%d',
'%s',
'%s',
'%s',
'%d',
];
$rows_inserted = $wpdb->insert( RIO_Process_Queue::table_name(), $data, $format );
if ( $rows_inserted > 0 ) {
++$processed_items;
$attachment_id = absint( $attachment->ID );
$wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE post_id='{$attachment_id}' AND meta_key LIKE 'wio_%'" );
}
}
$left_items = $attachments_total - $processed_items;
// translators: %s is the number of items left to migrate
$message = sprintf( __( 'left to migrate: %s items', 'robin-image-optimizer' ), $left_items );
$need_more_time = true;
WRIO_Plugin::app()->logger->info( 'Succefull migrated ' . $processed_items . ' items.' );
} else {
WRIO_Plugin::app()->logger->info( 'Succefull migrated all items. Finishing-up...' );
// Assumed to be 2 after 010105.php migration
RIO_Process_Queue::update_db_version( 2 );
$need_more_time = false;
$message = __( 'Finishing-up...', 'robin-image-optimizer' );
}
WRIO_Plugin::app()->logger->memory_usage();
wp_send_json_success(
[
'need_more_time' => $need_more_time,
'message' => $message,
]
);
}

View File

@@ -0,0 +1,28 @@
<?php
/**
* Ajax действие, которое выполняется для смены текущего multisite блога
*
* @version 1.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/*
add_action( 'wp_ajax_wbcr_rio_update_current_blog', function () {
check_ajax_referer( 'update_blog_id', 'wpnonce' );
$blog_id = (int) WRIO_Plugin::app()->request->post( 'current_blog_id' );
$context = sanitize_text_field( WRIO_Plugin::app()->request->post( 'context' ) );
WRIO_Plugin::app()->updatePopulateOption( 'current_blog', $blog_id );
$image_statistics = WIO_OptimizationTools::getImageStatistics( $context );
switch_to_blog( $blog_id );
$statistic_data = $image_statistics->load();
restore_current_blog();
wp_send_json_success( array(
'statistic' => $statistic_data,
) );
} );*/

View File

@@ -0,0 +1,38 @@
<?php
/**
* Ajax действие, которое выполняется при сохранении настроек
*
* @version 1.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* AJAX обработчик массовой сохранения уровня сжатия
*/
add_action(
'wp_ajax_wio_settings_update_level',
function () {
check_admin_referer( 'wio-iph' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( - 1 );
}
$level = sanitize_text_field( $_POST['level'] );
if ( ! $level ) {
die();
}
if ( ! in_array( $level, [ 'normal', 'aggresive', 'ultra' ] ) ) {
die();
}
WRIO_Plugin::app()->updatePopulateOption( 'image_optimization_level', $level );
die();
}
);

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,921 @@
/**
* Styles for the Widget to be displayed in the plugin
*/
@positiveColor: #bbd2a1;
@webpPositiveColor: #8CC152;
@negativeColor: #D2D3D6;
@neutralColor: #828282;
@errorColor: #fb5d49;
@waringColor: #ffb635;
@greyButtonBg: #f3f3f3;
@greyButtonColor: #656565;
@greenButtonBg: #c9deb2;
@greenButtonColor: #586549;
@orangeButtonBg: #fdd599;
@orangeButtonColor: #a57b3c;
#WBCR {
.premium-label(@position: relative, @positionTop:-8px, @positionLeft:-10px, @positionRight:auto) {
display: inline-block;
position: @position;
content: 'PRO';
background: #ff5722;
border-radius: 4px;
color: #fff;
font-size: 10px;
line-height: 1;
font-style: normal;
padding: 4px 6px;
margin-left: 4px;
vertical-align: top;
top: @positionTop;
left: @positionLeft;
right: @positionRight;
z-index: 11;
}
.factory-bootstrap-000 {
select.form-control {
background: #efefef url(data:image/svg+xml;charset=US-ASCII,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22M5%206l5%205%205-5%202%201-7%207-7-7%202-1z%22%20fill%3D%22%23555%22%2F%3E%3C%2Fsvg%3E) no-repeat right 5px top 55% !important;
}
.btn-default.active, .factory-bootstrap-000 .btn-default:active {
text-shadow: none;
color: #fff;
background-color: #33aad5;
-webkit-box-shadow: inset 0 1px 1px #0074a2;
box-shadow: inset 0 1px 3px #0074a2;
border-top: 1px solid #0074a2;
border-bottom: 1px solid #0074a2;
border-left: 1px solid #0074a2;
}
.btn-group > .btn:last-of-type {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
}
.wio-clear {
clear: both;
}
// This code hides tabs custom folders and nextgen gallery
// -----------------------------------------------
#io_folders_statistic-wbcr_clearfy-tab, #io_nextgen_gallery_statistic-wbcr_clearfy-tab {
display: none !important;
}
// Styling tabs on statistics pages
// -----------------------------------------------
.wrio-statistic-nav {
margin: 0;
//box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
background: #efefef;
ul {
margin: 0 0 0 10px;
li {
position: relative;
display: inline-block;
//width: 300px;
margin: 0 5px 0 0;
background: #ffffff;
box-shadow: 0 -2px 0 #eaeaea;
&:hover {
background: #f7f7f7;
}
&.active {
//box-shadow: 0 -2px 0 #c9deb2;
background: #f7f7f7;
border-top: 1px solid #d4d4d4;
border-left: 1px solid #d4d4d4;
border-right: 1px solid #d4d4d4;
border-bottom: 1px solid #f7f7f7;
margin-bottom: -1px;
a {
color: #222;
.wrio-statistic-tab-percent {
border: 2px dashed #8bc34a;
color: #5e8237;
}
}
.dashicons, .dashicons-before:before {
color: #ff8b66;
}
}
.wrio-statistic-tab {
display: block;
padding: 10px 20px 10px 20px;
text-decoration: none;
color: #d4d4d4;
font-size: 22px;
line-height: 2;
&:active, &:focus {
background: 0;
box-shadow: none;
outline: none;
}
.dashicons, .dashicons-before:before {
display: inline-block;
width: 30px;
height: 30px;
font-size: 30px;
line-height: 1.5;
margin-right: 15px;
color: #d4d4d4;
}
.wrio-statistic-tab-percent {
display: inline-block;
width: 42px;
height: 42px;
border-radius: 100px;
border: 2px dashed #e4e4e4;
padding: 5px;
margin-left: 30px;
font-size: 14px;
font-weight: 600;
text-align: center;
color: #bdbdbd;
}
}
.wrio-statistic-tab-premium-label:after {
.premium-label(absolute, 10px, auto, 10px);
}
}
}
}
// Table style. The table is used for optimization log
.wrio-table {
width: 100%;
table-layout: fixed;
box-sizing: border-box;
border-spacing: 3px;
background: #fff;
border-top: 2px dashed #cac9c9;
th, td {
padding: 16px 10px;
text-align: center;
}
th {
background: #f3f3f3;
color: #777777;
box-shadow: 0 1px 0 rgb(216, 216, 216);
&:nth-child(2n+1) {
background: #f9f9f9
}
}
tr.wrio-error {
background-color: #ffe9e9 !important;
}
.wrio-table-spinner {
background: url("../img/quick-start-loader.gif") center center no-repeat;
}
.wrio-table-highlighter {
display: inline-block;
padding: 3px 7px;
background: @greyButtonBg;
}
.wbcr-rio-server-success {
color: @positiveColor;
}
.wbcr-rio-server-error {
color: @errorColor;
}
.wbcr-rio-server-warning {
color: @waringColor;
}
&.wbcr-rio-folders-table {
td:nth-child(3) {
text-align: left;
}
}
}
.wrio-servers {
padding: 20px 20px;
label {
span {
display: block;
font-weight: normal;
font-size: 12px;
color: #b7b2b2;
}
}
#wrio-change-optimization-server {
position: relative;
display: inline-block;
max-width: 400px;
margin-right: 15px;
margin-bottom: 0;
border: 1px solid #d2d0d0;
background-color: #efefef;
}
.wrio-servers-info {
margin: 0 0 0;
padding: 20px;
background: #fff;
}
.wrio-server-status-wrap {
display: inline-block;
margin-top: 8px;
.wrio-server-status {
background: transparent;
color: #fff;
padding: 3px 5px;
border-radius: 4px;
&.wrio-down {
background: #ff5722;
}
&.wrio-stable {
background: #8bc34a;
}
&.wrio-server-check-proccess {
display: inline-block;
height: 10px;
width: 30px;
background: url("../img/quick-start-loader.gif") center no-repeat;
}
}
}
.wrio-premium-user-balance-wrap {
display: inline-block;
margin-top: 8px;
margin-left: 10px;
.wrio-premium-user-balance {
color: #fff;
padding: 3px 5px;
border-radius: 4px;
background: #ffc107;
}
.wrio-premium-user-balance-check-proccess {
display: inline-block;
height: 10px;
width: 30px;
background: url("../img/quick-start-loader.gif") center no-repeat;
}
}
.wrio-premium-user-update-wrap {
display: inline-block;
margin-top: 8px;
margin-left: 10px;
.wrio-premium-user-update {
color: #fff;
padding: 3px 5px;
border-radius: 4px;
background: #ffc107;
}
.wrio-premium-user-update-check-proccess {
display: inline-block;
height: 10px;
width: 30px;
background: url("../img/quick-start-loader.gif") center no-repeat;
}
}
}
.wio-columns {
overflow: hidden;
padding: 15px 0;
counter-reset: cols;
[class^="col-"] {
float: left;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.col-1-3 {
width: 33.333%;
padding-left: 28px;
}
.col-2-3 {
width: 66.666%;
padding-left: 28px
}
.col-1-2 {
width: 50%;
padding: 0 20px;
}
.col-statistics.col-statistics {
width: 60%;
}
.col-chart.col-chart {
width: 40%;
position: relative;
padding: 20px;
font-size: 12px;
text-transform: uppercase;
background: #f1f1f1b3;
color: #abacaf;
font-weight: bold;
border-radius: 5px;
margin-top: 10px;
text-align: left;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
}
}
.wio-col {
float: left;
width: 50%;
box-sizing: border-box;
-webkit-flex-basis: 50%;
-ms-flex-preferred-size: 50%;
flex-basis: 50%;
}
.wio-col {
padding-right: 20px;
}
.wio-col + .wio-col {
padding-right: 0;
padding-left: 50px;
}
.wio-col:target {
animation: wiohello 1s 3 linear backwards;
}
.wio-number-you-optimized {
margin-bottom: 1.35em;
overflow: hidden;
#wio-total-optimized-attachments-pct {
color: @neutralColor;
}
.wio-number {
display: table-cell;
padding-right: 15px;
font-size: 48px;
font-weight: bold;
line-height: 1;
vertical-align: middle;
white-space: nowrap;
color: @neutralColor;
}
.wio-text {
display: table-cell;
vertical-align: middle;
overflow: hidden;
font-size: 12px;
color: @neutralColor;
}
& > p {
display: table;
}
}
.wio-bars {
padding-right: 15px;
}
.wio-bars p {
font-size: 12px;
margin-bottom: 5px;
}
.wio-bars + .wio-number-you-optimized {
border-bottom: 0;
padding-top: 0.85em;
}
.wio-bars + .wio-number-you-optimized p {
color: darken(@positiveColor, 10);
}
.wio-bar-negative {
.wio-progress {
background: @negativeColor;
}
.wio-barnb {
color: darken(@negativeColor, 20);
}
}
.wio-progress {
height: 8px;
transition: width .3s;
/*.wio-bar-negative {
width: 92% !important;
}*/
}
.wio-bar-positive {
.wio-progress {
background: @positiveColor;
}
.wio-barnb {
color: darken(@positiveColor, 10);
}
}
.wio-bar-primary {
.wio-progress {
background: @positiveColor;
}
.wio-barnb {
color: darken(@positiveColor, 10);
}
}
.wio-bar-webp {
.wio-progress {
background: @webpPositiveColor;
}
.wio-barnb {
color: darken(@webpPositiveColor, 10);
}
}
.wio-right-outside-number .wio-barnb {
display: block;
margin-right: -5.25em;
text-align: right;
font-weight: bold;
line-height: .8;
}
/* Doughnut */
.wio-chart {
position: relative;
top: 1px;
display: inline-block;
vertical-align: middle;
}
.wio-chart-container {
position: relative;
display: inline-block;
margin-right: 5px;
}
.wio-chart-container canvas {
display: block;
}
.wio-overview-chart-container {
float: left;
margin-right: 20px;
}
.wio-overview-chart-container-webp {
float: right;
margin-left: 20px;
}
.wio-chart-wrapper {
position: relative;
width: 200px;
height: 200px;
}
.wio-chart-percent {
color: #afafaf;
position: absolute;
font-size: 35px;
font-weight: 600;
left: 50%;
bottom: 167px;
z-index: 100;
transform: translateX(-45%);
-webkit-transform: translateX(-45%);
-ms-transform: translateX(-45%);
}
.wio-chart-percent span {
font-size: 20px;
vertical-align: super;
}
#wio-overview-chart-legend {
overflow: hidden;
}
.wio-doughnut-legend li {
display: inline-block;
position: relative;
margin-bottom: 15px;
border-radius: 5px;
padding: 3px 8px 2px 31px;
font-size: 9px;
cursor: default;
-webkit-transition: background-color 200ms ease-in-out;
-moz-transition: background-color 200ms ease-in-out;
-o-transition: background-color 200ms ease-in-out;
transition: background-color 200ms ease-in-out;
}
.wio-doughnut-legend li span {
display: block;
position: absolute;
left: 0;
top: 0;
width: 25px;
height: 25px;
border-radius: 50%;
}
.wio-optimize-button {
min-width: 180px;
padding: 12px 30px;
background: @greenButtonBg;
color: @greenButtonColor;
border: 0;
box-shadow: none;
font-size: 14px;
text-transform: uppercase !important;
font-weight: bold;
border-radius: 4px;
outline: none;
&:active {
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5);
}
&:disabled {
background: lighten(@greenButtonBg, 10%);
color: lighten(@greenButtonColor, 30%);
}
&.wio-running {
color: @orangeButtonColor;
background: @orangeButtonBg url("../img/Spinner-1s-33px.gif") 10px center no-repeat;
padding-left: 50px;
}
}
.wio-global-optim-phrase {
width: 180px;
padding-top: 20px;
font-size: 14px;
text-align: center;
}
.wio-total-percent, .wio-total-percent-webp {
color: darken(@positiveColor, 20);
}
#wio-start-msg-top, #wio-start-msg-right, #wio-start-msg-complete {
display: none;
}
.wio-text-left {
text-align: left;
}
span.wio-num {
display: inline !important;
position: inherit !important;
}
// WIDGETS SPACE
// -----------------------------------------------
.wio-image-optimize-board {
padding-bottom: 0 !important;
}
.wio-page-statistic {
padding: 20px;
.wio-optimize-statistic {
display: flex;
justify-content: space-between;
}
.wrio-statistic-buttons-wrap {
display: flex;
justify-content: space-between;
}
}
.wio-stat-totals {
padding: 20px 20px;
background: #efefef;
font-weight: bold;
vertical-align: middle;
&__counter {
display: inline-block;
background: #ffffff;
min-width: 30px;
height: 25px;
padding: 2px 5px;
border-radius: 3px;
border: 1px dashed #bdb5b5;
color: #222;
font-weight: normal;
text-align: center;
}
&__loading {
color: #fff;
background: #fff url("../img/quick-start-loader.gif") center no-repeat !important;
background-size: 16px 16px !important;
}
&__totals {
}
&__optimized {
background: #8bc34a;
color: #fff;
}
}
.wrio-optimization-progress {
//margin-top: 30px;
background: none;
padding: 0;
h4 {
font-size: 15px;
font-weight: 700;
}
/*button {
padding: 5px 10px;
border: 0;
font-size: 11px;
text-transform: uppercase !important;
font-weight: bold;
border-radius: 4px;
outline: none;
background: @greyButtonBg;
color: @greyButtonColor;
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
&:active {
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5);
}
&.wbcr-rio-loading {
width: 56px;
font-size: 0;
background: @greyButtonBg url("../img/quick-start-loader.gif") center no-repeat;
}
&.wbcr-rio-selected {
background: #f3efe2;
color: #d8d8d8;
&:active {
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.1);
}
}
}*/
.wbcr-rio-warning-message {
padding: 20px;
background: #efefef;
font-size: 15px;
color: #b7b7b7;
font-style: italic;
}
}
.wio-widget {
padding: 0 !important;
.wio-chart-percent {
font-size: 44px;
line-height: 1;
}
.wio-bars {
width: 60%;
margin-left: 155px;
}
.col-chart.col-chart {
width: 100%;
}
.col-controls {
width: 45%;
padding-left: 5px;
padding-top: 110px
}
.wio-doughnut-legend {
/*padding-top:30px;*/
text-align: left;
}
.wio-widget-bottom {
display: table;
padding-top: 20px !important;
width: 100%;
text-align: right;
}
.wio-widget-bottom li {
display: table-cell;
}
.wio-widget-bottom li:first-child {
text-align: left;
}
}
// FORMS SPACE
// -----------------------------------------------
.factory-checkbox {
&.wrio-checkbox-premium-label:after {
.premium-label();
}
}
.factory-checkbox-disabled {
input, button {
pointer-events: none;
cursor: not-allowed;
opacity: .65;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
box-shadow: none;
}
}
#wrio-webp-options, #wrio-error-log-options {
h3 {
font-size: 14px;
margin: 0 0 10px 0;
font-weight: 600;
color: #565656;
}
.wrio-webp-options-info {
color: #8a8787;
font-size: 12px;
}
ul {
padding-left: 0;
li {
&:after {
content: '';
display: block;
clear: both;;
}
label {
font-weight: 600;
}
.wrio-webp-options-radio, .wrio-error-log-options-checkbox {
display: block;
float: left;
margin-top: 2px;
margin-right: 8px;
&:focus {
outline: none;
box-shadow: none;
}
}
.wrio-webp-options-info, .wrio-error-log-options-info {
padding-left: 25px;
}
}
}
}
// MEDIA SPACE
// -----------------------------------------------
@media (max-width: 830px) {
.wio [class^="col-"] {
float: none;
margin-bottom: 1.5em;
}
.wio .col-1-3,
.wio .col-1-2 {
width: auto;
padding: 0 28px;
clear: both;
padding-top: 1em;
}
}
@keyframes wiohello {
0%, 100% {
background: #FFF;
}
50% {
background: #F4F7F9;
}
}
@media (max-width: 1520px) and (min-width: 1381px), (max-width: 1086px) {
.wio-columns {
.col-statistics.col-statistics, .col-chart.col-chart {
width: 50%;
}
}
}
@media (max-width: 808px) {
.wio-columns {
.col-statistics.col-statistics, .col-chart.col-chart {
width: auto;
float: none;
padding: 0;
}
.col-chart.col-chart {
margin-top: 3em;
}
}
}
/*@media (max-width: 1380px) and (min-width: 1246px), (max-width: 380px) {
.wio-overview-chart-container {
float: none;
margin-right: 0;
}
}
@media (max-width: 1380px) and (min-width: 1246px), (max-width: 380px) {
.wio-overview-chart-container {
float: none;
margin-right: 0;
}
.wio-doughnut-legend {
margin-top: 18px;
}
.wio-global-optim-phrase {
padding-top: 0;
width: auto;
}
}*/
}

View File

@@ -0,0 +1,2 @@
<?php
// silence is golden

View File

@@ -0,0 +1,235 @@
/**
* == Custom column & Metabox
*/
.column-wio_optimized_file.column-wio_optimized_file {
width: 300px;
text-align: center;
vertical-align: middle;
}
.column-wio_optimized_file > * {
max-width: 235px;
margin: 0 auto;
}
@media (min-width: 1151px) and (max-width: 1800px) {
.column-wio_optimized_file.column-wio_optimized_file {
width: 235px;
}
}
@media (min-width: 783px) and (max-width: 1150px) {
.column-wio_optimized_file.column-wio_optimized_file {
width: 13em;
}
table.media .column-title .has-media-icon ~ .row-actions.row-actions {
margin-left: 0;
}
}
@media (max-width: 782px) {
table.media .column-wio_optimized_file.column-wio_optimized_file {
text-align: left;
}
table.media .wio-datas-more-action,
table.media .wio-datas-actions-links {
text-align: center;
}
table.media .column-wio_optimized_file > *,
table.media .column-wio_optimized_file .wio-datas-actions-links a {
max-width: 100%;
margin-left: 0;
}
}
@media (min-width: 783px) and (max-width: 1150px), (max-width: 360px) {
table.media .wio-hide-if-small {
position: absolute;
margin: -1px;
padding: 0;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(0 0 0 0);
border: 0;
word-wrap: normal !important; /* Many screen reader and browser combinations announce broken words as they would appear visually. */
}
}
.compat-field-wio .label {
vertical-align: top;
}
.compat-field-wio ul.wio-datas-list {
margin-top: 7px;
font-size: 11px;
}
ul.wio-datas-list.wio-datas-list {
margin: 0 auto;
color: #555;
font-size: 10px;
}
ul.wio-datas-list .big {
font-size: 12px;
color: #40B1D0;
}
.wio-data-item {
overflow: hidden;
}
li.wio-data-item {
clear: both;
margin-bottom: 2px;
display: flex;
align-items: center;
gap: 5px;
}
ul.wio-datas-list .wio-data-item span.data,
ul.wio-datas-list .wio-data-item strong {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
ul.wio-datas-list .wio-data-item span.data {
text-align: left;
padding-right: 5px;
}
.compat-field-wio .wio-datas-list .wio-data-item .data {
width: 130px;
text-align: left;
font-weight: bold;
}
ul.wio-datas-list .wio-data-item strong {
text-align: left;
padding-left: 5px;
}
.media-sidebar .wio-datas-list .wio-data-item .data {
width: auto;
float: none;
}
.media-sidebar .wio-datas-list .wio-data-item strong {
display: inline-block;
width: auto;
float: none;
}
.media-sidebar .wio-datas-list .wio-data-item .wio-chart {
float: left;
}
.wio-datas-more-action.wio-datas-more-action {
margin: .4em auto;
background: linear-gradient(to bottom, transparent, transparent 49%, rgba(0,0,0,.075) 50%, rgba(0,0,0,.075) 58%, transparent 58%, transparent);
}
.wio-datas-more-action a {
display: inline-block;
padding: 0 5px;
background: #40B1D0;
color: #FFF;
text-transform: uppercase;
font-size: 9px;
font-weight: bold;
line-height: 1.9;
text-decoration: none;
}
.wio-datas-more-action a.is-open {
background: #555;
}
.wio-datas-more-action a.is-open .dashicons {
transform: rotate(180deg);
}
.wio-datas-more-action a .dashicons {
font-size: 14px;
vertical-align: middle;
line-height: .8;
}
.wio-datas-more-action a .dashicons:before {
vertical-align: middle;
line-height: 20px;
}
.wio-datas-more-action .the-text {
display: inline-block;
vertical-align: middle;
height: auto;
line-height: inherit;
}
ul.wio-datas-details.wio-datas-details {
margin: .7em auto;
}
.wio-datas-details strong {
color: #40B1D0;
}
.wio-datas-details .original {
color: #555;
}
.wio-datas-actions-links {
overflow: hidden;
border-top: 2px solid transparent;
padding-top: 5px;
font-size: 8px;
}
.nggform .wio-datas-actions-links {
position: relative;
z-index: 2;
}
.nggform .row-actions {
z-index: 1;
}
.wio-datas-actions-links a {
position: relative;
display: inline-block;
padding-left: 17px;
text-decoration: none;
font-weight: 600;
}
.compat-field-wio .wio-datas-actions-links {
max-width: 300px;
}
.misc-pub-wio .wio-datas-actions-links {
border-top: 2px solid #f2f2f2;
padding-bottom: 5px;
}
/* Library */
.column-wio_optimized_file .wio-datas-actions-links a {
margin: 0 .7em;
padding-left: 15px;
}
/* Media edition */
.compat-field-wio .wio-datas-actions-links a,
.misc-pub-wio .wio-datas-actions-links a {
font-size: 10px;
float: left;
width: 50%;
}
.media-sidebar .compat-field-wio .wio-datas-actions-links a,
.submitbox .misc-pub-wio .wio-datas-actions-links a {
display: block;
width: auto;
float: none;
}
.wio-datas-actions-links a:only-child {
float: none;
width: auto;
}
.wio-datas-details.is-open + .wio-datas-actions-links {
border-top-color: rgba(0,0,0,.075);
}
.wio-datas-actions-links .dashicons {
position: absolute;
left: 0; top: 4px;
width: 12px;
margin-right: 2px;
font-size: 11px;
}
/* Button spacing */
td.column-wio_optimized_file {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
gap: 8px;
}
.column-wio_optimized_file .wio-datas-actions-links {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 8px 1em;
}
.column-wio_optimized_file .wio-datas-actions-links a {
margin: 0;
}

View File

@@ -0,0 +1,19 @@
/* PRO labels for dropdown buttons */
button[data-value="googlepage"]:after,
button[data-value="background"]:after {
display: inline-block;
position: absolute;
content: 'PRO';
background: #ff5722;
border-radius: 4px;
color: #fff;
font-size: 10px;
line-height: 1;
font-style: normal;
padding: 4px 6px;
margin-left: 4px;
vertical-align: top;
top: -8px;
right: 0;
z-index: 11;
}

View File

@@ -0,0 +1,410 @@
/**
* == Columns
*/
.wio-columns {
overflow: hidden;
padding: 15px 0;
counter-reset: cols;
}
.wio-columns [class^="col-"] {
float: left;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.wio-columns .col-1-3 {
width: 33.333%;
padding-left: 28px;
}
.wio .col-2-3 {
width: 66.666%;
padding-left: 28px
}
.wio .col-1-2 {
width: 50%;
padding: 0 20px;
}
@media (max-width: 830px) {
.wio [class^="col-"] {
float: none;
margin-bottom: 1.5em;
}
.wio .col-1-3,
.wio .col-1-2 {
width: auto;
padding: 0 28px;
clear: both;
padding-top: 1em;
}
}
/* Col, behavior depending on parent */
.wio-col {
float: left;
width: 50%;
box-sizing: border-box;
-webkit-flex-basis: 50%;
-ms-flex-preferred-size: 50%;
flex-basis: 50%;
}
.wio-col {
padding-right: 20px;
}
.wio-col + .wio-col {
padding-right: 0;
padding-left: 50px;
}
.wio-col:target {
animation: wiohello 1s 3 linear backwards;
}
@keyframes wiohello {
0%, 100% {
background: #FFF;
}
50% {
background: #F4F7F9;
}
}
.wio-columns .col-statistics.col-statistics {
width: 60%;
}
@media (max-width: 1520px) and (min-width: 1381px), (max-width: 1086px) {
.wio-columns .col-statistics.col-statistics,
.wio-columns .col-chart.col-chart {
width: 50%;
}
}
@media (max-width: 808px) {
.wio-columns .col-statistics.col-statistics,
.wio-columns .col-chart.col-chart {
width: auto;
float: none;
padding: 0;
}
.wio-columns .col-chart.col-chart {
margin-top: 3em;
}
}
/* Number display */
.wio-number-you-optimized {
margin-bottom: 1.35em;
overflow: hidden;
}
.wio-number-you-optimized .number {
display: table-cell;
padding-right: 15px;
font-size: 48px;
font-weight: bold;
line-height: 1;
vertical-align: middle;
white-space: nowrap;
color: #000;
}
.wio-number-you-optimized [id="wio-total-optimized-attachments-pct"] {
color: #40B1D0;
}
.wio-number-you-optimized .text {
display: table-cell;
vertical-align: middle;
overflow: hidden;
font-size: 12px;
color: #626E7B;
}
.wio-number-you-optimized > p {
display: table;
}
/* Number and bars */
.wio-bars {
padding-right: 15px;
}
.wio-bars p {
font-size: 12px;
margin-bottom: 5px;
}
.wio-bars + .wio-number-you-optimized {
border-bottom: 0;
padding-top: 0.85em;
}
.wio-bars + .wio-number-you-optimized p {
color: #46b1ce;
}
.wio-bar-negative .wio-progress {
background: #D2D3D6;
}
.wio-bar-negative .wio-barnb {
color: #7A8996;
}
.wio-bar-neutral .wio-progress {
background: #F5A623;
}
.wio-space-left .wio-bar-negative .wio-progress {
background: #C51162;
}
.wio-progress {
height: 8px;
}
.wio-progress {
transition: width .3s;
}
.wio-bar-positive .wio-progress {
background: #8CC152;
}
.wio-bar-positive .wio-barnb {
color: #8CC152;
}
.wio-bar-primary .wio-progress {
background: #8bc34a;
}
.wio-bar-primary .wio-barnb {
color: #8bc34a;
}
.right-outside-number .wio-barnb {
display: block;
margin-right: -5.25em;
text-align: right;
font-weight: bold;
line-height: .8;
}
/* Doughnut */
.wio-chart {
position: relative;
top: 1px;
display: inline-block;
vertical-align: middle;
}
.wio-chart-container {
position: relative;
display: inline-block;
margin-right: 5px;
}
.wio-chart-container canvas {
display: block;
}
.wio-overview-chart-container {
float: left;
margin-right: 20px;
}
@media (max-width: 1380px) and (min-width: 1246px), (max-width: 380px) {
.wio-overview-chart-container {
float: none;
margin-right: 0;
}
}
.wio-chart-percent {
position: absolute;
left: 0;
right: 0;
top: 50%;
margin-top: -.5em;
line-height: 1;
text-align: center;
font-size: 55px;
font-weight: bold;
color: #afafaf;
}
.wio-chart-percent span {
font-size: 20px;
vertical-align: super;
}
#wio-overview-chart-legend {
overflow: hidden;
}
.imagify-doughnut-legend {
margin-top: 38px;
list-style: none;
}
.wio-doughnut-legend li {
display: inline-block;
padding-left: 30px;
position: relative;
margin-bottom: 15px;
border-radius: 5px;
padding: 3px 8px 2px 31px;
font-size: 13px;
cursor: default;
-webkit-transition: background-color 200ms ease-in-out;
-moz-transition: background-color 200ms ease-in-out;
-o-transition: background-color 200ms ease-in-out;
transition: background-color 200ms ease-in-out;
}
.wio-doughnut-legend li span {
display: block;
position: absolute;
left: 0;
top: 0;
width: 25px;
height: 25px;
border-radius: 50%;
}
@media (max-width: 1380px) and (min-width: 1246px), (max-width: 380px) {
.wio-overview-chart-container {
float: none;
margin-right: 0;
}
.wio-doughnut-legend {
margin-top: 18px;
}
.wio-global-optim-phrase {
padding-top: 0;
width: auto;
}
}
.wio-global-optim-phrase {
width: 180px;
padding-top: 20px;
font-size: 14px;
text-align: center;
}
.wio-clear {
clear: both;
}
.wio-total-percent {
color: #46b1ce;
}
.wio-columns .col-chart.col-chart {
width: 40%;
position: relative;
padding: 20px;
font-size: 12px;
text-transform: uppercase;
background: #f1f1f1b3;
color: #abacaf;
font-weight: bold;
border-radius: 5px;
margin-top: 10px;
text-align: left;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
}
.wio-image-optimize-board {
padding-bottom: 0 !important;
}
.wio-optimize-button {
width: 180px;
padding: 12px 30px;
background: #c9deb2;
color: #586549;
border: 0;
box-shadow: none;
font-size: 16px;
text-transform: uppercase !important;
font-weight: bold;
border-radius: 4px;
outline: none;
}
.wio-optimize-button:active {
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.5);
}
.wio-optimize-button.running {
color: #a57b3c;
background: #fdd599 url("../img/Spinner-1s-33px.gif") 10px center no-repeat;
}
.wio-widget-bottom {
display: table;
padding-top: 20px !important;
width: 100%;
text-align: right;
}
.wio-widget-bottom li {
display: table-cell;
}
.wio-widget-bottom li:first-child {
text-align: left;
}
.wio-imagify-widget {
padding: 0 !important;
}
.wio-imagify-widget .wio-bars {
width: 60%;
margin-left: 155px;
}
.wio-imagify-widget .col-chart.col-chart {
width: 100%;
}
.wio-imagify-widget .col-controls {
width: 45%;
padding-left: 5px;
padding-top: 110px
}
.wio-imagify-widget .wio-doughnut-legend {
/*padding-top:30px;*/
text-align: left;
}
#wio-start-msg-top, #wio-start-msg-right, #wio-start-msg-complete {
display: none;
}
.wio-text-left {
text-align: left;
}
span.wio-num {
display: inline !important;
position: inherit !important;
}

View File

@@ -0,0 +1,155 @@
/* Sub Layer */
body[class*="_rio"] .swal2-container.swal2-shown {
background: rgba(16, 17, 21, 0.9);
z-index: 100000;
}
.wrio-modal {
padding: 0 !important;
}
.wrio-modal .swal2-close {
color: rgba(0, 0, 0, 0.8);
}
.wrio-modal .swal2-modal {
border-radius: 2px;
}
.wrio-modal .swal2-icon {
margin-bottom: 25px;
}
.wrio-modal .swal2-title {
margin: 0;
padding: 28px 32px;
font-size: 24px;
text-align: left;
color: #fff !important;
background: #3e3e3e !important;
}
.wrio-modal .swal2-content {
font-size: 14px;
padding: 28px 32px;
background: #efefef;
}
.wrio-modal .swal2-buttonswrapper {
margin-top: 0;
padding: 22px;
background: #F4F7F9;
}
.wrio-modal .swal2-buttonswrapper a.button svg {
margin-right: 12px;
vertical-align: -2px;
}
.wrio-modal .swal2-buttonswrapper button.loading {
border-radius: 100% !important;
height: 40px !important;
padding: 0 !important;
box-shadow: none !important;
}
.wrio-modal .swal2-buttonswrapper button.swal2-styled {
height: auto;
padding: 12px 32px;
margin: 10px;
font-size: 14px;
letter-spacing: 1px;
text-transform: uppercase;
border-radius: 3px;
font-weight: bold;
outline: none;
}
.wrio-modal .swal2-buttonswrapper button.swal2-styled.swal2-confirm {
background-color: #fdd599 !important;
text-shadow: none !important;
box-shadow: 0 3px 0 #ceac7a !important;
color: #a57b3c !important;
}
.wrio-modal .swal2-buttonswrapper button.swal2-styled.swal2-cancel {
background-color: #d2d2d2 !important;
color: #656464 !important;
text-shadow: none !important;
box-shadow: 0 3px 0 #a9a9a9;
/*background-color: #c9deb2 !important;
color: #606956 !important;
text-shadow: none !important;
box-shadow: 0 3px 0 #a7b994;*/
}
.wrio-modal .swal2-buttonswrapper button.swal2-styled:focus,
.wrio-modal .swal2-buttonswrapper button.swal2-styled:hover {
outline: none;
text-shadow: none;
color: #FFF;
}
.wrio-modal-warning {
background: #FF5722 !important;
}
.wrio-modal-warning .swal2-title {
text-align: center;
color: #222 !important;
background: #efefef !important;
}
.wrio-modal-warning .swal2-content {
font-size: 16px;
padding: 10px 20px 32px;
background: #efefef;
}
.wrio-modal-warning .swal2-buttonswrapper {
background: #efefef;
}
.wrio-modal-error {
background: #dec2c0 !important;
}
.wrio-modal-error .swal2-title {
text-align: center;
color: #222 !important;
background: #efefef !important;
}
.wrio-modal-error .swal2-content {
font-size: 16px;
padding: 10px 20px 32px;
background: #efefef;
}
.wrio-modal-error .swal2-buttonswrapper {
background: #efefef;
}
.wrio-modal-optimization-way {
background: #1F2332 !important;
}
.wrio-modal-optimization-way .wrio-swal-subtitle {
padding: 0 0 28px;
margin-top: 0px;
font-weight: 500;
font-size: 18px;
text-align: left;
color: #8c8888;
background: #efefef;
}
.wrio-modal-optimization-way .wrio-list-infos {
margin: 0;
padding: 0;
}
.wrio-modal-optimization-way .wrio-list-infos li {
display: flex;
align-items: center;
padding: 5px 5px;
text-align: left;
font-size: 14px;
line-height: 1.5;
color: #787575;
}
.wrio-modal-optimization-way .wrio-list-infos li:first-child {
padding-top: 5px;
}
.wrio-modal-optimization-way .wrio-list-infos li:last-child {
padding-bottom: 5px;
}
.wrio-modal-optimization-way .wrio-list-infos li + li {
border-top: 1px solid #E9EFF2;
}
.wrio-modal-optimization-way .wrio-list-infos a:before {
content: '';
display: block;
}
.wrio-modal-optimization-way .wrio-info-icon {
flex-grow: 0;
flex-basis: 50px;
}
.wrio-modal-optimization-way .wrio-info-icon + span {
padding-left: 20px;
}

View File

@@ -0,0 +1 @@
{"version":3,"sources":["sweetalert-custom.less"],"names":[],"mappings":";AACA,IAAI,eAAgB,iBAAgB;EAClC,iCAAA;EACA,eAAA;;AAGF;EACE,qBAAA;;AADF,WAGE;EACE,yBAAA;;AAJJ,WAOE;EACE,kBAAA;;AARJ,WAWE;EACE,mBAAA;;AAZJ,WAeE;EACE,SAAA;EACA,kBAAA;EACA,eAAA;EACA,gBAAA;EACA,WAAA;EACA,mBAAA;;AArBJ,WAwBE;EACE,eAAA;EACA,kBAAA;EACA,mBAAA;;AA3BJ,WA8BE;EACE,aAAA;EACA,aAAA;EACA,mBAAA;;AAjCJ,WA8BE,sBAKE,EAAC,OAAQ;EACP,kBAAA;EACA,oBAAA;;AArCN,WA8BE,sBAUE,OAAM;EACJ,8BAAA;EACA,uBAAA;EACA,qBAAA;EACA,2BAAA;;AA5CN,WA8BE,sBAiBE,OAAM;EACJ,YAAA;EACA,kBAAA;EACA,YAAA;EACA,eAAA;EACA,mBAAA;EACA,yBAAA;EACA,kBAAA;EACA,iBAAA;EACA,aAAA;;AAEA,WA5BJ,sBAiBE,OAAM,aAWH;EACC,yBAAA;EACA,4BAAA;EACA,2BAAA;EACA,cAAA;;AAGF,WAnCJ,sBAiBE,OAAM,aAkBH;EACC,yBAAA;EACA,cAAA;EACA,4BAAA;EACA,2BAAA;;;;;;AAOF,WA9CJ,sBAiBE,OAAM,aA6BH;AAAQ,WA9Cb,sBAiBE,OAAM,aA6BM;EACR,aAAA;EACA,iBAAA;EACA,WAAA;;AAMR;EACE,mBAAA;;AADF,mBAGE;EACE,kBAAA;EACA,WAAA;EACA,mBAAA;;AANJ,mBASE;EACE,eAAA;EACA,uBAAA;EACA,mBAAA;;AAZJ,mBAeE;EACE,mBAAA;;AAIJ;EACE,mBAAA;;AADF,iBAGE;EACE,kBAAA;EACA,WAAA;EACA,mBAAA;;AANJ,iBASE;EACE,eAAA;EACA,uBAAA;EACA,mBAAA;;AAZJ,iBAeE;EACE,mBAAA;;AAIJ;EACE,mBAAA;;AADF,4BAGE;EACE,iBAAA;EACA,eAAA;EACA,gBAAA;EACA,eAAA;EACA,gBAAA;EACA,cAAA;EACA,mBAAA;;AAVJ,4BAaE;EACE,SAAA;EACA,UAAA;;AAfJ,4BAaE,iBAIE;EACE,aAAA;EACA,mBAAA;EACA,iBAAA;EACA,gBAAA;EACA,eAAA;EACA,gBAAA;EACA,cAAA;;AAxBN,4BAaE,iBAcE,GAAE;EACA,gBAAA;;AA5BN,4BAaE,iBAkBE,GAAE;EACA,mBAAA;;AAhCN,4BAaE,iBAsBE,GAAG;EACD,6BAAA;;AApCN,4BAaE,iBA0BE,EAAC;EACC,SAAS,EAAT;EACA,cAAA;;AAzCN,4BA6CE;EACE,YAAA;EACA,gBAAA;;AA/CJ,4BAkDE,gBAAgB;EACd,kBAAA","file":"sweetalert-custom.css"}

View File

@@ -0,0 +1,185 @@
/* Sub Layer */
body[class*="_rio"] .swal2-container.swal2-shown {
background: rgba(16, 17, 21, 0.9);
z-index: 100000;
}
.wrio-modal {
padding: 0 !important;
.swal2-close {
color: rgba(0, 0, 0, .8);
}
.swal2-modal {
border-radius: 2px;
}
.swal2-icon {
margin-bottom: 25px;
}
.swal2-title {
margin: 0;
padding: 28px 32px;
font-size: 24px;
text-align: left;
color: #fff !important;
background: #3e3e3e !important;
}
.swal2-content {
font-size: 14px;
padding: 28px 32px;
background: #efefef;
}
.swal2-buttonswrapper {
margin-top: 0;
padding: 22px;
background: #F4F7F9;
a.button svg {
margin-right: 12px;
vertical-align: -2px;
}
button.loading {
border-radius: 100% !important;
height: 40px !important;
padding: 0 !important;
box-shadow: none !important;
}
button.swal2-styled {
height: auto;
padding: 12px 32px;
margin: 10px;
font-size: 14px;
letter-spacing: 1px;
text-transform: uppercase;
border-radius: 3px;
font-weight: bold;
outline: none;
&.swal2-confirm {
background-color: #fdd599 !important;
text-shadow: none !important;
box-shadow: 0 3px 0 #ceac7a !important;
color: #a57b3c !important;
}
&.swal2-cancel {
background-color: #d2d2d2 !important;
color: #656464 !important;
text-shadow: none !important;
box-shadow: 0 3px 0 #a9a9a9;
/*background-color: #c9deb2 !important;
color: #606956 !important;
text-shadow: none !important;
box-shadow: 0 3px 0 #a7b994;*/
}
&:focus, &:hover {
outline: none;
text-shadow: none;
color: #FFF;
}
}
}
}
.wrio-modal-warning {
background: #FF5722 !important;
.swal2-title {
text-align: center;
color: #222 !important;
background: #efefef !important;
}
.swal2-content {
font-size: 16px;
padding: 10px 20px 32px;
background: #efefef;
}
.swal2-buttonswrapper {
background: #efefef;
}
}
.wrio-modal-error {
background: #dec2c0 !important;
.swal2-title {
text-align: center;
color: #222 !important;
background: #efefef !important;
}
.swal2-content {
font-size: 16px;
padding: 10px 20px 32px;
background: #efefef;
}
.swal2-buttonswrapper {
background: #efefef;
}
}
.wrio-modal-optimization-way {
background: #1F2332 !important;
.wrio-swal-subtitle {
padding: 0 0 28px;
margin-top: 0px;
font-weight: 500;
font-size: 18px;
text-align: left;
color: #8c8888;
background: #efefef;
}
.wrio-list-infos {
margin: 0;
padding: 0;
li {
display: flex;
align-items: center;
padding: 15px 5px;
text-align: left;
font-size: 14px;
line-height: 1.5;
color: #8c8888;
}
li:first-child {
padding-top: 5px;
}
li:last-child {
padding-bottom: 5px;
}
li + li {
border-top: 1px solid #E9EFF2;
}
a:before {
content: '';
display: block;
}
}
.wrio-info-icon {
flex-grow: 0;
flex-basis: 50px;
}
.wrio-info-icon + span {
padding-left: 20px;
}
}

View File

@@ -0,0 +1,716 @@
body.swal2-shown {
overflow-y: hidden; }
body.swal2-iosfix {
position: fixed;
left: 0;
right: 0; }
.swal2-container {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
padding: 10px;
background-color: transparent;
z-index: 1060; }
.swal2-container.swal2-fade {
-webkit-transition: background-color .1s;
transition: background-color .1s; }
.swal2-container.swal2-shown {
background-color: rgba(0, 0, 0, 0.4); }
.swal2-modal {
background-color: #fff;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
border-radius: 5px;
-webkit-box-sizing: border-box;
box-sizing: border-box;
text-align: center;
margin: auto;
overflow-x: hidden;
overflow-y: auto;
display: none;
position: relative;
max-width: 100%; }
.swal2-modal:focus {
outline: none; }
.swal2-modal.swal2-loading {
overflow-y: hidden; }
.swal2-modal .swal2-title {
color: #595959;
font-size: 30px;
text-align: center;
font-weight: 600;
text-transform: none;
position: relative;
margin: 0 0 .4em;
padding: 0;
display: block;
word-wrap: break-word; }
.swal2-modal .swal2-buttonswrapper {
margin-top: 15px; }
.swal2-modal .swal2-buttonswrapper:not(.swal2-loading) .swal2-styled[disabled] {
opacity: .4;
cursor: no-drop; }
.swal2-modal .swal2-buttonswrapper.swal2-loading .swal2-styled.swal2-confirm {
-webkit-box-sizing: border-box;
box-sizing: border-box;
border: 4px solid transparent;
border-color: transparent;
width: 40px;
height: 40px;
padding: 0;
margin: 7.5px;
vertical-align: top;
background-color: transparent !important;
color: transparent;
cursor: default;
border-radius: 100%;
-webkit-animation: rotate-loading 1.5s linear 0s infinite normal;
animation: rotate-loading 1.5s linear 0s infinite normal;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none; }
.swal2-modal .swal2-buttonswrapper.swal2-loading .swal2-styled.swal2-cancel {
margin-left: 30px;
margin-right: 30px; }
.swal2-modal .swal2-buttonswrapper.swal2-loading :not(.swal2-styled).swal2-confirm::after {
display: inline-block;
content: '';
margin-left: 5px 0 15px;
vertical-align: -1px;
height: 15px;
width: 15px;
border: 3px solid #999999;
-webkit-box-shadow: 1px 1px 1px #fff;
box-shadow: 1px 1px 1px #fff;
border-right-color: transparent;
border-radius: 50%;
-webkit-animation: rotate-loading 1.5s linear 0s infinite normal;
animation: rotate-loading 1.5s linear 0s infinite normal; }
.swal2-modal .swal2-styled {
border: 0;
border-radius: 3px;
-webkit-box-shadow: none;
box-shadow: none;
color: #fff;
cursor: pointer;
font-size: 17px;
font-weight: 500;
margin: 15px 5px 0;
padding: 10px 32px; }
.swal2-modal .swal2-image {
margin: 20px auto;
max-width: 100%; }
.swal2-modal .swal2-close {
background: transparent;
border: 0;
margin: 0;
padding: 0;
width: 38px;
height: 40px;
font-size: 36px;
line-height: 40px;
font-family: serif;
position: absolute;
top: 5px;
right: 8px;
cursor: pointer;
color: #cccccc;
-webkit-transition: color .1s ease;
transition: color .1s ease; }
.swal2-modal .swal2-close:hover {
color: #d55; }
.swal2-modal > .swal2-input,
.swal2-modal > .swal2-file,
.swal2-modal > .swal2-textarea,
.swal2-modal > .swal2-select,
.swal2-modal > .swal2-radio,
.swal2-modal > .swal2-checkbox {
display: none; }
.swal2-modal .swal2-content {
font-size: 18px;
text-align: center;
font-weight: 300;
position: relative;
float: none;
margin: 0;
padding: 0;
line-height: normal;
color: #545454;
word-wrap: break-word; }
.swal2-modal .swal2-input,
.swal2-modal .swal2-file,
.swal2-modal .swal2-textarea,
.swal2-modal .swal2-select,
.swal2-modal .swal2-radio,
.swal2-modal .swal2-checkbox {
margin: 20px auto; }
.swal2-modal .swal2-input,
.swal2-modal .swal2-file,
.swal2-modal .swal2-textarea {
width: 100%;
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-size: 18px;
border-radius: 3px;
border: 1px solid #d9d9d9;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06);
-webkit-transition: border-color box-shadow .3s;
transition: border-color box-shadow .3s; }
.swal2-modal .swal2-input.swal2-inputerror,
.swal2-modal .swal2-file.swal2-inputerror,
.swal2-modal .swal2-textarea.swal2-inputerror {
border-color: #f27474 !important;
-webkit-box-shadow: 0 0 2px #f27474 !important;
box-shadow: 0 0 2px #f27474 !important; }
.swal2-modal .swal2-input:focus,
.swal2-modal .swal2-file:focus,
.swal2-modal .swal2-textarea:focus {
outline: none;
border: 1px solid #b4dbed;
-webkit-box-shadow: 0 0 3px #c4e6f5;
box-shadow: 0 0 3px #c4e6f5; }
.swal2-modal .swal2-input:focus::-webkit-input-placeholder,
.swal2-modal .swal2-file:focus::-webkit-input-placeholder,
.swal2-modal .swal2-textarea:focus::-webkit-input-placeholder {
-webkit-transition: opacity .3s .03s ease;
transition: opacity .3s .03s ease;
opacity: .8; }
.swal2-modal .swal2-input:focus:-ms-input-placeholder,
.swal2-modal .swal2-file:focus:-ms-input-placeholder,
.swal2-modal .swal2-textarea:focus:-ms-input-placeholder {
-webkit-transition: opacity .3s .03s ease;
transition: opacity .3s .03s ease;
opacity: .8; }
.swal2-modal .swal2-input:focus::placeholder,
.swal2-modal .swal2-file:focus::placeholder,
.swal2-modal .swal2-textarea:focus::placeholder {
-webkit-transition: opacity .3s .03s ease;
transition: opacity .3s .03s ease;
opacity: .8; }
.swal2-modal .swal2-input::-webkit-input-placeholder,
.swal2-modal .swal2-file::-webkit-input-placeholder,
.swal2-modal .swal2-textarea::-webkit-input-placeholder {
color: #e6e6e6; }
.swal2-modal .swal2-input:-ms-input-placeholder,
.swal2-modal .swal2-file:-ms-input-placeholder,
.swal2-modal .swal2-textarea:-ms-input-placeholder {
color: #e6e6e6; }
.swal2-modal .swal2-input::placeholder,
.swal2-modal .swal2-file::placeholder,
.swal2-modal .swal2-textarea::placeholder {
color: #e6e6e6; }
.swal2-modal .swal2-range input {
float: left;
width: 80%; }
.swal2-modal .swal2-range output {
float: right;
width: 20%;
font-size: 20px;
font-weight: 600;
text-align: center; }
.swal2-modal .swal2-range input,
.swal2-modal .swal2-range output {
height: 43px;
line-height: 43px;
vertical-align: middle;
margin: 20px auto;
padding: 0; }
.swal2-modal .swal2-input {
height: 43px;
padding: 0 12px; }
.swal2-modal .swal2-input[type='number'] {
max-width: 150px; }
.swal2-modal .swal2-file {
font-size: 20px; }
.swal2-modal .swal2-textarea {
height: 108px;
padding: 12px; }
.swal2-modal .swal2-select {
color: #545454;
font-size: inherit;
padding: 5px 10px;
min-width: 40%;
max-width: 100%; }
.swal2-modal .swal2-radio {
border: 0; }
.swal2-modal .swal2-radio label:not(:first-child) {
margin-left: 20px; }
.swal2-modal .swal2-radio input,
.swal2-modal .swal2-radio span {
vertical-align: middle; }
.swal2-modal .swal2-radio input {
margin: 0 3px 0 0; }
.swal2-modal .swal2-checkbox {
color: #545454; }
.swal2-modal .swal2-checkbox input,
.swal2-modal .swal2-checkbox span {
vertical-align: middle; }
.swal2-modal .swal2-validationerror {
background-color: #f0f0f0;
margin: 0 -20px;
overflow: hidden;
padding: 10px;
color: gray;
font-size: 16px;
font-weight: 300;
display: none; }
.swal2-modal .swal2-validationerror::before {
content: '!';
display: inline-block;
width: 24px;
height: 24px;
border-radius: 50%;
background-color: #ea7d7d;
color: #fff;
line-height: 24px;
text-align: center;
margin-right: 10px; }
@supports (-ms-accelerator: true) {
.swal2-range input {
width: 100% !important; }
.swal2-range output {
display: none; } }
@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
.swal2-range input {
width: 100% !important; }
.swal2-range output {
display: none; } }
.swal2-icon {
width: 80px;
height: 80px;
border: 4px solid transparent;
border-radius: 50%;
margin: 20px auto 30px;
padding: 0;
position: relative;
-webkit-box-sizing: content-box;
box-sizing: content-box;
cursor: default;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none; }
.swal2-icon.swal2-error {
border-color: #f27474; }
.swal2-icon.swal2-error .swal2-x-mark {
position: relative;
display: block; }
.swal2-icon.swal2-error [class^='swal2-x-mark-line'] {
position: absolute;
height: 5px;
width: 47px;
background-color: #f27474;
display: block;
top: 37px;
border-radius: 2px; }
.swal2-icon.swal2-error [class^='swal2-x-mark-line'][class$='left'] {
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
left: 17px; }
.swal2-icon.swal2-error [class^='swal2-x-mark-line'][class$='right'] {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
right: 16px; }
.swal2-icon.swal2-warning {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
color: #f8bb86;
border-color: #facea8;
font-size: 60px;
line-height: 80px;
text-align: center; }
.swal2-icon.swal2-info {
font-family: 'Open Sans', sans-serif;
color: #3fc3ee;
border-color: #9de0f6;
font-size: 60px;
line-height: 80px;
text-align: center; }
.swal2-icon.swal2-question {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
color: #87adbd;
border-color: #c9dae1;
font-size: 60px;
line-height: 80px;
text-align: center; }
.swal2-icon.swal2-success {
border-color: #a5dc86; }
.swal2-icon.swal2-success [class^='swal2-success-circular-line'] {
border-radius: 50%;
position: absolute;
width: 60px;
height: 120px;
-webkit-transform: rotate(45deg);
transform: rotate(45deg); }
.swal2-icon.swal2-success [class^='swal2-success-circular-line'][class$='left'] {
border-radius: 120px 0 0 120px;
top: -7px;
left: -33px;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 60px 60px;
transform-origin: 60px 60px; }
.swal2-icon.swal2-success [class^='swal2-success-circular-line'][class$='right'] {
border-radius: 0 120px 120px 0;
top: -11px;
left: 30px;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 60px;
transform-origin: 0 60px; }
.swal2-icon.swal2-success .swal2-success-ring {
width: 80px;
height: 80px;
border: 4px solid rgba(165, 220, 134, 0.2);
border-radius: 50%;
-webkit-box-sizing: content-box;
box-sizing: content-box;
position: absolute;
left: -4px;
top: -4px;
z-index: 2; }
.swal2-icon.swal2-success .swal2-success-fix {
width: 7px;
height: 90px;
position: absolute;
left: 28px;
top: 8px;
z-index: 1;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg); }
.swal2-icon.swal2-success [class^='swal2-success-line'] {
height: 5px;
background-color: #a5dc86;
display: block;
border-radius: 2px;
position: absolute;
z-index: 2; }
.swal2-icon.swal2-success [class^='swal2-success-line'][class$='tip'] {
width: 25px;
left: 14px;
top: 46px;
-webkit-transform: rotate(45deg);
transform: rotate(45deg); }
.swal2-icon.swal2-success [class^='swal2-success-line'][class$='long'] {
width: 47px;
right: 8px;
top: 38px;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg); }
.swal2-progresssteps {
font-weight: 600;
margin: 0 0 20px;
padding: 0; }
.swal2-progresssteps li {
display: inline-block;
position: relative; }
.swal2-progresssteps .swal2-progresscircle {
background: #3085d6;
border-radius: 2em;
color: #fff;
height: 2em;
line-height: 2em;
text-align: center;
width: 2em;
z-index: 20; }
.swal2-progresssteps .swal2-progresscircle:first-child {
margin-left: 0; }
.swal2-progresssteps .swal2-progresscircle:last-child {
margin-right: 0; }
.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep {
background: #3085d6; }
.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep ~ .swal2-progresscircle {
background: #add8e6; }
.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep ~ .swal2-progressline {
background: #add8e6; }
.swal2-progresssteps .swal2-progressline {
background: #3085d6;
height: .4em;
margin: 0 -1px;
z-index: 10; }
[class^='swal2'] {
-webkit-tap-highlight-color: transparent; }
@-webkit-keyframes showSweetAlert {
0% {
-webkit-transform: scale(0.7);
transform: scale(0.7); }
45% {
-webkit-transform: scale(1.05);
transform: scale(1.05); }
80% {
-webkit-transform: scale(0.95);
transform: scale(0.95); }
100% {
-webkit-transform: scale(1);
transform: scale(1); } }
@keyframes showSweetAlert {
0% {
-webkit-transform: scale(0.7);
transform: scale(0.7); }
45% {
-webkit-transform: scale(1.05);
transform: scale(1.05); }
80% {
-webkit-transform: scale(0.95);
transform: scale(0.95); }
100% {
-webkit-transform: scale(1);
transform: scale(1); } }
@-webkit-keyframes hideSweetAlert {
0% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1; }
100% {
-webkit-transform: scale(0.5);
transform: scale(0.5);
opacity: 0; } }
@keyframes hideSweetAlert {
0% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 1; }
100% {
-webkit-transform: scale(0.5);
transform: scale(0.5);
opacity: 0; } }
.swal2-show {
-webkit-animation: showSweetAlert 0.3s;
animation: showSweetAlert 0.3s; }
.swal2-show.swal2-noanimation {
-webkit-animation: none;
animation: none; }
.swal2-hide {
-webkit-animation: hideSweetAlert 0.15s forwards;
animation: hideSweetAlert 0.15s forwards; }
.swal2-hide.swal2-noanimation {
-webkit-animation: none;
animation: none; }
@-webkit-keyframes animate-success-tip {
0% {
width: 0;
left: 1px;
top: 19px; }
54% {
width: 0;
left: 1px;
top: 19px; }
70% {
width: 50px;
left: -8px;
top: 37px; }
84% {
width: 17px;
left: 21px;
top: 48px; }
100% {
width: 25px;
left: 14px;
top: 45px; } }
@keyframes animate-success-tip {
0% {
width: 0;
left: 1px;
top: 19px; }
54% {
width: 0;
left: 1px;
top: 19px; }
70% {
width: 50px;
left: -8px;
top: 37px; }
84% {
width: 17px;
left: 21px;
top: 48px; }
100% {
width: 25px;
left: 14px;
top: 45px; } }
@-webkit-keyframes animate-success-long {
0% {
width: 0;
right: 46px;
top: 54px; }
65% {
width: 0;
right: 46px;
top: 54px; }
84% {
width: 55px;
right: 0;
top: 35px; }
100% {
width: 47px;
right: 8px;
top: 38px; } }
@keyframes animate-success-long {
0% {
width: 0;
right: 46px;
top: 54px; }
65% {
width: 0;
right: 46px;
top: 54px; }
84% {
width: 55px;
right: 0;
top: 35px; }
100% {
width: 47px;
right: 8px;
top: 38px; } }
@-webkit-keyframes rotatePlaceholder {
0% {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg); }
5% {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg); }
12% {
-webkit-transform: rotate(-405deg);
transform: rotate(-405deg); }
100% {
-webkit-transform: rotate(-405deg);
transform: rotate(-405deg); } }
@keyframes rotatePlaceholder {
0% {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg); }
5% {
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg); }
12% {
-webkit-transform: rotate(-405deg);
transform: rotate(-405deg); }
100% {
-webkit-transform: rotate(-405deg);
transform: rotate(-405deg); } }
.swal2-animate-success-line-tip {
-webkit-animation: animate-success-tip 0.75s;
animation: animate-success-tip 0.75s; }
.swal2-animate-success-line-long {
-webkit-animation: animate-success-long 0.75s;
animation: animate-success-long 0.75s; }
.swal2-success.swal2-animate-success-icon .swal2-success-circular-line-right {
-webkit-animation: rotatePlaceholder 4.25s ease-in;
animation: rotatePlaceholder 4.25s ease-in; }
@-webkit-keyframes animate-error-icon {
0% {
-webkit-transform: rotateX(100deg);
transform: rotateX(100deg);
opacity: 0; }
100% {
-webkit-transform: rotateX(0deg);
transform: rotateX(0deg);
opacity: 1; } }
@keyframes animate-error-icon {
0% {
-webkit-transform: rotateX(100deg);
transform: rotateX(100deg);
opacity: 0; }
100% {
-webkit-transform: rotateX(0deg);
transform: rotateX(0deg);
opacity: 1; } }
.swal2-animate-error-icon {
-webkit-animation: animate-error-icon 0.5s;
animation: animate-error-icon 0.5s; }
@-webkit-keyframes animate-x-mark {
0% {
-webkit-transform: scale(0.4);
transform: scale(0.4);
margin-top: 26px;
opacity: 0; }
50% {
-webkit-transform: scale(0.4);
transform: scale(0.4);
margin-top: 26px;
opacity: 0; }
80% {
-webkit-transform: scale(1.15);
transform: scale(1.15);
margin-top: -6px; }
100% {
-webkit-transform: scale(1);
transform: scale(1);
margin-top: 0;
opacity: 1; } }
@keyframes animate-x-mark {
0% {
-webkit-transform: scale(0.4);
transform: scale(0.4);
margin-top: 26px;
opacity: 0; }
50% {
-webkit-transform: scale(0.4);
transform: scale(0.4);
margin-top: 26px;
opacity: 0; }
80% {
-webkit-transform: scale(1.15);
transform: scale(1.15);
margin-top: -6px; }
100% {
-webkit-transform: scale(1);
transform: scale(1);
margin-top: 0;
opacity: 1; } }
.swal2-animate-x-mark {
-webkit-animation: animate-x-mark 0.5s;
animation: animate-x-mark 0.5s; }
@-webkit-keyframes rotate-loading {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@keyframes rotate-loading {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }

View File

@@ -0,0 +1,126 @@
/**
* Subscribe Widget Styles
* Matches the onp-container / license-manager styling
*
* @package Robin_Image_Optimizer
*/
.wrio-subscribe-widget {
border: 0;
padding: 0;
border-radius: 5px;
background: rgb(255, 255, 255);
background: linear-gradient(to bottom, rgba(255, 255, 255, 1) 63%, rgba(246, 246, 246, 1) 100%);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
box-sizing: border-box;
margin-top: 30px;
}
.wrio-subscribe-widget__header {
padding: 20px;
padding-bottom: 0;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.wrio-subscribe-widget__header h3 {
margin: 0;
padding: 0;
font-size: 16px;
}
.wrio-subscribe-widget__body {
padding: 20px;
padding-top: 15px;
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
}
.wrio-subscribe-widget__messages {
margin-bottom: 15px;
}
.wrio-subscribe-widget__success {
background: #f0fdf4;
border: 1px solid #bbf7d0;
color: #16a34a;
padding: 12px 15px;
border-radius: 4px;
font-size: 14px;
line-height: 170%;
}
.wrio-subscribe-widget__error {
background: #fef2f2;
border: 1px solid #fecaca;
color: #dc2626;
padding: 12px 15px;
border-radius: 4px;
font-size: 14px;
line-height: 170%;
}
.wrio-subscribe-widget__form {
/* Form container */
}
.wrio-subscribe-widget__form p {
margin: 0 0 10px 0;
padding: 0;
line-height: 170%;
font-size: 14px;
}
.wrio-subscribe-widget__field-wrap {
display: flex;
flex-direction: row;
gap: 10px;
margin-bottom: 12px;
}
.wrio-subscribe-widget__email {
flex: 1;
font-size: 18px;
line-height: 20px;
height: 36px;
padding: 6px 12px;
border: 1px solid #7e8993;
border-radius: 4px;
color: #000;
}
.wrio-subscribe-widget__email:focus {
border-color: #007cba;
box-shadow: 0 0 0 1px #007cba;
outline: none;
}
.wrio-subscribe-widget__button {
white-space: nowrap;
padding: 7px 14px 6px 14px;
text-decoration: none;
}
.wrio-subscribe-widget .wrio-subscribe-widget__checkbox-label {
display: inline-block;
gap: 8px;
font-size: 13px;
color: #333;
line-height: 170%;
margin-top: 5px;
font-weight: normal;
}
.wrio-subscribe-widget__checkbox-label input[type="checkbox"] {
flex-shrink: 0;
margin-top: 0;
}
.wrio-subscribe-widget__checkbox-label a {
color: #0073aa;
text-decoration: none;
}
.wrio-subscribe-widget__checkbox-label a:hover {
text-decoration: underline;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

View File

@@ -0,0 +1,2 @@
<?php
// silence is golden

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -0,0 +1,2 @@
<?php
// silence is golden

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,470 @@
jQuery(function ($) {
/**
* Factory function to create a bulk conversion handler for a specific format.
*
* @param {string} format - The conversion format ('webp' or 'avif')
* @param {string} buttonSelector - jQuery selector for the start button
* @returns {Object} - Bulk conversion handler object
*/
function createBulkConversion(format, buttonSelector) {
return {
format: format,
inprogress: false,
serverDown: false,
i18n: {},
settings: {},
startConvertButton: $(buttonSelector),
startOptButton: $('#wrio-start-optimization'),
startWebpButton: $('#wrio-start-conversion'),
startAvifButton: $('#wrio-start-avif-conversion'),
init: function () {
this.i18n = wrio_l18n_bulk_page;
this.settings = wrio_settings_bulk_page;
if (this.startConvertButton.length) {
this.registerEvents();
this.checkInitialRunningState();
}
},
checkInitialRunningState: function () {
// If this conversion button is already running on page load, disable other buttons
if (this.startConvertButton.hasClass('wio-running')) {
this.startOptButton.prop('disabled', true);
// Disable the other conversion button (not this one)
if (this.format === 'webp') {
this.startAvifButton.prop('disabled', true);
} else {
this.startWebpButton.prop('disabled', true);
}
}
},
registerEvents: function () {
var self = this;
this.startConvertButton.on('click', function () {
if ($(this).hasClass('wio-running')) {
self.startOptButton.prop('disabled', false);
self.startWebpButton.prop('disabled', false);
self.startAvifButton.prop('disabled', false);
self.stop();
return;
}
self.showModal();
return false;
});
},
showModal: function () {
var self = this;
var infosModal = $('#wrio-tmpl-' + this.format + '-conversion');
// Fall back to webp template if format-specific one doesn't exist
if (!infosModal.length) {
infosModal = $('#wrio-tmpl-webp-conversion');
}
if (!infosModal.length) {
console.log('[Error]: Html template for modal not found.');
return;
}
var modalTitle = this.format === 'avif'
? (this.i18n.modal_avif_conversion_title || this.i18n.modal_conversion_title)
: this.i18n.modal_conversion_title;
// Swal Information before loading the optimize process.
swal({
title: modalTitle,
html: infosModal.html(),
type: '',
customClass: 'wrio-modal wrio-modal-optimization-way',
showCancelButton: true,
showCloseButton: true,
padding: 0,
width: 740,
confirmButtonText: this.i18n.modal_conversion_manual_button,
cancelButtonText: this.i18n.modal_conversion_cron_button,
reverseButtons: true,
}).then(function (result) {
self.startOptButton.prop('disabled', true);
self.startWebpButton.prop('disabled', true);
self.startAvifButton.prop('disabled', true);
self.startConvertButton.prop('disabled', false); // Re-enable current button for stop
self.process();
window.onbeforeunload = function () {
return self.i18n.leave_page_warning;
}
}, function (dismiss) {
if (dismiss === 'cancel') { // you might also handle 'close' or 'timer' if you used those
self.startOptButton.prop('disabled', true);
self.startWebpButton.prop('disabled', true);
self.startAvifButton.prop('disabled', true);
self.startConvertButton.prop('disabled', false); // Re-enable current button for stop
self.process('cron');
} else {
throw dismiss;
}
});
},
/**
* Start conversion
* @param {string} type - 'cron' or undefined for manual
*/
process: function (type) {
var self = this;
this.inprogress = true;
var sendData = {
'action': 'wrio-bulk-conversion-process',
'scope': this.settings.scope,
'format': this.format,
'multisite': 0,
'_wpnonce': this.settings.conversion_nonce,
};
this.setButtonStyleRun(type);
if ('cron' === type) {
this.startConvertButton.addClass('wrio-cron-mode');
sendData['action'] = 'wrio-' + this.format + '-cron-start';
$.post(ajaxurl, sendData, function (response) {
if (!response || !response.success) {
console.log('[Error]: Failed ajax request (Start cron).');
console.log(sendData);
console.log(response);
if (response.data && response.data.error_message) {
self.throwError(response.data.error_message);
}
} else {
if (response.data && response.data.stop) {
self.stop();
}
}
}).fail(function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
self.throwError(error);
});
return;
}
this.showMessage(this.i18n.conversion_inprogress.replace("%s", parseInt($('#wio-unoptimized-num').text())));
sendData['reset_current_errors'] = 1;
this.sendRequest(sendData);
},
stop: function () {
var self = this;
this.inprogress = false;
window.onbeforeunload = null;
self.setButtonStyleStop();
self.destroyMessages();
if (this.startConvertButton.hasClass('wrio-cron-mode')) {
this.startConvertButton.removeClass('wrio-cron-mode');
$.post(ajaxurl, {
'action': 'wrio-' + this.format + '-cron-stop',
'_wpnonce': self.settings.conversion_nonce,
'scope': self.settings.scope
}, function (response) {
if (!response || !response.success) {
console.log('[Error]: Failed ajax request (Stop cron).');
console.log(response);
if (response.data && response.data.error_message) {
self.throwError(response.data.error_message);
}
} else {
self.startOptButton.prop('disabled', false);
self.startWebpButton.prop('disabled', false);
self.startAvifButton.prop('disabled', false);
}
}).fail(function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
self.throwError(error);
});
}
},
complete: function () {
this.inprogress = false;
window.onbeforeunload = null;
this.setButtonStyleComplete();
},
setButtonStyleRun: function (mode) {
this.startConvertButton.addClass('wio-running');
if ("cron" === mode) {
this.startConvertButton.text(this.i18n.modal_conversion_cron_button_stop);
return;
}
this.startConvertButton.text(this.i18n.button_stop);
},
setButtonStyleComplete: function () {
this.showMessage(this.i18n.conversion_complete);
this.startConvertButton.text(this.i18n.button_completed);
this.startConvertButton.removeClass('wio-running');
this.startConvertButton.prop('disabled', true);
this.startOptButton.prop('disabled', false);
this.startWebpButton.prop('disabled', false);
this.startAvifButton.prop('disabled', false);
},
setButtonStyleStop: function () {
this.startConvertButton.removeClass('wio-running');
var buttonText = this.format === 'avif'
? (this.i18n.avif_button_start || 'Convert to AVIF')
: this.i18n.webp_button_start;
this.startConvertButton.text(buttonText);
},
showMessage: function (text) {
var contanier = $('.wio-page-statistic'),
message;
if (contanier.find('.wrio-statistic-message').length) {
message = contanier.find('.wrio-statistic-message');
} else {
message = $('<div>');
message.addClass('wrio-statistic-message');
contanier.append(message);
}
message.html(text);
},
throwError: function (error_message) {
this.stop();
var noticeId = $.wbcr_factory_templates_759.app.showNotice(error_message, 'danger');
setTimeout(function () {
$.wbcr_factory_templates_759.app.hideNotice(noticeId);
}, 10000);
},
destroyMessages: function () {
$('.wio-page-statistic').find('.wrio-statistic-message').empty();
},
sendRequest: function (data) {
var self = this;
if (!this.inprogress) {
return;
}
$.post(ajaxurl, data, function (response) {
if (!self.inprogress) {
return;
}
if (!response || !response.success) {
console.log('[Error]: Failed ajax request (Try to optimize images).');
console.log(response);
if (response.data && response.data.error_message) {
self.throwError(response.data.error_message);
}
return;
}
data.reset_current_errors = 0;
if (!response.data.end) {
$('#wio-total-unoptimized').text(parseInt(response.data.remain));
self.showMessage(self.i18n.conversion_inprogress.replace("%s", parseInt(response.data.remain)));
self.sendRequest(data);
} else {
$('#wio-total-unoptimized').text(response.data.remain);
self.complete();
}
redraw_statistics(response.data.statistic);
if (response.data.last_optimized) {
self.updateLog(response.data.last_optimized);
}
if (response.data.last_converted) {
self.updateLog(response.data.last_converted);
}
}).fail(function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
self.throwError(error);
});
},
updateLog: function (new_item_data) {
var self = this;
var limit = 100,
tableEl = $('.wrio-optimization-progress .wrio-table');
if (!tableEl.length || !new_item_data) {
return;
}
// Clear empty table state
if ($('.wrio-table-container-empty').length) {
$('.wrio-table-container-empty').addClass('wrio-table-container').removeClass('wrio-table-container-empty');
if (tableEl.find('tbody').length) {
tableEl.find('tbody').empty();
}
}
$.each(new_item_data, function (index, value) {
var trEl = $('<tr>'),
tdEl = $('<td>'),
webpSize = value.webp_size ? value.webp_size : '-',
avifSize = value.avif_size ? value.avif_size : '-';
if (tableEl.find('.wrio-row-id-' + value.id).length) {
tableEl.find('.wrio-row-id-' + value.id).remove();
}
trEl.addClass('flash').addClass('wrio-table-item').addClass('wrio-row-id-' + value.id);
if ('error' === value.type) {
trEl.addClass('wrio-error');
}
var preview = $('<img width="40" height="40" src="' + value.thumbnail_url + '" alt="">'),
previewUrl = $('<a href="' + value.url + '" target="_blank">' + value.file_name + '</a>');
tableEl.prepend(trEl);
trEl.append(tdEl.clone().append(preview));
trEl.append(tdEl.clone().append(previewUrl));
if ('error' === value.type) {
var colspan = value.scope !== 'custom-folders' ? '7' : '6';
trEl.append(tdEl.clone().attr('colspan', colspan).text("Error: " + value.error_msg));
} else {
trEl.append(tdEl.clone().text(value.original_size));
trEl.append(tdEl.clone().text(value.optimized_size));
trEl.append(tdEl.clone().text(webpSize));
trEl.append(tdEl.clone().text(avifSize));
trEl.append(tdEl.clone().text(value.original_saving));
if ("custom-folders" !== self.settings.scope) {
trEl.append(tdEl.clone().text(value.thumbnails_count));
}
trEl.append(tdEl.clone().text(value.total_saving));
}
});
if (tableEl.find('tr').length > limit) {
var diff = tableEl.find('tr').length - limit;
for (var i = 0; i < diff; i++) {
tableEl.find('tr:last').remove();
}
}
}
};
}
// Create WebP conversion handler
var bulkConversionWebp = createBulkConversion('webp', '#wrio-start-conversion');
// Create AVIF conversion handler
var bulkConversionAvif = createBulkConversion('avif', '#wrio-start-avif-conversion');
$(document).ready(function () {
bulkConversionWebp.init();
bulkConversionAvif.init();
$('[data-toggle="tooltip"]').tooltip();
});
var ajaxUrl = ajaxurl;
var ai_data;
function redraw_statistics(statistic) {
// Update WebP stats - chart data attributes
$('#wio-webp-chart').attr('data-unoptimized', statistic.unconverted)
.attr('data-optimized', statistic.converted)
.attr('data-errors', statistic.webp_error);
// Update WebP percent display
$('#wio-overview-chart-percent-webp').text(statistic.webp_percent_line);
// Update WebP legend
$('#wio-webp-pending').text(statistic.unconverted);
$('#wio-webp-converted').text(statistic.converted);
$('#wio-webp-error').text(statistic.webp_error);
$('#wio-webp-done').text(statistic.converted);
// Update AVIF stats (if available)
if (statistic.avif_unconverted !== undefined) {
$('#wio-avif-chart').attr('data-unoptimized', statistic.avif_unconverted)
.attr('data-optimized', statistic.avif_converted)
.attr('data-errors', statistic.avif_error);
// Update AVIF percent display
$('#wio-overview-chart-percent-avif').text(statistic.avif_percent_line);
// Update AVIF legend
$('#wio-avif-pending').text(statistic.avif_unconverted);
$('#wio-avif-converted').text(statistic.avif_converted);
$('#wio-avif-error').text(statistic.avif_error);
$('#wio-avif-done').text(statistic.avif_converted);
}
var credits = $('.wrio-premium-user-balance');
if (credits.attr('data-server') !== "server_5") {
credits.text(statistic.credits);
}
if (window.wio_chart_webp) {
window.wio_chart_webp.data.datasets[0].data[0] = statistic.webp_error; // errors
window.wio_chart_webp.data.datasets[0].data[1] = statistic.converted; // optimized
window.wio_chart_webp.data.datasets[0].data[2] = statistic.unconverted; // unoptimized
window.wio_chart_webp.update();
}
if (window.wio_chart_avif && statistic.avif_unconverted !== undefined) {
window.wio_chart_avif.data.datasets[0].data[0] = statistic.avif_error; // errors
window.wio_chart_avif.data.datasets[0].data[1] = statistic.avif_converted; // optimized
window.wio_chart_avif.data.datasets[0].data[2] = statistic.avif_unconverted; // unoptimized
window.wio_chart_avif.update();
}
if ($('#wio-overview-chart-percent-webp').text() == '100') {
window.onbeforeunload = null;
}
}
});

View File

@@ -0,0 +1,646 @@
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes === 0) {
return '0 Byte';
}
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
if (i === 0) {
return bytes + ' ' + sizes[i];
}
return (bytes / Math.pow(1024, i)).toFixed(2) + ' ' + sizes[i];
}
jQuery(function ($) {
var bulkOptimization = {
inprogress: false,
serverDown: false,
i18n: {},
settings: {},
init: function () {
if (wrio_l18n_bulk_page === undefined || wrio_settings_bulk_page === undefined) {
console.log('[Error]: Required global variables are not declared.');
return;
}
this.i18n = wrio_l18n_bulk_page;
this.settings = wrio_settings_bulk_page;
this.startOptButton = $('#wrio-start-optimization');
this.registerEvents();
this.checkServerStatus();
//this.calculateTotalImages();
this.checkPremiumUserBalance();
},
registerEvents: function () {
var self = this;
this.startOptButton.on('click', function () {
self.startOptButton = $(this);
if ($(this).hasClass('wio-running')) {
self.stop();
return;
}
if (self.serverDown) {
$.wrio_modal.showErrorModal(self.i18n.server_down_warning);
return;
}
if ("1" === self.settings.need_migration) {
$.wrio_modal.showErrorModal(self.i18n.need_migrations);
return;
}
if ("0" === self.settings.images_backup) {
$.wrio_modal.showWarningModal(self.i18n.process_without_backup, function () {
self.showModal();
});
return;
}
self.showModal();
return false;
});
},
checkPremiumUserBalance: function () {
var self = this,
userBalance = $('.wrio-premium-user-balance'),
balanceResetAt = $('.wrio-premium-user-update'),
data = {
'action': 'wbcr-rio-check-user-balance',
'_wpnonce': self.settings.optimization_nonce
};
userBalance.addClass('wrio-premium-user-balance-check-proccess');
userBalance.text('');
balanceResetAt.addClass('wrio-premium-user-update-check-proccess');
balanceResetAt.text('');
$.post(ajaxurl, data, function (response) {
userBalance.removeClass('wrio-premium-user-balance-check-proccess');
balanceResetAt.removeClass('wrio-premium-user-update-check-proccess');
if (!response || !response.data || !response.success) {
console.log('[Error]: Response error');
response.data && response.data.error && console.log(response.data.error);
if (!response || !response.data) {
console.log(response);
}
userBalance.text('error');
balanceResetAt.text('error');
} else {
userBalance.text(response.data?.balance);
balanceResetAt.text(response.data?.reset_at);
}
}).fail(function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
self.throwError(error);
});
},
checkServerStatus: function () {
var self = this,
serverStatus = $('.wrio-server-status'),
data = {
'action': 'wbcr-rio-check-servers-status',
'_wpnonce': self.settings.optimization_nonce
};
self.serverDown = false;
serverStatus.addClass('wrio-server-check-proccess');
serverStatus.text('');
serverStatus.removeClass('wrio-down').removeClass('wrio-stable');
self.startOptButton.prop('disabled', true);
$.post(ajaxurl, data, function (response) {
serverStatus.removeClass('wrio-server-check-proccess');
if (!response || !response.data || !response.success) {
console.log('[Error]: Response error');
response.data && response.data.error && console.log(response.data.error);
if (!response || !response.data) {
console.log(response);
}
serverStatus.addClass('wrio-down');
serverStatus.text(self.i18n.server_status_down);
self.serverDown = true;
return;
} else {
serverStatus.addClass('wrio-stable');
serverStatus.text(self.i18n.server_status_stable);
}
self.startOptButton.prop('disabled', false);
}).fail(function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
self.throwError(error);
});
},
calculateTotalImages: function () {
var self = this,
total_num = $('#wio-total-num'),
data = {
'action': 'wbcr-rio-calculate-total-images',
'_wpnonce': self.settings.optimization_nonce
};
total_num.addClass('wrio-calculate-process');
total_num.text('');
$.post(ajaxurl, data, function (response) {
total_num.removeClass('wrio-calculate-process');
if (!response || !response.data || !response.success) {
console.log('[Error]: Response error');
response.data && response.data.error && console.log(response.data.error);
if (!response || !response.data) {
console.log(response);
}
total_num.text('');
return;
} else {
if (typeof (response.data.total) !== "undefined") {
total_num.addClass('wrio-total-images');
total_num.text(response.data.total);
}
}
}).fail(function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
self.throwError(error);
});
},
showModal: function () {
var self = this;
var infosModal = $('#wrio-tmpl-bulk-optimization');
if (!infosModal.length) {
console.log('[Error]: Html template for modal not found.');
return;
}
// Swal Information before loading the optimize process.
swal({
title: this.i18n.modal_optimization_title,
html: infosModal.html(),
type: '',
customClass: 'wrio-modal wrio-modal-optimization-way',
showCancelButton: true,
showCloseButton: true,
padding: 0,
width: 740,
confirmButtonText: this.i18n.modal_optimization_manual_button,
cancelButtonText: this.i18n.modal_optimization_cron_button,
reverseButtons: true,
}).then(function (result) {
self.process();
window.onbeforeunload = function () {
return self.i18n.leave_page_warning;
}
}, function (dismiss) {
if (dismiss === 'cancel') { // you might also handle 'close' or 'timer' if you used those
self.process('cron');
} else {
throw dismiss;
}
});
},
/**
* Start optimization
* @param {string} type
*/
process: function (type) {
var self = this;
this.inprogress = true;
var sendData = {
'action': 'wrio-bulk-optimization-process',
'scope': this.settings.scope,
'multisite': 0,
'_wpnonce': this.settings.optimization_nonce,
};
this.setButtonStyleRun(type);
if ('cron' === type) {
this.startOptButton.addClass('wrio-cron-mode');
sendData['action'] = 'wrio-cron-start';
$.post(ajaxurl, sendData, function (response) {
if (!response || !response.success) {
console.log('[Error]: Failed ajax request (Start cron).');
console.log(sendData);
console.log(response);
if (response.data && response.data.error_message) {
self.throwError(response.data.error_message);
}
} else {
if (response.data && response.data.stop) {
self.stop();
}
}
}).fail(function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
self.throwError(error);
});
return;
}
this.showMessage(this.i18n.optimization_inprogress.replace("%s", parseInt($('#wio-unoptimized-num').text())));
// show message: Optimization remined
/*if( "1" === this.settings.is_network_admin ) {
sendData['multisite'] = 1;
}*/
sendData['reset_current_errors'] = 1;
this.sendRequest(sendData);
},
stop: function () {
var self = this;
this.inprogress = false;
window.onbeforeunload = null;
self.setButtonStyleStop();
self.destroyMessages();
if (this.startOptButton.hasClass('wrio-cron-mode')) {
this.startOptButton.removeClass('wrio-cron-mode');
$.post(ajaxurl, {
'action': 'wrio-cron-stop',
'_wpnonce': self.settings.optimization_nonce,
'scope': self.settings.scope
}, function (response) {
if (!response || !response.success) {
console.log('[Error]: Failed ajax request (Stop cron).');
console.log(response);
if (response.data && response.data.error_message) {
self.throwError(response.data.error_message);
}
}
}).fail(function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
self.throwError(error);
});
}
},
complete: function () {
this.inprogress = false;
window.onbeforeunload = null;
this.setButtonStyleComplete();
},
setButtonStyleRun: function (mode) {
this.startOptButton.addClass('wio-running');
if ("cron" === mode) {
this.startOptButton.text(this.i18n.modal_optimization_cron_button_stop);
return;
}
this.startOptButton.text(this.i18n.button_stop);
},
setButtonStyleComplete: function () {
this.showMessage(this.i18n.optimization_complete);
this.startOptButton.text(this.i18n.button_completed);
this.startOptButton.removeClass('wio-running');
this.startOptButton.prop('disabled', true);
},
setButtonStyleStop: function () {
this.startOptButton.removeClass('wio-running');
this.startOptButton.text(this.i18n.button_start);
},
showMessage: function (text) {
var contanier = $('.wio-page-statistic'),
message;
if (contanier.find('.wrio-statistic-message').length) {
message = contanier.find('.wrio-statistic-message');
} else {
message = $('<div>');
message.addClass('wrio-statistic-message');
contanier.append(message);
}
message.html(text);
},
throwError: function (error_message) {
this.stop();
var noticeId = $.wbcr_factory_templates_759.app.showNotice(error_message, 'danger');
setTimeout(function () {
$.wbcr_factory_templates_759.app.hideNotice(noticeId);
}, 10000);
},
destroyMessages: function () {
$('.wio-page-statistic').find('.wrio-statistic-message').empty();
},
sendRequest: function (data) {
var self = this;
if (!this.inprogress) {
return;
}
$.post(ajaxurl, data, function (response) {
if (!self.inprogress) {
return;
}
console.log(response);
if (!response || !response.success) {
console.log('[Error]: Failed ajax request (Try to optimize images).');
console.log(response);
if (response.data && response.data.error_message) {
self.throwError(response.data.error_message);
}
return;
}
data.reset_current_errors = 0;
if (!response.data.end) {
$('#wio-total-unoptimized').text(parseInt(response.data.remain));
self.showMessage(self.i18n.optimization_inprogress.replace("%s", parseInt(response.data.remain)));
self.sendRequest(data);
} else {
$('#wio-total-unoptimized').text(response.data.remain);
self.complete();
// если мультисайт режим, то не скрываем кнопку запуска оптимизации
/*if( $('#wbcr-rio-current-blog').length ) {
$('#wio-start-optimization').toggleClass('wio-running');
} else {
$('#wio-start-optimization').hide();
}*/
}
redraw_statistics(response.data.statistic);
self.updateLog(response.data.last_optimized);
}).fail(function (xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
self.throwError(error);
});
},
updateLog: function (new_item_data) {
const self = this;
const limit = 100;
const tableEl = $('.wrio-optimization-progress .wrio-table');
if (!tableEl.length || !new_item_data) {
return;
}
// Handle empty table state
if ($('.wrio-table-container-empty').length) {
$('.wrio-table-container-empty').addClass('wrio-table-container').removeClass('wrio-table-container-empty');
if (tableEl.find('tbody').length) {
tableEl.find('tbody').empty();
}
}
$.each(new_item_data, function (index, value) {
const attachmentId = value.attachment_id || value.id;
const existingRow = tableEl.find('[data-attachment-id="' + attachmentId + '"]');
if (existingRow.length) {
// Update existing row data
self.updateRowData(existingRow, value);
// Move existing row to top of the table
existingRow.detach();
tableEl.find('tbody').prepend(existingRow);
// Re-trigger flash animation
existingRow.removeClass('flash');
// Force reflow to restart animation
existingRow[0].offsetWidth;
existingRow.addClass('flash');
} else {
// Create new row and add to top
const trEl = self.buildLogRow(value);
tableEl.find('tbody').prepend(trEl);
}
});
// Enforce row limit
self.enforceRowLimit(tableEl, limit);
},
updateRowData: function (row, data) {
// Update optimized size cell
row.find('.wrio-optimized-size').text(data.optimized_size);
// Update WebP size if present
if (data.webp_size) {
const webpCell = row.find('.wrio-webp-size');
if (webpCell.length) {
webpCell.text(data.webp_size);
}
}
// Update AVIF size if present
if (data.avif_size) {
const avifCell = row.find('.wrio-avif-size');
if (avifCell.length) {
avifCell.text(data.avif_size);
}
}
// Update total saving
row.find('.wrio-total-saving').text(data.total_saving);
// Update thumbnails count
if (data.thumbnails_count !== undefined) {
row.find('.wrio-thumbnails-count').text(data.thumbnails_count);
}
// Update error state if needed
if (data.type === 'error') {
row.addClass('wrio-error');
} else {
row.removeClass('wrio-error');
}
},
buildLogRow: function (value) {
const attachmentId = value.attachment_id || value.id;
const trEl = $('<tr>')
.addClass('flash wrio-table-item')
.addClass('wrio-row-id-' + value.id)
.attr('data-attachment-id', attachmentId);
if (value.type === 'error') {
trEl.addClass('wrio-error');
}
// Build cells with classes for easy updates
const preview = $('<img width="40" height="40" src="' + value.thumbnail_url + '" alt="">');
const previewUrl = $('<a href="' + value.url + '" target="_blank">' + value.file_name + '</a>');
trEl.append($('<td>').append(preview));
trEl.append($('<td>').append(previewUrl));
if (value.type === 'error') {
const colspan = this.settings.scope !== 'custom-folders' ? '4' : '3';
trEl.append($('<td>').attr('colspan', colspan).text("Error: " + value.error_msg));
} else {
trEl.append($('<td class="wrio-original-size">').text(value.original_size));
trEl.append($('<td class="wrio-optimized-size">').text(value.optimized_size));
if ("custom-folders" !== this.settings.scope) {
trEl.append($('<td class="wrio-thumbnails-count">').text(value.thumbnails_count));
}
trEl.append($('<td class="wrio-total-saving">').text(value.total_saving));
}
return trEl;
},
enforceRowLimit: function (tableEl, limit) {
const rows = tableEl.find('tbody tr');
if (rows.length > limit) {
rows.slice(limit).remove();
}
}
};
$(document).ready(function () {
bulkOptimization.init();
$('[data-toggle="tooltip"]').tooltip();
});
var ajaxUrl = ajaxurl;
var ai_data;
function redraw_statistics(statistic) {
$('#wio-main-chart').attr('data-unoptimized', statistic.unoptimized)
.attr('data-optimized', statistic.optimized)
.attr('data-errors', statistic.error);
$('#wio-total-optimized-attachments').text(statistic.optimized); // optimized
$('#wio-original-size').text(bytesToSize(statistic.original_size));
$('#wio-optimized-size').text(bytesToSize(statistic.optimized_size));
$('#wio-total-saved').text(statistic.save_size_percent + '%');
$('#wio-overview-chart-percent').text(statistic.optimized_percent);
$('.wio-total-percent').text(statistic.optimized_percent + '%');
$('#wio-optimized-bar').css('width', statistic.percent_line + '%');
$('#wio-unoptimized-num').text(statistic.unoptimized);
$('#wio-optimized-num').text(statistic.optimized);
$('#wio-error-num').text(statistic.error);
if(statistic.quota_limit) {
$('.wrio-premium-user-balance').text(statistic.quota_limit);
}
if ($('.wrio-statistic-nav li.active').length) {
$('.wrio-statistic-nav li.active').find('span.wio-statistic-tab-percent').text(statistic.optimized_percent + '%');
}
window.wio_chart.data.datasets[0].data[0] = statistic.error; // errors
window.wio_chart.data.datasets[0].data[1] = statistic.optimized; // optimized
window.wio_chart.data.datasets[0].data[2] = statistic.unoptimized; // unoptimized
window.wio_chart.update();
if ($('#wio-overview-chart-percent').text() == '100%') {
window.onbeforeunload = null;
}
}
/*$('#wbcr-rio-current-blog').on('change', function() {
var self = $(this);
$('#wio-start-msg-complete').hide();
$(this).attr('disabled', true);
$('#wio-start-optimization').attr('disabled', true);
var ai_data = {
'action': 'wbcr_rio_update_current_blog',
'wpnonce': $(this).data('nonce'),
'current_blog_id': $(this).find('option:selected').val(),
'context': $(this).attr('data-context')
};
$.post(ajaxUrl, ai_data, function(response) {
self.removeAttr('disabled');
$('#wio-start-optimization').removeAttr('disabled');
redraw_statistics(response.data.statistic);
});
});*/
// AVIF upsell banner dismiss handler
$(document).on('click', '.wrio-avif-banner-dismiss', function () {
var $banner = $(this).closest('.wrio-avif-upsell-banner');
$.post(ajaxurl, {
action: 'wrio_dismiss_avif_banner',
nonce: $banner.data('nonce')
}, function () {
$banner.slideUp(300, function () {
$(this).remove();
});
});
});
});

View File

@@ -0,0 +1,169 @@
(function ($) {
class BulkOptimization {
constructor(ajaxUrl, i18n, settings) {
if (!i18n || !settings) {
console.error('[Error]: Required global variables are missing.');
return;
}
this.ajaxUrl = ajaxUrl;
this.i18n = i18n;
this.settings = settings;
this.totalImages = 0;
this.countAttachments = 0;
this.countThumbs = 0;
}
/**
* Initializes the bulk optimization process by chaining multiple calculations.
* If any error occurs during the process, it will be caught and handled.
*/
init() {
this.calculateTotalAttachments()
.then(() => this.calculateTotalThumbs())
.then(() => this.calculateTotalImages())
.catch((error) => this.throwError(error));
}
/**
* Sends an AJAX POST request to the server.
*
* @param {string} action - The AJAX action to trigger on the server.
* @param {Object} additionalData - Additional data to send with the request.
* @returns {Promise<Object>} - A promise that resolves with the response data from the server.
* @throws Will throw an error if the response is invalid or the request fails.
*/
async postAjax(action, additionalData = {}) {
const data = {
action: action,
_wpnonce: this.settings.optimization_nonce,
...additionalData,
};
try {
const response = await $.post(this.ajaxUrl, data);
if (!response || !response.success || !response.data) {
console.error('[Error]: Invalid AJAX response.', response);
if (response?.data?.error) {
console.error(response.data.error);
}
throw new Error(this.i18n.ajaxError || 'AJAX Error Occurred');
}
return response.data;
} catch (xhr) {
console.error('[Error]: AJAX Request Failed.', xhr);
throw xhr;
}
}
/**
* Calculates the total number of attachments.
*
* This method sends an AJAX request to the server to fetch the total
* number of media attachments and updates the corresponding UI element with the result.
*
* @returns {Promise<void>} - A promise that resolves when the calculation is complete.
*/
async calculateTotalAttachments() {
try {
const data = await this.postAjax('wbcr-rio-calculate-total-attachments');
this.countAttachments = data.found_attachments;
$('#wio-stat-totals__originals')
.removeClass('wio-stat-totals__loading')
.text(data.found_attachments);
} catch (error) {
this.throwError(error);
}
}
/**
* Updates the total count of images by summing attachments and thumbnails.
*
* This method does not send an AJAX request. Instead, it calculates the total
* number of found images and updates the corresponding UI element.
*/
async calculateTotalImages() {
this.totalImages = this.countAttachments + this.countThumbs;
$('#wio-stat-totals__totals')
.removeClass('wio-stat-totals__loading')
.text(this.totalImages);
}
/**
* Calculates the total number of thumbnails in a paginated manner.
*
* This method sends multiple AJAX requests based on the `offset` returned
* from the server. It stops once the `done` parameter is `true` and accumulates
* the total number of thumbnails found during the process.
*
* @returns {Promise<void>} - A promise that resolves when all requests are complete.
* @throws Will throw an error if `next_offset` is missing or undefined in the response.
*/
async calculateTotalThumbs() {
try {
let offset = 0;
let totalThumbs = 0;
// Sequentially fetch thumbnail counts in batches
while (true) {
const data = await this.postAjax('wbcr-rio-calculate-total-thumbs', { offset });
// Update the total thumbnail counter
totalThumbs = data.found_thumbs;
// Update the thumbnails count in the UI
$('#wio-stat-totals__thumbnails')
.removeClass('wio-stat-totals__loading')
.text(totalThumbs);
// Break the loop if the server indicates the process is complete
if (data.done) {
break;
}
// Update the offset for the next request
offset = data.next_offset;
// Validate the offset to avoid infinite loops
if (offset === undefined || offset === null) {
console.error('[Error]: Missing offset in server response.');
throw new Error('Invalid server response: offset is undefined.');
}
}
this.countThumbs = totalThumbs;
} catch (error) {
this.throwError(error);
}
}
/**
* Handles errors by logging them to the console and displaying an alert.
*
* This method provides a standardized way to handle any unexpected errors
* that occur during the execution of the bulk optimization process.
*
* @param {Error|string} error - The error message or object to handle.
*/
throwError(error) {
console.error('[Error]:', error);
alert(this.i18n.generalError || 'An error occurred. Please try again.');
}
}
// Initialize the bulk optimization process on document ready
$(document).ready(() => {
const bulkOptimization = new BulkOptimization(
ajaxurl, // The URL for WordPress AJAX requests
window.wrio_l18n_bulk_page, // Localization data for the UI
window.wrio_settings_bulk_page // Settings data for the optimization
);
bulkOptimization.init();
});
})(jQuery);

View File

@@ -0,0 +1,2 @@
<?php
// silence is golden

View File

@@ -0,0 +1,52 @@
jQuery(function($) {
$('#wbcr-wio-meta-migration-action').on('click', function() {
var data = {
'action': 'wrio_meta_migrations',
'_wpnonce': $(this).data('nonce'),
};
$(this).addClass('disabled').text('Please wait...');
send_request($(this), data);
});
function send_request(button, data) {
$.post(window.ajaxurl, data, function(response) {
console.log(response);
if( !response || !response.data ) {
console.log('An unknown server error has occurred.');
console.log(response);
return false;
}
if( !response.data.need_more_time ) {
if( button.closest('.notice').length ) {
button.closest('.notice').remove();
}
if( button.closest('.alert').length ) {
button.closest('.alert').remove();
}
return false;
}
button.text(response.data.message);
send_request(button, data);
}).fail(function(xhr, status, error) {
console.log(xhr);
console.log(status);
console.log(error);
data.limit = 5;
data.error = 1;
setTimeout(function() {
send_request(button, data);
}, 2000);
});
}
});

View File

@@ -0,0 +1,57 @@
/**
* A set of tools for creating pop-ups. You can create a popup
* using a global method call.
*
* @version 1.0
*/
(function($) {
'use strict';
if( !$.wrio_modal ) {
$.wrio_modal = {};
}
$.wrio_modal = $.wrio_popup || {
showErrorModal: function(text) {
if( !text ) {
console.log('[Error]: Text required.');
return;
}
swal({
title: 'Error',
text: text,
type: 'error',
customClass: 'wrio-modal wrio-modal-error',
width: 500,
confirmButtonText: 'OK',
});
},
showWarningModal: function(text, callback) {
if( !text ) {
console.log('[Error]: Text required.');
return;
}
swal({
title: 'Warning',
text: text,
type: 'warning',
customClass: 'wrio-modal wrio-modal-warning',
width: 500,
showCancelButton: true,
showCloseButton: true,
confirmButtonText: 'OK',
}).then(function(result) {
if( callback ) {
callback();
}
}).catch(swal.noop);
},
};
})(jQuery);

View File

@@ -0,0 +1,209 @@
jQuery(function($){
var ajaxUrl = ajaxurl;
// Delivery Mode Toggle Handler
// Handles the visibility of the delivery mode options based on WebP and AVIF conversion toggles
var $webpToggle = $('input[name="wbcr_io_convert_webp_format"]');
var $avifToggle = $('input[name="wbcr_io_convert_avif_format"]');
var $deliveryModeSection = $('.wrio-conversion-delivery-options');
// Function to check if at least one toggle is enabled
function updateDeliveryModeVisibility() {
var isWebpEnabled = $webpToggle.val() === '1';
var isAvifEnabled = $avifToggle.val() === '1';
// Show delivery mode section only if at least one format is enabled
if (isWebpEnabled || isAvifEnabled) {
$deliveryModeSection.slideDown(300);
} else {
$deliveryModeSection.slideUp(300);
}
}
// Attach event listeners to both toggles
if ($webpToggle.length && $avifToggle.length && $deliveryModeSection.length) {
// Get the button containers for both toggles
var $webpButtons = $webpToggle.closest('.factory-checkbox').find('button');
var $avifButtons = $avifToggle.closest('.factory-checkbox').find('button');
// Initial check on page load
updateDeliveryModeVisibility();
// Listen for clicks on the factory buttons
$webpButtons.on('click', function() {
setTimeout(updateDeliveryModeVisibility, 50);
});
$avifButtons.on('click', function() {
setTimeout(updateDeliveryModeVisibility, 50);
});
// Also listen for direct changes on the hidden inputs (fallback)
$webpToggle.on('change', function() {
updateDeliveryModeVisibility();
});
$avifToggle.on('change', function() {
updateDeliveryModeVisibility();
});
}
$('#wio-restore-backup-btn').on('click', function() {
if ( $('#wio-multisite-mode').length ) {
$('#wio-multisite-mode').toggle();
$('#wio-multisite-confirm').attr('data-action', 'restore');
$('#wio-multisite-restore-progress').empty();
return false;
}
result = confirm( $(this).attr('data-confirm') );
if ( ! result ) {
return false;
}
$(this).hide();
$('#wio-restore-backup-progress').show();
var ai_data = {
'total' : '?',
'action': 'wio_restore_backup',
'_wpnonce': $('#wio-iph-nonce').val()
};
send_post_data(ai_data);
return false;
});
$('#wio-clear-backup-btn').on('click', function() {
$('#wio-restore-backup-msg').hide();
if ( $('#wio-multisite-mode').length ) {
$('#wio-multisite-mode').toggle();
$('#wio-multisite-confirm').attr('data-action', 'clear');
$('#wio-multisite-restore-progress').empty();
return false;
}
result = confirm( $(this).attr('data-confirm') );
if ( ! result ) {
return false;
}
var data = {
'action': 'wio_clear_backup',
'_wpnonce': $('#wio-iph-nonce').val()
};
$.post(ajaxUrl, data, function(response) {
$('#wio-clear-backup-msg').show();
});
});
$('#wio-multisite-confirm').on('click', function() {
var action = $(this).attr('data-action');
// если запущена очистка резервных копий
if ( action == 'clear' ) {
result = confirm( $('#wio-clear-backup-btn').attr('data-confirm') ); // берём сообщение из основной кнопки
if ( ! result ) {
return false;
}
var blogs = [];
$('.wbcr_io_multisite_blogs:checked').each(function() {
blogs.push( $(this).val() );
});
var data = {
'action': 'wio_clear_backup',
'_wpnonce': $('#wio-iph-nonce').val(),
'blogs': blogs
};
$.post(ajaxUrl, data, function(response) {
$('#wio-clear-backup-msg').show();
$('#wio-multisite-mode').toggle();
});
return false;
}
// если запущено восстановление из резервных копий
if ( action == 'restore' ) {
result = confirm( $('#wio-restore-backup-btn').attr('data-confirm') ); // берём сообщение из основной кнопки
if ( ! result ) {
return false;
}
$('#wio-multisite-mode').toggle();
$('#wio-multisite-restore-progress').empty();
$('.wbcr_io_multisite_blogs:checked').each(function() {
$('#wio-multisite-restore-progress').append('\
<label>'+$(this).attr('data-name')+'</label>\
<div class="progress">\
<div id="wio-restore-backup-progress-'+$(this).val()+'" class="wio-restore-backup-progressbar progress-bar progress-bar-success" data-id="'+$(this).val()+'" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width:0%">\
</div>\
</div>\
');
});
$('#wio-multisite-restore-progress').show();
if ( ! $('.wio-restore-backup-progressbar').length ) {
$('#wio-restore-backup-msg').show();
return false;
}
var ai_data = {
'total' : '?',
'action': 'wio_restore_backup',
'_wpnonce': $('#wio-iph-nonce').val(),
'blog_id': $('.wio-restore-backup-progressbar:eq(0)').attr('data-id')
};
send_multisite_post_data(ai_data);
return false;
}
});
$('#wbcr_io_multisite_blog_all').on('change', function() {
if ( $(this).attr('checked') == 'checked' ) {
$('.wbcr_io_multisite_blogs').attr('checked', true);
} else {
$('.wbcr_io_multisite_blogs').removeAttr('checked');
}
});
$('.wbcr_io_multisite_blogs').on('change', function() {
var all_checked = true;
$('.wbcr_io_multisite_blogs').each(function() {
if ( $(this).attr('checked') != 'checked' ) {
all_checked = false;
}
});
if ( all_checked ) {
$('#wbcr_io_multisite_blog_all').attr('checked', true);
} else {
$('#wbcr_io_multisite_blog_all').removeAttr('checked');
}
});
function send_post_data(data){
$.post(ajaxUrl, data, function(response) {
if ( ! response.end ) {
data.total = response.total;
send_post_data(data);
$('#wio-restore-backup-progress').find('.progress-bar').css( 'width', response.percent + '%' );
} else {
$('#wio-restore-backup-progress').find('.progress-bar').css( 'width', '100%' );
$('#wio-restore-backup-msg').show();
}
});
}
function send_multisite_post_data(data){
$.post(ajaxUrl, data, function(response) {
if ( ! response.end ) {
data.total = response.total;
send_multisite_post_data(data);
$('#wio-restore-backup-progress-' + data.blog_id).css( 'width', response.percent + '%' );
} else {
$('#wio-restore-backup-progress-' + data.blog_id).css( 'width', '100%' ).removeClass('wio-restore-backup-progressbar');
if ( $('.wio-restore-backup-progressbar').length ) {
var ai_data = {
'total' : '?',
'action': 'wio_restore_backup',
'_wpnonce': $('#wio-iph-nonce').val(),
'blog_id': $('.wio-restore-backup-progressbar:eq(0)').attr('data-id')
};
send_multisite_post_data(ai_data);
} else {
$('#wio-restore-backup-msg').show();
}
}
});
}
});

View File

@@ -0,0 +1,5 @@
jQuery(document).ready(function($) {
// Disable premium dropdown buttons for non-licensed users
$('button[data-value="googlepage"]').attr('disabled', 'disabled');
$('button[data-value="background"]').attr('disabled', 'disabled');
});

View File

@@ -0,0 +1,102 @@
jQuery(function($) {
var ajaxUrl = ajaxurl;
$(document).on('click', '.wio-reoptimize', function() {
var ai_data = {
'action' : $(this).attr('data-action'),
'id' : $(this).attr('data-id'),
'level' : $(this).attr('data-level'),
'_wpnonce' : $(this).attr('data-nonce')
};
var td = $(this).closest('td');
var msg = $(this).attr( 'data-waiting-label' );
td.html('<p>'+msg+'</p>');
wio_reoptimize( ai_data, td );
return false;
});
$(document).on('click', '.wio-convert', function() {
var ai_data = {
'action' : $(this).attr('data-action'),
'id' : $(this).attr('data-id'),
'format' : $(this).attr('data-format'),
'_wpnonce' : $(this).attr('data-nonce')
};
var td = $(this).closest('td');
var msg = $(this).attr( 'data-waiting-label' );
td.html('<p>'+msg+'</p>');
wio_convert( ai_data, td );
return false;
});
function wio_reoptimize( ai_data, td ) {
$.post(ajaxUrl, ai_data, function(response) {
if ( response === 'processing' ) {
wio_reoptimize( ai_data, td );
return false;
}
td.html(response);
var btn = $('.wio-reoptimize').first();
if ( btn.closest('.media-frame-content').length ) {
if ( btn.closest('table').find('.wio-datas-list').length ) {
var diminsionName = $('.dimensions').find('strong').clone();
var fileSizeName = $('.file-size').find('strong').clone();
var diminsionSize = btn.closest('table').find('.wio-datas-list').data('dimensions');
var fileSize = btn.closest('table').find('.wio-datas-list').data('size');
$('.dimensions').html(diminsionName.get(0).outerHTML + ' ' + diminsionSize);
$('.file-size').html(fileSizeName.get(0).outerHTML + ' ' + fileSize);
}
}
});
}
function wio_convert( ai_data, td ) {
$.post(ajaxUrl, ai_data, function(response) {
if ( response === 'processing' ) {
wio_convert( ai_data, td );
return false;
}
td.html(response);
var btn = $('.wio-convert').first();
if ( btn.closest('.media-frame-content').length ) {
if ( btn.closest('table').find('.wio-datas-list').length ) {
var diminsionName = $('.dimensions').find('strong').clone();
var fileSizeName = $('.file-size').find('strong').clone();
var diminsionSize = btn.closest('table').find('.wio-datas-list').data('dimensions');
var fileSize = btn.closest('table').find('.wio-datas-list').data('size');
$('.dimensions').html(diminsionName.get(0).outerHTML + ' ' + diminsionSize);
$('.file-size').html(fileSizeName.get(0).outerHTML + ' ' + fileSize);
}
}
});
}
$(document).on('click', '.button-wio-restore', function() {
var ai_data = {
'action' : $(this).attr('data-action'),
'id' : $(this).attr('data-id'),
'_wpnonce' : $(this).attr('data-nonce')
};
var td = $(this).closest('td');
var msg = $(this).attr( 'data-waiting-label' );
td.html('<p>'+msg+'</p>');
$.post(ajaxUrl, ai_data, function(response) {
td.html(response);
var btn = $('.wio-reoptimize');
if ( btn.closest('.media-frame-content').length ) {
if ( btn.length ) {
btn = btn.first();
var diminsionName = $('.dimensions').find('strong').clone();
var fileSizeName = $('.file-size').find('strong').clone();
var diminsionSize = btn.data('dimensions');
var fileSize = btn.data('size');
$('.dimensions').html(diminsionName.get(0).outerHTML + ' ' + diminsionSize);
$('.file-size').html(fileSizeName.get(0).outerHTML + ' ' + fileSize);
}
}
});
return false;
});
});

View File

@@ -0,0 +1,113 @@
jQuery(function ($) {
var chart_html_id = 'wio-main-chart';
var webp_chart_html_id = 'wio-webp-chart';
var avif_chart_html_id = 'wio-avif-chart';
var ctx = document.getElementById(chart_html_id);
var ctx_webp = document.getElementById(webp_chart_html_id);
var ctx_avif = document.getElementById(avif_chart_html_id);
window.wio_chart = new window.robin.Chart(ctx, {
type: 'doughnut',
data: {
datasets: [
{
data: [
$('#' + chart_html_id).attr('data-errors'),
$('#' + chart_html_id).attr('data-optimized'),
$('#' + chart_html_id).attr('data-unoptimized'),
],
backgroundColor: [
'#f1b1b6',
'#8bc34a',
'#d6d6d6',
],
borderWidth: 0,
label: 'Dataset 1'
}
]
},
options: {
legend: {
display: false
},
events: [],
animation: {
easing: 'easeOutBounce'
},
responsive: false,
cutoutPercentage: 80
}
});
if (ctx_webp) {
window.wio_chart_webp = new window.robin.Chart(ctx_webp, {
type: 'doughnut',
data: {
datasets: [
{
data: [
$('#' + webp_chart_html_id).attr('data-errors'),
$('#' + webp_chart_html_id).attr('data-optimized'),
$('#' + webp_chart_html_id).attr('data-unoptimized'),
],
backgroundColor: [
'#f1b1b6',
'#8bc34a',
'#d6d6d6',
],
borderWidth: 0,
label: 'Dataset 1'
}
]
},
options: {
legend: {
display: false
},
events: [],
animation: {
easing: 'easeOutBounce'
},
responsive: false,
cutoutPercentage: 80
}
});
}
if (ctx_avif) {
window.wio_chart_avif = new window.robin.Chart(ctx_avif, {
type: 'doughnut',
data: {
datasets: [
{
data: [
$('#' + avif_chart_html_id).attr('data-errors'),
$('#' + avif_chart_html_id).attr('data-optimized'),
$('#' + avif_chart_html_id).attr('data-unoptimized'),
],
backgroundColor: [
'#f1b1b6',
'#8bc34a',
'#d6d6d6',
],
borderWidth: 0,
label: 'Dataset 1'
}
]
},
options: {
legend: {
display: false
},
events: [],
animation: {
easing: 'easeOutBounce'
},
responsive: false,
cutoutPercentage: 80
}
});
}
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,148 @@
/**
* License Manager JavaScript
*
* Handles license activation, deactivation, sync, and unsubscribe actions.
* This is a lightweight replacement for clearfy-license-manager.js
*
* @package Robin_Image_Optimizer
*/
jQuery(function($) {
'use strict';
/**
* Handle license action button clicks
*/
$(document).on('click', '.wrio-license-btn', function(e) {
e.preventDefault();
// Remove any existing notices when user tries again
$('.wrio-license-notice').remove();
var $button = $(this),
$wrapper = $('#wrio-license-wrapper'),
action = $button.data('action'),
nonce = $wrapper.data('nonce'),
loaderUrl = $wrapper.data('loader');
// Disable all buttons and show loader inside the clicked button
$('.wrio-license-btn').prop('disabled', true);
$button.prepend('<img class="wrio-loader" src="' + loaderUrl + '" alt="Loading..." style="height: 16px; vertical-align: middle; margin-right: 8px;">');
// Build request data
var data = {
action: 'wrio_license_action',
_wpnonce: nonce,
license_action: action,
licensekey: ''
};
// Include license key for activation
if (action === 'activate') {
data.licensekey = $('#license-key').val().trim();
if (!data.licensekey) {
showNotice('Please enter a license key.', 'error');
resetButtons();
return;
}
}
// Send AJAX request
$.ajax({
url: ajaxurl,
type: 'POST',
dataType: 'json',
data: data,
success: function(response) {
if (response && response.success) {
showNotice(response.data.message, 'success');
// Reload page to show updated license state
setTimeout(function() {
window.location.reload();
}, 1000);
} else {
var errorMsg = response && response.data && response.data.message
? response.data.message
: 'An error occurred. Please try again.';
showNotice(errorMsg, 'error');
resetButtons();
}
},
error: function(xhr, status, error) {
console.error('WRIO License AJAX Error:', {
status: xhr.status,
statusText: xhr.statusText,
responseText: xhr.responseText,
error: error
});
var errorMsg = 'Connection error. Please check your internet connection and try again.';
if (xhr.responseText) {
try {
var response = JSON.parse(xhr.responseText);
if (response.data && response.data.message) {
errorMsg = response.data.message;
}
} catch (e) {
// Response wasn't JSON
}
}
showNotice(errorMsg, 'error');
resetButtons();
}
});
});
/**
* Reset buttons to their original state
*/
function resetButtons() {
$('.wrio-loader').remove();
$('.wrio-license-btn').prop('disabled', false);
}
/**
* Show a notice message
*
* @param {string} message The message to display
* @param {string} type Notice type: 'success' or 'error'
*/
function showNotice(message, type) {
// Remove any existing notices
$('.wrio-license-notice').remove();
var typeClass = type === 'success' ? 'wrio-license-notice--success' : 'wrio-license-notice--error';
var $notice = $('<div class="wrio-license-notice ' + typeClass + '"><p>' + escapeHtml(message) + '</p></div>');
// Insert into the error container
$('#license-form-error-container').html($notice);
// Auto-dismiss after 5 seconds for success messages
if (type === 'success') {
setTimeout(function() {
$notice.fadeOut(function() {
$(this).remove();
});
}, 5000);
}
}
/**
* Escape HTML entities
*
* @param {string} text Text to escape
* @return {string} Escaped text
*/
function escapeHtml(text) {
var map = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
};
return String(text).replace(/[&<>"']/g, function(m) { return map[m]; });
}
});

View File

@@ -0,0 +1,355 @@
<?php
/**
* Admin boot
*
* @version 1.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Проверяем таблицу в базе данных
*
* Если таблица не существует или её структура устарела, то обновляем.
* Проверка проводится при каждой инициализации плагина т.к. структура может измениться
* после очередного обновления плагина.
*
* @return bool
*/
add_action(
'admin_init',
function () {
RIO_Process_Queue::try_create_plugin_tables();
}
);
/**
*
* @since 1.3.0
*/
add_filter(
'wbcr/clearfy/components/items_list',
function ( $components ) {
if ( wrio_is_clearfy_license_activate() ) {
return $components;
}
if ( ! empty( $components ) ) {
foreach ( $components as $key => $component ) {
if ( 'robin_image_optimizer' == $component['name'] ) {
unset( $components[ $key ] );
}
}
}
return $components;
}
);
/**
* Добавляет карточку компонента на страницу компонентов
*
* @since 1.3.0
*/
add_action(
'wbcr/clearfy/components/custom_plugins_card',
function () {
if ( ! wrio_is_clearfy_license_activate() ) {
$view = WRIO_Views::get_instance( WRIO_PLUGIN_DIR );
$view->print_template( 'clearfy-component-card' );
}
}
);
/**
* We asset migration scripts to all admin panel pages
*
* @since 1.3.0
*/
add_action(
'admin_enqueue_scripts',
function () {
if ( ! current_user_can( 'update_plugins' ) || ! wbcr_rio_has_meta_to_migrate() ) {
return;
}
wp_enqueue_script(
'wrio-meta-migrations',
WRIO_PLUGIN_URL . '/admin/assets/js/meta-migrations.js',
[
'jquery',
'wbcr-factory-clearfy-000-global',
],
WRIO_Plugin::app()->getPluginVersion()
);
}
);
/**
* Plugin was heavy migrated into new architecture. Specifically, post meta was moved to separate table and
* therefore it is required to migrate all of them to new table.
*
* This action prints a notice, which contains clickable link with JS onclick event, which invokes AJAX request
* to migrate these post metas to new table.
*
* Once all post meta migrated, notice would not be shown anymore.
*
* @param $notices
*
* @return array
* @since 1.3.0
*
* @see wbcr_rio_migrate_postmeta_to_process_queue() for further information about AJAX processing function.
* @see wbcr_rio_has_meta_to_migrate() used to check whether to show notice or not.
*
* @see RIO_Process_Queue for further information about new table.
*/
add_action(
'wbcr/factory/admin_notices',
function ( $notices ) {
if ( ! current_user_can( 'update_plugins' ) || ! wbcr_rio_has_meta_to_migrate() ) {
return $notices;
}
$notices[] = [
'id' => WRIO_Plugin::app()->getPrefix() . 'meta_to_migration',
'type' => 'warning',
'dismissible' => false,
'dismiss_expires' => 0,
'text' => '<p><b>' . WRIO_Plugin::app()->getPluginTitle() . ':</b> ' . wrio_get_meta_migration_notice_text() . '</p>',
];
return $notices;
}
);
/**
* Plugin was heavy migrated into new architecture. Specifically, post meta was moved to separate table and
* therefore it is required to migrate all of them to new table.
*
* This action prints a notice, which contains clickable link with JS onclick event, which invokes AJAX request
* to migrate these post metas to new table.
*
* Once all post meta migrated, notice would not be shown anymore.
*
* @param Wbcr_Factory480_Plugin $plugin
* @param Wbcr_FactoryPages480_ImpressiveThemplate $obj
*
* @since 1.3.0
*
* @see wbcr_rio_migrate_postmeta_to_process_queue() for further information about AJAX processing function.
* @see wbcr_rio_has_meta_to_migrate() used to check whether to show notice or not.
*
* @see RIO_Process_Queue for further information about new table.
*/
add_action(
'wbcr/factory/pages/impressive/print_all_notices',
function ( $plugin, $obj ) {
if ( ( $plugin->getPluginName() != WRIO_Plugin::app()->getPluginName() ) || ! wbcr_rio_has_meta_to_migrate() ) {
return;
}
$obj->printWarningNotice( wrio_get_meta_migration_notice_text() );
},
10,
2
);
/***
* Flush configuration after saving the settings
*
* @param WRIO_Plugin $plugin
* @param Wbcr_FactoryPages480_ImpressiveThemplate $obj
*
* @return bool
*/
/*
add_action('wbcr_factory_480_imppage_after_form_save', function ($plugin, $obj) {
$is_rio = WRIO_Plugin::app()->getPluginName() == $plugin->getPluginName();
if( $is_rio ) {
WRIO_Cron::check();
}
}, 10, 2);*/
/**
* Виджет отзывов
*
* @param string $page_url
* @param string $plugin_name
*
* @return string
*/
function wio_rating_widget_url( $page_url, $plugin_name ) {
if ( $plugin_name == WRIO_Plugin::app()->getPluginName() ) {
return 'https://wordpress.org/support/plugin/robin-image-optimizer/reviews/#new-post';
}
return $page_url;
}
add_filter( 'wbcr_factory_pages_480_imppage_rating_widget_url', 'wio_rating_widget_url', 10, 2 );
/**
*
* @param array $widgets
* @param string $position
* @param Wbcr_Factory480_Plugin $plugin
*/
add_filter(
'wbcr/factory/pages/impressive/widgets',
function ( $widgets, $position, $plugin ) {
if ( $plugin->getPluginName() == WRIO_Plugin::app()->getPluginName() ) {
require_once WRIO_PLUGIN_DIR . '/admin/includes/sidebar-widgets.php';
if ( wrio_is_license_activate() ) {
unset( $widgets['donate_widget'] );
if ( $position == 'right' ) {
unset( $widgets['adverts_widget'] );
unset( $widgets['business_suggetion'] );
unset( $widgets['rating_widget'] );
unset( $widgets['info_widget'] );
}
/*
if ( $position == 'bottom' ) {
$widgets['support'] = wrio_get_sidebar_support_widget();
}*/
return $widgets;
} elseif ( $position == 'right' ) {
unset( $widgets['info_widget'] );
unset( $widgets['rating_widget'] );
// $widgets['support'] = wrio_get_sidebar_support_widget();
}
}
return $widgets;
},
20,
3
);
/**
* Заменяет заголовок в рекламном виджете
*
* @param array $features
* @param string $plugin_name
* @param string $page_id
*/
add_filter(
'wbcr/clearfy/pages/suggetion_title',
function ( $features, $plugin_name, $page_id ) {
if ( ! empty( $plugin_name ) && ( $plugin_name == WRIO_Plugin::app()->getPluginName() ) ) {
return __( 'ROBIN IMAGE OPTIMIZER PRO', 'robin-image-optimizer' );
}
return $features;
},
20,
3
);
/**
* Заменяем премиум возможности в рекламном виджете
*
* @param array $features
* @param string $plugin_name
* @param string $page_id
*/
add_filter(
'wbcr/clearfy/pages/suggetion_features',
function ( $features, $plugin_name, $page_id ) {
if ( ! empty( $plugin_name ) && ( $plugin_name == WRIO_Plugin::app()->getPluginName() ) ) {
$upgrade_feature = [];
$upgrade_feature[] = __( 'Automatic conversion to WebP', 'robin-image-optimizer' );
$upgrade_feature[] = __( 'You can optimize custom folders', 'robin-image-optimizer' );
$upgrade_feature[] = __( 'Supports NextGen gallery', 'robin-image-optimizer' );
$upgrade_feature[] = __( 'Multisite support', 'robin-image-optimizer' );
$upgrade_feature[] = __( 'Fast optimization servers', 'robin-image-optimizer' );
$upgrade_feature[] = __( 'Ad-free experience', 'robin-image-optimizer' );
$upgrade_feature[] = __( 'Priority support', 'robin-image-optimizer' );
return $upgrade_feature;
}
return $features;
},
20,
3
);
/**
* Заменяем премиум возможности в рекламном виджете
*
* @param array $messages
* @param string $type
* @param string $plugin_name
*/
add_filter(
'wbcr/factory/premium/notice_text',
function ( $text, $type, $plugin_name ) {
if ( WRIO_Plugin::app()->getPluginName() != $plugin_name ) {
return $text;
}
$license_page_url = WRIO_Plugin::app()->getPluginPageUrl( 'rio_license' );
if ( null === $license_page_url ) {
return $text;
}
if ( 'need_activate_license' == $type ) {
return sprintf(
// translators: %1$s is opening <a> tag, %2$s is closing </a> tag.
__( '%1$sLicense activation%2$s required. A license is required to get premium plugin updates, as well as to get additional services.', 'robin-image-optimizer' ),
'<a href="' . esc_url( $license_page_url ) . '">',
'</a>'
);
} elseif ( 'need_renew_license' == $type ) {
return sprintf(
// translators: %1$s is opening <a> tag, %2$s is closing </a> tag.
__( 'Your %1$slicense%2$s has expired. You can no longer get premium plugin updates, premium support and your access to services has been suspended.', 'robin-image-optimizer' ),
'<a href="' . esc_url( $license_page_url ) . '">',
'</a>'
);
}
return $text;
},
10,
3
);
/**
* Check if the AVIF upsell banner has been dismissed by the current user.
*
* @return bool True if dismissed, false otherwise.
*/
function wrio_is_avif_banner_dismissed() {
return (bool) get_user_meta( get_current_user_id(), 'wrio_avif_banner_dismissed', true );
}
/**
* AJAX handler for dismissing the AVIF upsell banner.
*/
add_action(
'wp_ajax_wrio_dismiss_avif_banner',
function () {
check_ajax_referer( 'wrio_dismiss_avif_banner', 'nonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => __( 'Permission denied.', 'robin-image-optimizer' ) ] );
}
// Dismiss permanently.
update_user_meta( get_current_user_id(), 'wrio_avif_banner_dismissed', 1 );
wp_send_json_success();
}
);

View File

@@ -0,0 +1,226 @@
<?php
/**
* Subscribe Widget Class
*
* Self-contained newsletter subscription widget that can be used on any admin page.
* No dependencies on Factory libs.
*
* @package Robin_Image_Optimizer
* @subpackage Admin\Includes
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class WRIO_Subscribe_Widget
*/
class WRIO_Subscribe_Widget {
/**
* ThemeIsle subscription API endpoint
*/
const API_URL = 'https://api.themeisle.com/tracking/subscribe';
/**
* Option name to track subscription status
*/
const OPTION_SUBSCRIBED = 'wrio_user_subscribed';
/**
* Plugin slug for API
*
* @var string
*/
private $plugin_name = 'wbcr_image_optimizer';
/**
* Privacy policy URL
*
* @var string
*/
private $privacy_url = 'https://themeisle.com/privacy-policy/';
/**
* Constructor
*/
public function __construct() {
add_action( 'wp_ajax_wrio_subscribe', [ $this, 'ajax_handler' ] );
}
/**
* Check if user has already subscribed
*
* @return bool
*/
public function is_subscribed() {
return (bool) get_option( self::OPTION_SUBSCRIBED, false );
}
/**
* Render the subscribe widget
*
* @return void
*/
public function render() {
if ( $this->is_subscribed() ) {
return;
}
$nonce = wp_create_nonce( 'wrio_subscribe' );
?>
<div class="wrio-subscribe-widget">
<div class="wrio-subscribe-widget__header">
<h3><?php esc_html_e( 'Subscribe to plugin\'s newsletter', 'robin-image-optimizer' ); ?></h3>
</div>
<div class="wrio-subscribe-widget__body">
<p><?php esc_html_e( 'Get the latest news and updates about the plugin:', 'robin-image-optimizer' ); ?></p>
<div class="wrio-subscribe-widget__messages">
<div class="wrio-subscribe-widget__success" style="display:none;">
<?php esc_html_e( 'Thank you for subscribing.', 'robin-image-optimizer' ); ?>
</div>
<div class="wrio-subscribe-widget__error" style="display:none;"></div>
</div>
<form class="wrio-subscribe-widget__form">
<div class="wrio-subscribe-widget__field-wrap">
<input
type="email"
name="email"
class="wrio-subscribe-widget__email"
placeholder="<?php esc_attr_e( 'Enter your email address', 'robin-image-optimizer' ); ?>"
required
>
<button type="submit" class="button button-primary wrio-subscribe-widget__button">
<?php esc_html_e( 'Subscribe', 'robin-image-optimizer' ); ?>
</button>
</div>
<label class="wrio-subscribe-widget__checkbox-label">
<input type="checkbox" name="agree_terms" checked required>
<?php
printf(
/* translators: %1$s: opening link tag, %2$s: closing link tag */
esc_html__( 'I agree to receive the Themeisle newsletter. See our %1$sPrivacy Policy%2$s for details.', 'robin-image-optimizer' ),
'<a href="' . esc_url( $this->privacy_url ) . '" target="_blank" rel="noopener">',
'</a>'
);
?>
</label>
</form>
</div>
</div>
<script>
(function() {
const form = document.querySelector('.wrio-subscribe-widget__form');
if (!form) return;
form.addEventListener('submit', function(e) {
e.preventDefault();
const button = form.querySelector('.wrio-subscribe-widget__button');
const successEl = document.querySelector('.wrio-subscribe-widget__success');
const errorEl = document.querySelector('.wrio-subscribe-widget__error');
const email = form.querySelector('[name="email"]').value;
const agreed = form.querySelector('[name="agree_terms"]').checked;
if (!agreed) {
return;
}
button.disabled = true;
button.textContent = '<?php echo esc_js( __( 'Subscribing...', 'robin-image-optimizer' ) ); ?>';
errorEl.style.display = 'none';
const data = new FormData();
data.append('action', 'wrio_subscribe');
data.append('email', email);
data.append('_wpnonce', '<?php echo esc_js( $nonce ); ?>');
fetch(ajaxurl, {
method: 'POST',
body: data
})
.then(r => r.json())
.then(res => {
if (res.success) {
form.style.display = 'none';
successEl.style.display = 'block';
} else {
errorEl.textContent = res.data.message || '<?php echo esc_js( __( 'An error occurred. Please try again.', 'robin-image-optimizer' ) ); ?>';
errorEl.style.display = 'block';
button.disabled = false;
button.textContent = '<?php echo esc_js( __( 'Subscribe', 'robin-image-optimizer' ) ); ?>';
}
})
.catch(() => {
errorEl.textContent = '<?php echo esc_js( __( 'An error occurred. Please try again.', 'robin-image-optimizer' ) ); ?>';
errorEl.style.display = 'block';
button.disabled = false;
button.textContent = '<?php echo esc_js( __( 'Subscribe', 'robin-image-optimizer' ) ); ?>';
});
});
})();
</script>
<?php
}
/**
* Handle AJAX subscription request
*
* @return void
*/
public function ajax_handler() {
check_ajax_referer( 'wrio_subscribe', '_wpnonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => __( 'Permission denied.', 'robin-image-optimizer' ) ] );
}
$email = isset( $_POST['email'] ) ? sanitize_email( wp_unslash( $_POST['email'] ) ) : '';
if ( ! is_email( $email ) ) {
wp_send_json_error( [ 'message' => __( 'Please enter a valid email address.', 'robin-image-optimizer' ) ] );
}
$body = wp_json_encode(
[
'slug' => $this->plugin_name,
'site' => home_url(),
'email' => $email,
]
);
// Ensure body is a string, not false.
if ( false === $body ) {
wp_send_json_error( [ 'message' => __( 'Failed to encode request body.', 'robin-image-optimizer' ) ] );
}
$response = wp_remote_post(
self::API_URL,
[
'timeout' => 10,
'headers' => [
'Content-Type' => 'application/json',
'Cache-Control' => 'no-cache',
'Accept' => 'application/json, */*;q=0.1',
],
'body' => $body,
]
);
if ( is_wp_error( $response ) ) {
wp_send_json_error( [ 'message' => $response->get_error_message() ] );
}
$body = wp_remote_retrieve_body( $response );
$data = json_decode( $body, true );
if ( isset( $data['code'] ) ) {
update_option( self::OPTION_SUBSCRIBED, 1 );
wp_send_json_success( [ 'message' => __( 'Subscribed successfully!', 'robin-image-optimizer' ) ] );
}
wp_send_json_error( [ 'message' => __( 'Subscription failed. Please try again.', 'robin-image-optimizer' ) ] );
}
}

View File

@@ -0,0 +1,60 @@
<?php
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Класс используется для вывода страницы лендинга
*
* @version 1.0
*/
class WIO_NextgenLanding {
/**
* Инициализация лендинга
*/
public function __construct() {
add_action( 'admin_menu', [ $this, 'removeSubMenu' ], 99999 );
add_action( 'admin_menu', [ $this, 'addSubMenu' ], 20 );
}
/**
* Удаляет лендинг nextgen
*/
public function removeSubMenu() {
remove_submenu_page( 'nextgen-gallery', 'ngg_imagify' );
}
/**
* Добавляем свою страницу в меню Тextgen
*/
public function addSubMenu() {
add_submenu_page(
'nextgen-gallery',
__( 'Image optimizer', 'robin-image-optimizer' ),
__( 'Image optimizer', 'robin-image-optimizer' ),
'manage_options',
'ngg_robin', // если взять старый слаг ngg_imagify, то на странице выведет оба лендинга
[ $this, 'nngLandingPage' ]
);
}
/**
* Контент лендинга
*/
public function nngLandingPage() {
// если активна премиум версия - делаем редирект на страницу статистики nextgen
if ( defined( 'WRIOP_PLUGIN_ACTIVE' ) && WRIOP_PLUGIN_ACTIVE ) {
wp_redirect( admin_url( 'admin.php?page=io_nextgen_gallery_statistic-wbcr_image_optimizer' ) );
die();
}
?>
рекламма установки премиум аддона
<?php
}
}
new WIO_NextgenLanding();

View File

@@ -0,0 +1,405 @@
<?php
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Класс реализует шаблон блока статистики
*
* @version 1.0
*/
class WIO_OptimizePageTemplate {
/**
* Тип страницы
*/
protected $page_type = 'media-library';
public function __construct( $type = 'media-library' ) {
$this->page_type = $type;
}
/**
* Выводит контент страницы с учётом мультисайта
*
* @param WRIO_Page $page
*
* @throws Exception
*/
/*
public function showPageContent( WRIO_Page $page ) {
do_action( 'wbcr/rio/multisite_current_blog' );
$this->pageContent( $page );
do_action( 'wbcr/rio/multisite_restore_blog' );
}*/
/**
* Выбор сайта для мультисайт режима
*/
/*
public function selectSite() {
if ( ! WRIO_Plugin::app()->isNetworkAdmin() ) {
return;
}
$blogs = WIO_Multisite::getBlogs( $this->page_type );
$current_blog = WRIO_Plugin::app()->getPopulateOption( 'current_blog', 1 );
?>
<select style="width:200px;display:inline-block; height: 45px; margin-left:40px;" id="wbcr-rio-current-blog"
class="factory-dropdown factory-from-control-dropdown form-control"
data-context="<?php echo esc_attr( $this->page_type ); ?>"
data-nonce="<?php echo wp_create_nonce( 'update_blog_id' ); ?>">
<?php foreach ( $blogs as $blog ) : ?>
<?php
$blog_name = $blog->domain . $blog->path;
if ( defined( 'SUBDOMAIN_INSTALL' ) && SUBDOMAIN_INSTALL ) {
$blog_name = $blog->domain;
}
?>
<option <?php selected( $current_blog, $blog->blog_id ); ?>
value="<?php echo esc_attr( $blog->blog_id ); ?>"><?php echo esc_attr( $blog_name ); ?></option>
<?php endforeach; ?>
</select>
<?php
}*/
/**
* Возвращает html код блока ручной оптимизации
*
* @param array $params {
* Параметры
*
* @type int $attachment_id Attachment post ID
* @type bool $is_optimized Оптимизировано ли изображение
* @type string $attach_dimensions Размеры изображения. Например 200x150
* @type int $attachment_file_size Размер оригинального основного файла в байтах
* @type bool $is_skipped Пропущено ли изображение. Изображения с таким флагом больше не участвуют в
* оптимизации
* @type int $optimized_size Оптимизированный размер основного файла + превьюшек в байтах
* @type int $original_size Оригинальный размер основного файла + превьюшек в байтах
* @type int $original_main_size Оригинальный размер основного файла в байтах
* @type int $thumbnails_optimized Кол-во оптимизированных превьюшек
* @type string $optimization_level Уровень оптимизации
* @type string $error_msg Текст ошибки
* @type bool $backuped Сделана ли резервная копия
* @type float $diff_percent Разница между оригиналом и оптимизацией в процентах
* @type float $diff_percent_all Общая оптимизация в процентах
* }
*
* @return string
*/
public function getMediaColumnTemplate( $params ) {
ob_start();
$ajaxActionOptimize = apply_filters( 'wbcr/rio/optimize_template/reoptimize_ajax_action', 'wio_reoptimize_image', $this->page_type );
$ajaxActionConvert = apply_filters( 'wbcr/rio/optimize_template/convert_ajax_action', 'wio_convert_image', $this->page_type );
$ajaxActionRestore = apply_filters( 'wbcr/rio/optimize_template/restore_ajax_action', 'wio_restore_image', $this->page_type );
$attachment_id = $params['attachment_id'];
$is_optimized = $params['is_optimized'];
$attach_dimensions = $params['attach_dimensions'];
$attachment_file_size = $params['attachment_file_size'];
$is_skipped = $params['is_skipped'];
$is_supported_format = isset( $params['is_supported_format'] ) ? $params['is_supported_format'] : true;
$webp_size = $params['webp_size'];
$avif_size = isset( $params['avif_size'] ) ? $params['avif_size'] : 0;
$webp_percent = isset( $params['webp_percent'] ) ? $params['webp_percent'] : 0;
$avif_percent = isset( $params['avif_percent'] ) ? $params['avif_percent'] : 0;
$backuped = isset( $params['backuped'] ) ? $params['backuped'] : false;
if ( $is_skipped ) {
return (string) ob_get_clean();
}
// Don't show buttons for unsupported formats
if ( ! $is_supported_format ) {
return (string) ob_get_clean();
}
if ( $is_optimized ) {
$original_main_size = $params['original_main_size'];
$thumbnails_optimized = $params['thumbnails_optimized'];
$optimization_level = $params['optimization_level'];
$error_msg = $params['error_msg'];
$diff_percent = $params['diff_percent'];
$diff_percent_all = $params['diff_percent_all'];
?>
<ul class="wio-datas-list" data-size="<?php echo esc_attr( size_format( $attachment_file_size ) ); ?>"
data-dimensions="<?php echo esc_attr( $attach_dimensions ); ?>">
<li class="wio-data-item"><span
class="data"><?php _e( 'New Filesize:', 'robin-image-optimizer' ); ?></span>
<strong class="big"><?php echo esc_attr( size_format( $attachment_file_size, 1 ) ); ?></strong>
<span class="wio-chart-value">(<?php echo esc_attr( $diff_percent ); ?>%)</span></li>
<?php if ( $webp_size ) : ?>
<li class="wio-data-item"><span
class="data"><?php _e( 'WebP Filesize:', 'robin-image-optimizer' ); ?></span>
<strong class="big"><?php echo esc_attr( size_format( $webp_size, 1 ) ); ?></strong>
<span class="wio-chart-value">(<?php echo esc_attr( $webp_percent ); ?>%)</span></li>
<?php endif; ?>
<?php if ( $avif_size ) : ?>
<li class="wio-data-item"><span
class="data"><?php _e( 'AVIF Filesize:', 'robin-image-optimizer' ); ?></span>
<strong class="big"><?php echo esc_attr( size_format( $avif_size, 1 ) ); ?></strong>
<span class="wio-chart-value">(<?php echo esc_attr( $avif_percent ); ?>%)</span></li>
<?php endif; ?>
<li class="wio-data-item">
<span class="data"><?php _e( 'Original Filesize:', 'robin-image-optimizer' ); ?></span>
<strong class="original"><?php echo esc_attr( size_format( $original_main_size, 1 ) ); ?></strong>
</li>
<li class="wio-data-item"><span class="data"><?php _e( 'Level:', 'robin-image-optimizer' ); ?></span>
<strong>
<?php
if ( ! $error_msg ) {
// если уровень кастомный от 1 до 100
if ( is_numeric( $optimization_level ) ) {
echo __( 'Custom', 'robin-image-optimizer' ) . ' ' . intval( $optimization_level ) . '%';
} else {
// если уровень один из настроек
if ( $optimization_level == 'normal' ) {
echo __( 'Lossless', 'robin-image-optimizer' );
} elseif ( $optimization_level == 'aggresive' ) {
echo __( 'Lossy', 'robin-image-optimizer' );
} else {
echo __( 'High', 'robin-image-optimizer' );
}
}
}
?>
</strong>
</li>
<li class="wio-data-item">
<span class="data"><?php _e( 'Thumbnails Optimized:', 'robin-image-optimizer' ); ?></span>
<strong class="original"><?php echo intval( $thumbnails_optimized ); ?></strong>
</li>
<li class="wio-data-item">
<span class="data"><?php _e( 'Overall Saving:', 'robin-image-optimizer' ); ?></span>
<strong class="original"><?php echo esc_attr( $diff_percent_all ); ?>%</strong>
</li>
<?php if ( $error_msg ) : ?>
<li class="wio-data-item">
<span class="data"><?php _e( 'Error Message:', 'robin-image-optimizer' ); ?></span>
<strong><?php echo esc_attr( $error_msg ); ?></strong></li>
<?php endif; ?>
</ul>
<div class="wio-datas-actions-links" style="display:inline;">
<?php if ( $optimization_level != 'normal' ) : ?>
<a data-action="<?php echo esc_attr( $ajaxActionOptimize ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-level="normal"
data-nonce="<?php echo wp_create_nonce( 'reoptimize' ); ?>"
href="#"
class="wio-reoptimize button-wio-manual-override-upload"
data-waiting-label="<?php _e( 'Optimization in progress', 'robin-image-optimizer' ); ?>">
<span class="dashicons dashicons-admin-generic"></span>
<span
class="wio-hide-if-small"
>
<?php _e( 'Re-Optimize to:', 'robin-image-optimizer' ); ?>
</span><?php _e( 'Lossless', 'robin-image-optimizer' ); ?>
<span class="wio-hide-if-small"></span>
</a>
<?php endif; ?>
<?php if ( $optimization_level != 'aggresive' ) : ?>
<a data-action="<?php echo esc_attr( $ajaxActionOptimize ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-level="aggresive"
data-nonce="<?php echo wp_create_nonce( 'reoptimize' ); ?>"
href="#"
class="wio-reoptimize button-wio-manual-override-upload"
data-waiting-label="<?php _e( 'Optimization in progress', 'robin-image-optimizer' ); ?>">
<span class="dashicons dashicons-admin-generic"></span>
<span
class="wio-hide-if-small"
>
<?php _e( 'Re-Optimize to:', 'robin-image-optimizer' ); ?>
</span>
<?php _e( 'Lossy', 'robin-image-optimizer' ); ?>
<span class="wio-hide-if-small"></span>
</a>
<?php endif; ?>
<?php if ( $optimization_level != 'ultra' ) : ?>
<a data-action="<?php echo esc_attr( $ajaxActionOptimize ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-level="ultra"
data-nonce="<?php echo wp_create_nonce( 'reoptimize' ); ?>"
href="#"
class="wio-reoptimize button-wio-manual-override-upload"
data-waiting-label="<?php _e( 'Optimization in progress', 'robin-image-optimizer' ); ?>">
<span class="dashicons dashicons-admin-generic"></span>
<span
class="wio-hide-if-small"
>
<?php _e( 'Re-Optimize to:', 'robin-image-optimizer' ); ?>
</span>
<?php _e( 'High', 'robin-image-optimizer' ); ?>
<span class="wio-hide-if-small"></span>
</a>
<?php endif; ?>
<?php // WebP conversion is available to all users ?>
<a data-action="<?php echo esc_attr( $ajaxActionConvert ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-format="webp"
data-nonce="<?php echo wp_create_nonce( 'convert' ); ?>"
href="#"
class="wio-convert button-wio-manual-override-upload"
data-waiting-label="<?php esc_html_e( 'Convert in progress', 'robin-image-optimizer' ); ?>">
<span class="dashicons dashicons-images-alt2"></span>
<?php echo esc_html( $webp_size ? __( 'Re-convert to WebP', 'robin-image-optimizer' ) : __( 'Convert to WebP', 'robin-image-optimizer' ) ); ?>
</a>
<?php // AVIF conversion is a premium-only feature ?>
<?php if ( wrio_is_license_activate() ) : ?>
<a data-action="<?php echo esc_attr( $ajaxActionConvert ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-format="avif"
data-nonce="<?php echo wp_create_nonce( 'convert' ); ?>"
href="#"
class="wio-convert button-wio-manual-override-upload"
data-waiting-label="<?php esc_html_e( 'Convert in progress', 'robin-image-optimizer' ); ?>">
<span class="dashicons dashicons-images-alt2"></span>
<?php echo esc_html( $avif_size ? __( 'Re-convert to AVIF', 'robin-image-optimizer' ) : __( 'Convert to AVIF', 'robin-image-optimizer' ) ); ?>
</a>
<?php endif; ?>
<?php if ( $backuped ) : ?>
<a
href="#" data-action="<?php echo esc_attr( $ajaxActionRestore ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-nonce="<?php echo wp_create_nonce( 'restore' ); ?>"
class="button-wio-restore attachment-has-backup"
data-waiting-label="<?php esc_html_e( 'Recovery in progress', 'robin-image-optimizer' ); ?>"
>
<span class="dashicons dashicons-image-rotate"></span>
<?php esc_html_e( 'Restore original', 'robin-image-optimizer' ); ?>
</a>
<?php endif; ?>
</div>
<!-- .wio-datas-actions-links -->
<?php
} elseif ( $attach_dimensions !== '0 x 0' ) {
// Show full stats view if any conversion exists
if ( $webp_size || $avif_size ) {
?>
<ul class="wio-datas-list" data-size="<?php echo esc_attr( size_format( $attachment_file_size ) ); ?>"
data-dimensions="<?php echo esc_attr( $attach_dimensions ); ?>">
<li class="wio-data-item">
<span class="data"><?php esc_html_e( 'Original Filesize:', 'robin-image-optimizer' ); ?></span>
<strong class="big"><?php echo esc_attr( size_format( $attachment_file_size, 1 ) ); ?></strong>
</li>
<?php if ( $webp_size ) : ?>
<?php $webp_saving = $attachment_file_size ? round( ( $attachment_file_size - $webp_size ) * 100 / $attachment_file_size ) : 0; ?>
<li class="wio-data-item">
<span class="data"><?php esc_html_e( 'WebP Filesize:', 'robin-image-optimizer' ); ?></span>
<strong class="big"><?php echo esc_attr( size_format( $webp_size, 1 ) ); ?></strong>
<span class="wio-chart-value">(<?php echo esc_attr( $webp_saving ); ?>%)</span>
</li>
<?php endif; ?>
<?php if ( $avif_size ) : ?>
<?php $avif_saving = $attachment_file_size ? round( ( $attachment_file_size - $avif_size ) * 100 / $attachment_file_size ) : 0; ?>
<li class="wio-data-item">
<span class="data"><?php esc_html_e( 'AVIF Filesize:', 'robin-image-optimizer' ); ?></span>
<strong class="big"><?php echo esc_attr( size_format( $avif_size, 1 ) ); ?></strong>
<span class="wio-chart-value">(<?php echo esc_attr( $avif_saving ); ?>%)</span>
</li>
<?php endif; ?>
</ul>
<div class="wio-datas-actions-links" style="display:inline;">
<a data-action="<?php echo esc_attr( $ajaxActionOptimize ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-level=""
data-nonce="<?php echo wp_create_nonce( 'reoptimize' ); ?>"
href="#"
class="wio-reoptimize button-wio-manual-override-upload"
data-waiting-label="<?php esc_attr_e( 'Optimization in progress', 'robin-image-optimizer' ); ?>">
<span class="dashicons dashicons-admin-generic"></span>
<?php esc_html_e( 'Optimize', 'robin-image-optimizer' ); ?>
</a>
<?php // WebP conversion is available to all users ?>
<a data-action="<?php echo esc_attr( $ajaxActionConvert ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-format="webp"
data-nonce="<?php echo esc_attr( wp_create_nonce( 'convert' ) ); ?>"
href="#"
class="wio-convert button-wio-manual-override-upload"
data-waiting-label="<?php esc_attr_e( 'Convert in progress', 'robin-image-optimizer' ); ?>">
<span class="dashicons dashicons-images-alt2"></span>
<?php echo esc_html( $webp_size ? __( 'Re-convert to WebP', 'robin-image-optimizer' ) : __( 'Convert to WebP', 'robin-image-optimizer' ) ); ?>
</a>
<?php // AVIF conversion is a premium-only feature ?>
<?php if ( wrio_is_license_activate() ) : ?>
<a data-action="<?php echo esc_attr( $ajaxActionConvert ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-format="avif"
data-nonce="<?php echo esc_attr( wp_create_nonce( 'convert' ) ); ?>"
href="#"
class="wio-convert button-wio-manual-override-upload"
data-waiting-label="<?php esc_attr_e( 'Convert in progress', 'robin-image-optimizer' ); ?>">
<span class="dashicons dashicons-images-alt2"></span>
<?php echo esc_html( $avif_size ? __( 'Re-convert to AVIF', 'robin-image-optimizer' ) : __( 'Convert to AVIF', 'robin-image-optimizer' ) ); ?>
</a>
<?php endif; ?>
<?php if ( $backuped ) : ?>
<a
href="#" data-action="<?php echo esc_attr( $ajaxActionRestore ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-nonce="<?php echo esc_attr( wp_create_nonce( 'restore' ) ); ?>"
class="button-wio-restore attachment-has-backup"
data-waiting-label="<?php esc_attr_e( 'Recovery in progress', 'robin-image-optimizer' ); ?>"
>
<span class="dashicons dashicons-image-rotate"></span>
<?php esc_html_e( 'Restore original', 'robin-image-optimizer' ); ?>
</a>
<?php endif; ?>
</div>
<!-- .wio-datas-actions-links -->
<?php
} else {
// No conversions yet - show buttons
?>
<button
type="button" data-action="<?php echo esc_attr( $ajaxActionOptimize ); ?>"
data-nonce="<?php echo wp_create_nonce( 'reoptimize' ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>" data-level=""
class="wio-reoptimize button button-primary button-large"
data-waiting-label="<?php esc_attr_e( 'Optimization in progress', 'robin-image-optimizer' ); ?>"
data-size="<?php echo esc_attr( size_format( $attachment_file_size ) ); ?>"
data-dimensions="<?php echo esc_attr( $attach_dimensions ); ?>"
>
<?php esc_html_e( 'Optimize', 'robin-image-optimizer' ); ?>
</button>
<?php // WebP conversion is available to all users ?>
<button
type="button" data-action="<?php echo esc_attr( $ajaxActionConvert ); ?>"
data-nonce="<?php echo wp_create_nonce( 'convert' ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-format="webp"
class="wio-convert button button-primary button-large"
data-waiting-label="<?php esc_attr_e( 'Convert in progress', 'robin-image-optimizer' ); ?>"
data-size="<?php echo esc_attr( size_format( $attachment_file_size ) ); ?>"
data-dimensions="<?php echo esc_attr( $attach_dimensions ); ?>"
>
<?php esc_html_e( 'Convert to WebP', 'robin-image-optimizer' ); ?>
</button>
<?php // AVIF conversion is a premium-only feature ?>
<?php if ( wrio_is_license_activate() ) : ?>
<button
type="button" data-action="<?php echo esc_attr( $ajaxActionConvert ); ?>"
data-nonce="<?php echo wp_create_nonce( 'convert' ); ?>"
data-id="<?php echo esc_attr( $attachment_id ); ?>"
data-format="avif"
class="wio-convert button button-primary button-large"
data-waiting-label="<?php esc_attr_e( 'Convert in progress', 'robin-image-optimizer' ); ?>"
data-size="<?php echo esc_attr( size_format( $attachment_file_size ) ); ?>"
data-dimensions="<?php echo esc_attr( $attach_dimensions ); ?>"
>
<?php esc_html_e( 'Convert to AVIF', 'robin-image-optimizer' ); ?>
</button>
<?php endif; ?>
<?php
}
}
return (string) ob_get_clean();
}
}

View File

@@ -0,0 +1,2 @@
<?php
// silence is golden

View File

@@ -0,0 +1,2 @@
<?php
// silence is golden

View File

@@ -0,0 +1,54 @@
<?php
/**
* Sidebar widgets
*
* @version 1.0
*/
/**
* Return support widget markup
*
* @return string
*/
function wrio_get_sidebar_support_widget() {
$free_support_url = 'https://wordpress.org/support/plugin/robin-image-optimizer/';
$support_url = tsdk_utmify( tsdk_translate_link( 'https://themeisle.com/contact/' ), 'bug-security-ticket' );
ob_start();
?>
<div id="wbcr-clr-support-widget" class="wbcr-factory-sidebar-widget">
<p><strong><?php _e( 'Having Issues?', 'robin-image-optimizer' ); ?></strong></p>
<div class="wbcr-clr-support-widget-body">
<p>
<?php _e( 'Need help? Create a support ticket and we\'ll assist you.', 'robin-image-optimizer' ); ?>
</p>
<ul>
<li><span class="dashicons dashicons-sos"></span>
<a href="<?php echo esc_url( $free_support_url ); ?>" target="_blank" rel="noopener">
<?php esc_html_e( 'Get free support', 'robin-image-optimizer' ); ?>
</a>
</li>
<li style="margin-top: 15px;background: #fff4f1;padding: 10px;color: #a58074;">
<span class="dashicons dashicons-warning"></span>
<?php
echo wp_kses_post(
sprintf(
// translators: %1$s is opening <a> tag, %2$s is closing </a> tag
__( 'Found a bug or security issue? %1$sCreate a ticket%2$s for a faster response.', 'robin-image-optimizer' ),
'<a href="' . esc_url( $support_url ) . '" target="_blank" rel="noopener">',
'</a>'
)
);
?>
</li>
</ul>
</div>
</div>
<?php
$output = ob_get_contents();
ob_end_clean();
return $output;
}

View File

@@ -0,0 +1,2 @@
<?php
// silence is golden

View File

@@ -0,0 +1,690 @@
<?php
/**
* License Page class
*
* Self-contained license management page without Factory Templates dependency.
* Reuses existing factory-bootstrap-500 CSS framework.
*
* @package Robin_Image_Optimizer
* @subpackage Admin\Pages
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class WRIO_License_Page_View
*
* Handles the license management admin page.
*/
class WRIO_License_Page_View {
/**
* Page ID
*
* @var string
*/
public $id = 'wrio_license';
/**
* Page hook suffix
*
* @var string|false
*/
private $page_hook;
/**
* Premium provider instance
*
* @var WRIO_Premium_Provider
* @phpstan-ignore-next-line property.onlyRead
*/
private $premium;
/**
* License instance
*
* @var WRIO_License
* @phpstan-ignore-next-line property.onlyRead
*/
private $license;
/**
* Whether premium is activated
*
* @var bool|null
*/
private $is_premium;
/**
* Plan name
*
* @var string
*/
public $plan_name;
/**
* Subscribe widget instance
*
* @var WRIO_Subscribe_Widget
*/
private $subscribe_widget;
/**
* Constructor
*/
public function __construct() {
$this->is_premium = null;
$this->plan_name = __( 'Robin image optimizer Premium', 'robin-image-optimizer' );
// Initialize subscribe widget.
$this->subscribe_widget = new WRIO_Subscribe_Widget();
add_action( 'admin_menu', [ $this, 'register_page' ], 9 );
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_assets' ] );
add_action( 'wp_ajax_wrio_license_action', [ $this, 'ajax_handler' ] );
// Register this page in the Factory navigation menu
$this->register_in_factory_menu();
}
/**
* Register this page in the Factory impressive menu system
*
* This allows the license page to appear in the left navigation bar
* alongside other Factory-registered pages.
*
* @return void
*/
private function register_in_factory_menu() {
global $factory_impressive_page_menu;
$page_url = admin_url( 'admin.php?page=' . $this->id );
$factory_impressive_page_menu['robin-image-optimizer'][ $this->id ] = [
'type' => 'page',
'url' => $page_url,
'title' => __( 'License', 'robin-image-optimizer' ) . ' <span class="dashicons dashicons-admin-network"></span>',
'short_description' => __( 'Product activation', 'robin-image-optimizer' ),
'position' => 10,
'parent' => 'rio_general',
];
}
/**
* Initialize premium data
*
* Called late to ensure WRIO_Plugin is available.
*
* @return void
*/
private function init_premium() {
if ( null !== $this->premium ) {
return;
}
/**
* Initializes the premium provider instance.
*
* @var WRIO_Premium_Provider $premium
*/
$premium = WRIO_Plugin::app()->premium;
$this->premium = $premium;
/**
* Gets the license instance from premium provider.
*
* @var WRIO_License $license
*/
$license = $premium->get_license();
$this->license = $license;
$this->is_premium = $premium->is_activate();
}
/**
* Register the admin page
*
* @return void
*/
public function register_page() {
// Parent slug follows Factory pattern: {page_id}-{plugin_name}
$parent_slug = 'rio_general-robin-image-optimizer';
$this->page_hook = add_submenu_page(
$parent_slug,
__( 'License', 'robin-image-optimizer' ),
__( 'License', 'robin-image-optimizer' ),
'manage_options',
$this->id,
[ $this, 'render_page' ],
90 // Position before About Us (which uses 100)
);
}
/**
* Enqueue page assets
*
* @param string $hook Current admin page hook.
* @return void
*/
public function enqueue_assets( $hook ) {
if ( $this->page_hook !== $hook ) {
return;
}
wp_enqueue_script(
'wrio-license-manager',
WRIO_PLUGIN_URL . '/admin/assets/js/wrio-license-manager.js',
[ 'jquery' ],
WRIO_Plugin::app()->getPluginVersion(),
true
);
// Enqueue the Factory bootstrap core CSS (provides .btn, .form-control, etc.)
wp_enqueue_style(
'wrio-bootstrap-core',
WRIO_PLUGIN_URL . '/libs/factory/bootstrap/assets/css-min/bootstrap.core.min.css',
[],
WRIO_Plugin::app()->getPluginVersion()
);
// Enqueue the license manager CSS from Factory templates
wp_enqueue_style(
'wrio-license-manager',
WRIO_PLUGIN_URL . '/libs/factory/templates/assets/css/license-manager.css',
[ 'wrio-bootstrap-core' ],
WRIO_Plugin::app()->getPluginVersion()
);
// Enqueue the impressive page template CSS for full layout
wp_enqueue_style(
'wrio-impressive-template',
WRIO_PLUGIN_URL . '/libs/factory/templates/pages/templates/impressive/assets/css/impressive.page.template.css',
[ 'wrio-bootstrap-core' ],
WRIO_Plugin::app()->getPluginVersion()
);
// Enqueue subscribe widget CSS.
wp_enqueue_style(
'wrio-subscribe-widget',
WRIO_PLUGIN_URL . '/admin/assets/css/wrio-subscribe-widget.css',
[],
WRIO_Plugin::app()->getPluginVersion()
);
// Hide internal pages from sidebar (Custom Folders, Nextgen Gallery)
wp_add_inline_style(
'wrio-impressive-template',
'#io_folders_statistic-robin-image-optimizer-tab, #io_nextgen_gallery_statistic-robin-image-optimizer-tab { display: none !important; }'
);
}
/**
* Handle AJAX license actions
*
* @return void
*/
public function ajax_handler() {
// Verify nonce
if ( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'wrio_license_action' ) ) {
wp_send_json_error( [ 'message' => __( 'Security check failed.', 'robin-image-optimizer' ) ] );
}
// Check capabilities
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => __( 'You do not have permission to perform this action.', 'robin-image-optimizer' ) ] );
}
$this->init_premium();
$action = isset( $_POST['license_action'] ) ? sanitize_text_field( wp_unslash( $_POST['license_action'] ) ) : '';
$license_key = isset( $_POST['licensekey'] ) ? trim( wp_unslash( $_POST['licensekey'] ) ) : '';
$allowed_actions = [ 'activate', 'deactivate', 'unsubscribe' ];
if ( empty( $action ) || ! in_array( $action, $allowed_actions, true ) ) {
wp_send_json_error( [ 'message' => __( 'Invalid action.', 'robin-image-optimizer' ) ] );
}
try {
switch ( $action ) {
case 'activate':
if ( empty( $license_key ) ) {
wp_send_json_error( [ 'message' => __( 'Please enter a license key.', 'robin-image-optimizer' ) ] );
}
$this->premium->activate( $license_key );
$message = __( 'Your license has been successfully activated.', 'robin-image-optimizer' );
break;
case 'deactivate':
$this->premium->deactivate();
$message = __( 'Your license has been deactivated.', 'robin-image-optimizer' );
break;
case 'unsubscribe':
$this->premium->cancel_paid_subscription();
$message = __( 'Your subscription has been cancelled.', 'robin-image-optimizer' );
break;
default:
wp_send_json_error( [ 'message' => __( 'Unknown action.', 'robin-image-optimizer' ) ] );
}
wp_send_json_success( [ 'message' => $message ] );
} catch ( Exception $e ) {
wp_send_json_error( [ 'message' => $e->getMessage() ] );
}
}
/**
* Render the admin page
*
* @return void
*/
public function render_page() {
$this->init_premium();
$min_height = $this->calculate_menu_height();
?>
<div id="WBCR" class="wrap">
<div class="wbcr-factory-templates-759-impressive-page-template factory-bootstrap-500 factory-fontawesome-000">
<div class="wbcr-factory-page wbcr-factory-page-<?php echo esc_attr( $this->id ); ?>">
<?php $this->render_header(); ?>
<div class="wbcr-factory-left-navigation-bar">
<?php $this->render_page_menu(); ?>
</div>
<div class="wbcr-factory-page-inner-wrap">
<div class="wbcr-factory-content-section wbcr-fullwidth">
<div class="wbcr-factory-content" style="min-height:<?php echo esc_attr( (string) $min_height ); ?>px">
<div id="wrio-license-wrapper"
data-loader="<?php echo esc_url( admin_url( 'images/spinner.gif' ) ); ?>"
data-nonce="<?php echo esc_attr( wp_create_nonce( 'wrio_license_action' ) ); ?>">
<?php $this->render_license_form(); ?>
</div>
</div>
</div>
</div>
</div>
<div class="clearfix"></div>
</div>
</div>
<?php
}
/**
* Calculate minimum height for content based on menu items
*
* @return int
*/
private function calculate_menu_height() {
global $factory_impressive_page_menu;
$menu_scope = 'robin-image-optimizer';
$min_height = 0;
if ( isset( $factory_impressive_page_menu[ $menu_scope ] ) ) {
foreach ( $factory_impressive_page_menu[ $menu_scope ] as $page ) {
if ( ! isset( $page['parent'] ) || empty( $page['parent'] ) ) {
$min_height += 77;
}
}
}
return $min_height;
}
/**
* Render the page header
*
* @return void
*/
private function render_header() {
?>
<div class="wbcr-factory-page-header">
<div class="wbcr-factory-header-logo">
<?php echo esc_html( WRIO_Plugin::app()->getPluginTitle() ); ?>
<span class="version"><?php echo esc_html( WRIO_Plugin::app()->getPluginVersion() ); ?></span>
<span class="dash">—</span>
</div>
<div class="wbcr-factory-header-title">
<h2><?php esc_html_e( 'Page', 'robin-image-optimizer' ); ?>: <?php esc_html_e( 'License', 'robin-image-optimizer' ); ?></h2>
</div>
<div class="wbcr-factory-control">
<?php do_action( 'wbcr_factory_pages_impressive_header', WRIO_Plugin::app()->getPluginName() ); ?>
</div>
</div>
<?php
}
/**
* Render the left navigation menu
*
* @return void
*/
private function render_page_menu() {
global $factory_impressive_page_menu;
$menu_scope = 'robin-image-optimizer';
$self_page_id = $this->id;
if ( ! isset( $factory_impressive_page_menu[ $menu_scope ] ) ) {
return;
}
$page_menu = $factory_impressive_page_menu[ $menu_scope ];
// Sort by position (descending - higher position = higher in menu)
uasort(
$page_menu,
function ( $a, $b ) {
return $b['position'] <=> $a['position'];
}
);
?>
<ul>
<?php
// First, render parent pages
foreach ( $page_menu as $page_screen => $page ) :
if ( ! empty( $page['parent'] ) ) {
continue;
}
$active_tab = ( $page_screen === $self_page_id ) ? ' wbcr-factory-active-tab' : '';
?>
<li class="wbcr-factory-nav-tab<?php echo esc_attr( $active_tab ); ?>">
<a href="<?php echo esc_url( $page['url'] ); ?>"
id="<?php echo esc_attr( $page_screen ); ?>-tab"
class="wbcr-factory-tab__link js-wbcr-factory-tab__link">
<div class="wbcr-factory-tab__title">
<?php echo wp_kses( $page['title'], [ 'span' => [ 'class' => [] ] ] ); ?>
</div>
<?php if ( ! empty( $page['short_description'] ) ) : ?>
<div class="wbcr-factory-tab__short-description">
<?php echo esc_html( $page['short_description'] ); ?>
</div>
<?php endif; ?>
</a>
</li>
<?php endforeach; ?>
<?php
// Then, render child pages
foreach ( $page_menu as $page_screen => $page ) :
if ( empty( $page['parent'] ) ) {
continue;
}
$active_tab = ( $page_screen === $self_page_id ) ? ' wbcr-factory-active-tab' : '';
?>
<li class="wbcr-factory-nav-tab<?php echo esc_attr( $active_tab ); ?>">
<a href="<?php echo esc_url( $page['url'] ); ?>"
id="<?php echo esc_attr( $page_screen ); ?>-tab"
class="wbcr-factory-tab__link js-wbcr-factory-tab__link">
<div class="wbcr-factory-tab__title">
<?php echo wp_kses( $page['title'], [ 'span' => [ 'class' => [] ] ] ); ?>
</div>
<?php if ( ! empty( $page['short_description'] ) ) : ?>
<div class="wbcr-factory-tab__short-description">
<?php echo esc_html( $page['short_description'] ); ?>
</div>
<?php endif; ?>
</a>
</li>
<?php endforeach; ?>
</ul>
<?php
}
/**
* Get license type for CSS class
*
* @return string free|gift|trial|paid
*/
private function get_license_type() {
if ( ! $this->is_premium || null === $this->license ) {
return 'free';
}
if ( $this->license->is_lifetime() ) {
return 'gift';
}
if ( $this->license->get_expiration_time( 'days' ) < 1 ) {
return 'trial';
}
return 'paid';
}
/**
* Get hidden license key (first 8 + last 4 characters)
*
* @return string
*/
private function get_hidden_license_key() {
if ( ! $this->is_premium || null === $this->license ) {
return '';
}
return $this->license->get_masked_key();
}
/**
* Get unified expiration display string
*
* @return string
*/
private function get_expiration_display() {
if ( ! $this->is_premium || null === $this->license ) {
return __( 'N/A', 'robin-image-optimizer' );
}
return $this->license->get_expiration_display();
}
/**
* Render the license form
*
* @return void
*/
private function render_license_form() {
$license_type = $this->get_license_type();
$plan_title = __( 'Free', 'robin-image-optimizer' );
$has_pro = null !== $this->premium && null !== $this->premium->get_plan_id();
if ( $has_pro ) {
$plan_title = __( 'Pro', 'robin-image-optimizer' );
}
$license_status_label = __( 'License', 'robin-image-optimizer' );
?>
<div id="license-manager"
class="factory-bootstrap-500 onp-page-wrap <?php echo esc_attr( $license_type ); ?>-license-manager-content">
<?php if ( ! $has_pro ) : ?>
<?php $this->render_upgrade_banner(); ?>
<?php endif; ?>
<div class="onp-container">
<div class="license-details">
<h3>
<?php echo esc_html( $license_status_label ); ?>
<span class="license-info-badge <?php echo esc_attr( 'license-info-badge--plan-' . ( $has_pro ? 'pro' : 'free' ) ); ?>">
<?php echo esc_html( $plan_title ); ?>
</span>
<?php if ( $this->is_premium ) : ?>
<span class="license-info-badge license-info-badge--expiration">
<?php echo esc_html( $this->get_expiration_display() ); ?>
</span>
<?php endif; ?>
</h3>
</div>
<div class="license-input">
<form action="" method="post">
<?php if ( $this->is_premium ) : ?>
<p><?php esc_html_e( 'Have a key to activate the premium version? Paste it here:', 'robin-image-optimizer' ); ?></p>
<?php else : ?>
<p><?php esc_html_e( 'Have a key to activate the plugin? Paste it here:', 'robin-image-optimizer' ); ?></p>
<?php endif; ?>
<div class="license-key-wrap">
<input
type="text"
id="license-key"
name="licensekey"
value=""
class="form-control"
placeholder="<?php echo esc_html( $this->get_hidden_license_key() ); ?>"
/>
<?php if ( $this->is_premium ) : ?>
<button data-action="deactivate" class="button button-primary wrio-license-btn" type="button" id="license-submit">
<?php esc_html_e( 'Deactivate', 'robin-image-optimizer' ); ?>
</button>
<?php else : ?>
<button data-action="activate" class="button button-primary wrio-license-btn" type="button" id="license-submit">
<?php esc_html_e( 'Activate', 'robin-image-optimizer' ); ?>
</button>
<?php endif; ?>
</div>
<?php $this->render_learnmore_section(); ?>
<div id="license-form-error-container"></div>
<?php $this->render_freemius_migration_notice(); ?>
</form>
</div>
</div>
<?php $this->subscribe_widget->render(); ?>
</div>
<?php
}
/**
* Render the upgrade banner for free users
*
* @return void
*/
private function render_upgrade_banner() {
$support = WRIO_Plugin::app()->get_support();
$pricing_url = $support->get_pricing_url( true, 'license_banner' );
?>
<div class="wrio-license-upgrade-banner">
<div class="wrio-license-upgrade-icon">
<span>⚡</span>
</div>
<div class="wrio-license-upgrade-content">
<h2 class="wrio-license-upgrade-title"><?php esc_html_e( 'Supercharge Your Image Optimization', 'robin-image-optimizer' ); ?></h2>
<p class="wrio-license-upgrade-subtitle"><?php esc_html_e( "You're using the free version. Upgrade to unlock unlimited conversions and premium features.", 'robin-image-optimizer' ); ?></p>
<div class="wrio-license-upgrade-features">
<div class="wrio-license-upgrade-feature">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
<span><?php esc_html_e( 'Unlimited AVIF', 'robin-image-optimizer' ); ?></span>
</div>
<div class="wrio-license-upgrade-feature">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
<span><?php esc_html_e( 'Custom Folders Optimization', 'robin-image-optimizer' ); ?></span>
</div>
<div class="wrio-license-upgrade-feature">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
<span><?php esc_html_e( 'NextGen Gallery Support', 'robin-image-optimizer' ); ?></span>
</div>
<div class="wrio-license-upgrade-feature">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
<span><?php esc_html_e( 'Priority Support', 'robin-image-optimizer' ); ?></span>
</div>
<div class="wrio-license-upgrade-feature">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
<span><?php esc_html_e( 'More Compression Modes', 'robin-image-optimizer' ); ?></span>
</div>
<div class="wrio-license-upgrade-feature">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
<span><?php esc_html_e( 'Super Page Cache Pro', 'robin-image-optimizer' ); ?></span>
</div>
</div>
<a href="<?php echo esc_url( $pricing_url ); ?>" class="wrio-license-upgrade-button" target="_blank" rel="noopener">
<?php esc_html_e( 'View Pro Plans', 'robin-image-optimizer' ); ?> →
</a>
</div>
</div>
<?php
}
/**
* Render learn more section
*
* @return void
*/
private function render_learnmore_section() {
$support = WRIO_Plugin::app()->get_support();
if ( ! $this->is_premium ) :
?>
<p style="margin-top: 10px;">
<?php
printf(
wp_kses(
/* translators: %1$s: opening link tag, %2$s: closing link tag */
__( 'Can\'t find your key? Go to %1$sthis page%2$s and login using the e-mail address associated with your purchase.', 'robin-image-optimizer' ),
[
'a' => [
'href' => [],
'target' => [],
'rel' => [],
],
]
),
'<a href="' . esc_url( $support->get_contacts_url( true, 'license_page' ) ) . '" target="_blank" rel="noopener">',
'</a>'
);
?>
</p>
<?php
endif;
}
/**
* Render migration notice for Freemius license holders
*
* @return void
*/
private function render_freemius_migration_notice() {
if ( ! $this->is_premium || null === $this->license || $this->license->get_source() !== WRIO_License::SOURCE_FREEMIUS ) {
return;
}
?>
<div class="wrio-migration-notice">
<p>
<strong><?php esc_html_e( 'Action Required:', 'robin-image-optimizer' ); ?></strong>
<?php esc_html_e( 'Your license was issued through our previous licensing system (Freemius). Please contact support to receive a new Themeisle license key for continued access to updates and support.', 'robin-image-optimizer' ); ?>
</p>
<p>
<a href="<?php echo esc_url( WRIO_Plugin::app()->get_support()->get_contacts_url( true, 'license_migration' ) ); ?>" target="_blank" rel="noopener" class="button button-primary">
<?php esc_html_e( 'Contact Support', 'robin-image-optimizer' ); ?>
</a>
</p>
</div>
<?php
}
}

View File

@@ -0,0 +1,131 @@
<?php
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Класс отвечает за работу страницы логов.
*
* @version 1.0
*/
class WRIO_LogPage extends Wbcr_FactoryLogger359_PageBase {
/**
* {@inheritdoc}
*/
public $id = 'rio_logs'; // Уникальный идентификатор страницы
/**
* Hide bottom sidebar - only show on Settings page
*
* @var bool
*/
public $show_bottom_sidebar = false;
/**
* {@inheritdoc}
*
* @var string
*/
public $page_parent_page = 'rio_general';
/**
* {@inheritdoc}
*/
public $available_for_multisite = false;
/**
* {@inheritdoc}
*/
public $clearfy_collaboration = false;
/**
*
* Whether to show the right sidebar in options.
*
* @var bool
*/
public $show_right_sidebar_in_options = true;
/**
* Menu target for WordPress admin submenu.
*
* @var string
*/
public $menu_target = 'rio_general-robin-image-optimizer';
/**
* Use admin.php as base URL instead of menu_target.
*
* @var bool
*/
public $custom_target = true;
/**
* The page is internal and should not be displayed in the menu.
*
* @var bool
*/
public $internal = false;
/**
* View instance for rendering templates.
*
* @since 1.3.0
* @var WRIO_Views
*/
protected $view;
/**
* Подменяем пространство имен для меню плагина, если активирован плагин
* Меню текущего плагина будет добавлено в общее меню
*
* @return string
*/
public function getMenuScope() {
if ( $this->clearfy_collaboration ) {
$this->page_parent_page = 'rio_general';
return 'wbcr_clearfy';
}
return 'robin-image-optimizer';
}
/**
* @param WRIO_Plugin $plugin
*/
public function __construct( WRIO_Plugin $plugin ) {
$this->menu_title = __( 'Error Log', 'robin-image-optimizer' );
$this->page_menu_short_description = __( 'Plugin debug report', 'robin-image-optimizer' );
$this->view = WRIO_Views::get_instance( WRIO_PLUGIN_DIR );
if ( is_multisite() && defined( 'WCL_PLUGIN_ACTIVE' ) ) {
if ( WRIO_Plugin::app()->isNetworkActive() && WCL_Plugin::app()->isNetworkActive() ) {
$this->clearfy_collaboration = true;
}
} elseif ( defined( 'WCL_PLUGIN_ACTIVE' ) ) {
$this->clearfy_collaboration = true;
}
parent::__construct( $plugin );
}
/**
* {@inheritdoc}
*
* @return void
* @since 1.0.0
*/
public function assets( $scripts, $styles ) {
parent::assets( $scripts, $styles );
}
/**
* {@inheritdoc}
*/
public function getMenuTitle() {
return defined( 'LOADING_ROBIN_IMAGE_OPTIMIZER_AS_ADDON' ) ? __( 'Image optimizer', 'robin-image-optimizer' ) : __( 'Error Log', 'robin-image-optimizer' );
}
}

View File

@@ -0,0 +1,89 @@
<?php
/**
* The page Settings.
*
* @since 1.0.0
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Класс отвечает за работу страницы настроек
*
* @version 1.0
*/
class WRIO_Page extends WBCR\Factory_Templates_759\Impressive {
/**
* {@inheritdoc}
*/
public $page_parent_page = null;
/**
* {@inheritdoc}
*/
public $available_for_multisite = false;
/**
* {@inheritdoc}
*/
public $clearfy_collaboration = false;
/**
* {@inheritdoc}
*
* @var bool
*/
public $show_right_sidebar_in_options = false;
/**
* Hide bottom sidebar by default - only show on Settings page
*
* @var bool
*/
public $show_bottom_sidebar = false;
/**
* @since 1.3.0
* @var WRIO_Views
*/
protected $view;
/**
* @param WRIO_Plugin $plugin
*/
public function __construct( WRIO_Plugin $plugin ) {
$this->view = WRIO_Views::get_instance( WRIO_PLUGIN_DIR );
if ( is_multisite() && defined( 'WCL_PLUGIN_ACTIVE' ) ) {
if ( WRIO_Plugin::app()->isNetworkActive() && WCL_Plugin::app()->isNetworkActive() ) {
$this->clearfy_collaboration = true;
}
} elseif ( defined( 'WCL_PLUGIN_ACTIVE' ) ) {
$this->clearfy_collaboration = true;
}
parent::__construct( $plugin );
}
/**
* Подменяем простраинство имен для меню плагина, если активирован плагин
* Меню текущего плагина будет добавлено в общее меню
*
* @return string
*/
public function getMenuScope() {
if ( $this->clearfy_collaboration ) {
$this->page_parent_page = 'rio_general';
return 'wbcr_clearfy';
}
return 'robin-image-optimizer';
}
}

View File

@@ -0,0 +1,687 @@
<?php
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Класс отвечает за работу страницы настроек
*
* @version 1.0
*/
class WRIO_SettingsPage extends WRIO_Page {
/**
* {@inheritdoc}
*/
public $id = 'rio_settings';
/**
* {@inheritdoc}
*/
public $page_menu_dashicon = 'dashicons-admin-generic';
/**
* {@inheritdoc}
*
* @var string
*/
public $page_parent_page = 'rio_general';
/**
* {@inheritdoc}
*
* @var bool
*/
public $show_right_sidebar_in_options = false;
/**
* {@inheritDoc}
*
* @since 1.1.3 - Added
* @var bool
*/
public $show_bottom_sidebar = true;
/**
* @var bool
*/
public $show_search_options_form = false;
/**
* Menu target for WordPress admin submenu.
*
* @var string
*/
public $menu_target = 'rio_general-robin-image-optimizer';
/**
* Use admin.php as base URL instead of menu_target.
*
* @var bool
*/
public $custom_target = true;
/**
* @var bool
*/
public $internal = false;
/**
* @param WRIO_Plugin $plugin
*/
public function __construct( WRIO_Plugin $plugin ) {
$this->menu_title = __( 'Settings', 'robin-image-optimizer' );
$this->page_menu_short_description = __( 'Plugin configuration', 'robin-image-optimizer' );
if ( defined( 'WBCR_CLEARFY_PLUGIN_ACTIVE' ) ) {
$this->show_search_options_form = true;
}
add_filter(
'wbcr/factory/option_image_optimization_type',
function ( $option_value ) {
if ( ! wrio_is_license_activate() && $option_value === 'background' ) {
$option_value = 'schedule';
}
return $option_value;
}
);
add_filter(
'wbcr/factory/option_convert_avif_format',
function ( $option_value ) {
if ( ! wrio_is_license_activate() && $option_value ) {
$option_value = false;
}
return $option_value;
}
);
parent::__construct( $plugin );
}
/**
* Подключаем скрипты и стили для страницы
*
* @return void
* @since 1.0.0
* @see Wbcr_FactoryPages600_AdminPage
*/
public function assets( $scripts, $styles ) {
parent::assets( $scripts, $styles );
$this->styles->add( WRIO_PLUGIN_URL . '/admin/assets/css/base-statistic.css' );
$this->scripts->add( WRIO_PLUGIN_URL . '/admin/assets/js/restore-backup.js' );
if ( ! wrio_is_license_activate() ) {
$this->styles->add( WRIO_PLUGIN_URL . '/admin/assets/css/settings-premium.css' );
$this->scripts->add( WRIO_PLUGIN_URL . '/admin/assets/js/settings-premium.js' );
}
if ( defined( 'WBCR_CLEARFY_PLUGIN_ACTIVE' ) ) {
$this->styles->add( WCL_PLUGIN_URL . '/admin/assets/css/general.css' );
}
}
/**
* Выводим предупреждения
*/
protected function warningNotice() {
$upload_dir = wp_upload_dir();
if ( ! wp_is_writable( $upload_dir['basedir'] ) ) {
$this->printErrorNotice(
sprintf(
// translators: %s is the folder path.
__( 'Folder %s is unavailable for writing', 'robin-image-optimizer' ),
'wp-content/uploads/'
)
);
}
$wio_backup = $upload_dir['basedir'] . '/wio_backup/';
if ( file_exists( $wio_backup ) && ! wp_is_writable( $wio_backup ) ) {
$this->printErrorNotice(
sprintf(
// translators: %s is the folder path.
__( 'Folder %s is unavailable for writing', 'robin-image-optimizer' ),
'wp-content/uploads/wio-backup/'
)
);
}
if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON == true ) {
$this->printErrorNotice(
sprintf(
// translators: %s is the file name (wp-config.php).
__( 'Cron is disabled in %s', 'robin-image-optimizer' ),
'wp-config.php'
)
);
}
}
/**
* Метод должен передать массив опций для создания формы с полями.
* Созданием страницы и формы занимается фреймворк
*
* @return mixed[]
* @since 1.0.0
*/
public function getPageOptions() {
$options = [];
$options[] = [
'type' => 'html',
'html' => '<div class="wbcr-factory-page-group-header"><strong>' . __( 'Main Settings', 'robin-image-optimizer' ) . '</strong><p>' . __( 'Configure image optimization settings.', 'robin-image-optimizer' ) . '</p></div>',
];
// Радио переключатель
$options[] = [
'type' => 'dropdown',
'name' => 'image_optimization_level',
'way' => 'buttons',
'title' => __( 'Compression mode', 'robin-image-optimizer' ),
'data' => [
[
'normal',
__( 'Lossless', 'robin-image-optimizer' ),
__( 'This mode provides lossless compression and your images will be optimized without visible changes. If you want an ideal image quality, we recommend this mode. The size of the files will be reduced approximately 2 times. If this is not enough for you, try other modes.', 'robin-image-optimizer' ),
],
[
'aggresive',
__( 'Lossy', 'robin-image-optimizer' ),
__( 'This mode provides an ideal optimization of your images without significant quality loss. The file size will be reduced approximately 5 times with a slight decrease in image quality. In most cases that cannot be seen with the naked eye.', 'robin-image-optimizer' ),
],
[
'ultra',
__( 'High', 'robin-image-optimizer' ),
__( 'This mode will use all available optimization methods for maximum image compression. The file size will be reduced approximately 7 times. The quality of some images may deteriorate slightly. Use this mode if you need the maximum weight reduction, and you are ready to accept the loss of image quality.', 'robin-image-optimizer' ),
],
[
'googlepage',
__( 'G PageSpeed', 'robin-image-optimizer' ),
__( 'This mode uses the optimal settings for Google Page Speed', 'robin-image-optimizer' ),
],
[
'custom',
__( 'Custom', 'robin-image-optimizer' ),
__( 'This mode allows you to configure your own compression ratio.', 'robin-image-optimizer' ),
],
],
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'Select the compression mode appropriate for your case.', 'robin-image-optimizer' ),
'default' => 'normal',
'events' => [
'normal' => [
'hide' => '.factory-control-image_optimization_level_custom',
],
'aggresive' => [
'hide' => '.factory-control-image_optimization_level_custom',
],
'ultra' => [
'hide' => '.factory-control-image_optimization_level_custom',
],
'googlepage' => [
'hide' => '.factory-control-image_optimization_level_custom',
],
'custom' => [
'show' => '.factory-control-image_optimization_level_custom',
],
],
];
// Текстовое поле
$options[] = [
'type' => 'textbox',
'name' => 'image_optimization_level_custom',
'title' => __( 'Enter custom quality', 'robin-image-optimizer' ),
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'Custom quality 1-100', 'robin-image-optimizer' ),
'default' => '70',
];
// Переключатель
$options[] = [
'type' => 'checkbox',
'way' => 'buttons',
'name' => 'auto_optimize_when_upload',
'title' => __( 'Auto optimization on upload', 'robin-image-optimizer' ),
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'Automatically compress all images that you upload directly to the WordPress media library, when editing pages and posts or using themes and plugins.', 'robin-image-optimizer' ),
'default' => false,
];
// Переключатель
$options[] = [
'type' => 'checkbox',
'way' => 'buttons',
'name' => 'backup_origin_images',
'title' => __( 'Backup images', 'robin-image-optimizer' ),
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'green',
],
'hint' => __( 'Before optimizing, all your images will be saved in a separate folder for future recovery.', 'robin-image-optimizer' ),
'default' => true,
];
// Переключатель
$options[] = [
'type' => 'checkbox',
'way' => 'buttons',
'name' => 'error_log',
'title' => __( 'Error Log', 'robin-image-optimizer' ),
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'Enable error logging. The log will be displayed on a separate tab.', 'robin-image-optimizer' ),
'default' => false,
'eventsOn' => [
'show' => '#wrio-error-log-options',
],
'eventsOff' => [
'hide' => '#wrio-error-log-options',
],
];
$options[] = [
'type' => 'html',
'html' => [ $this, 'error_log_options' ],
];
// WebP conversion option (FREE)
$options[] = [
'type' => 'checkbox',
'way' => 'buttons',
'name' => 'convert_webp_format',
'title' => __( 'Convert Images to WebP', 'robin-image-optimizer' ),
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'Convert JPEG & PNG images into WebP format and replace them for browsers which support it. Unsupported browsers would be skipped.', 'robin-image-optimizer' ),
'default' => false,
];
// AVIF conversion option (PRO only)
$options[] = [
'type' => 'checkbox',
'way' => 'buttons',
'name' => 'convert_avif_format',
'title' => __( 'Convert Images to AVIF', 'robin-image-optimizer' ),
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'Convert JPEG & PNG images into AVIF format. AVIF provides superior compression but requires a premium license.', 'robin-image-optimizer' ),
'default' => false,
'cssClass' => ! wrio_is_license_activate() ? [ 'factory-checkbox-disabled', 'wrio-checkbox-premium-label' ] : [],
];
$options[] = [
'type' => 'html',
'html' => [ $this, 'conver_webp_options' ],
];
// восстановление
$options[] = [
'type' => 'html',
'html' => [ $this, 'rollbackButton' ],
];
// Переключатель
$options[] = [
'type' => 'checkbox',
'way' => 'buttons',
'name' => 'save_exif_data',
'title' => __( 'Strip EXIF data', 'robin-image-optimizer' ),
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'EXIF is information stored in photos: camera model, shutter speed, exposure compensation, ISO, GPS, etc. By default, the plugin removes EXIF extended data. If your project is dedicated to photography and you need to display this data, then enable this option.', 'robin-image-optimizer' ),
'default' => true,
];
$options[] = [
'type' => 'html',
'html' => '<div class="wbcr-factory-page-group-header"><strong>' . __( 'Optimization', 'robin-image-optimizer' ) . '</strong><p>' . __( 'Here you can specify additional image optimization options.', 'robin-image-optimizer' ) . '</p></div>',
];
$options[] = [
'type' => 'dropdown',
'name' => 'image_optimization_order',
'way' => 'buttons',
'title' => __( 'Optimization order', 'robin-image-optimizer' ),
'data' => [
[
'asc',
__( 'Ascending', 'robin-image-optimizer' ),
__( 'Optimization will start with old images in the media library', 'robin-image-optimizer' ),
],
[
'desc',
__( 'Descending', 'robin-image-optimizer' ),
__( 'Optimization will start with new images in the media library', 'robin-image-optimizer' ),
],
],
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( /** @lang text */ 'Select the optimization order from the media library.', 'robin-image-optimizer' ),
'default' => 'asc',
];
// Переключатель
$options[] = [
'type' => 'checkbox',
'way' => 'buttons',
'name' => 'resize_larger',
'title' => __( 'Resizing large images', 'robin-image-optimizer' ),
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'When you upload images from a camera or stock, they may be too high resolution and it is not necessary for web. The option allows you to automatically change images resolution on upload.', 'robin-image-optimizer' ),
'default' => false,
// когда чекбокс включен показываем поле с классом .factory-control-resize_larger_w
'eventsOn' => [
'show' => '.factory-control-resize_larger_w,.factory-control-resize_larger_h',
],
// когда чекбокс выключен, скрываем поле с классом .factory-control-resize_larger_w
'eventsOff' => [
'hide' => '.factory-control-resize_larger_w,.factory-control-resize_larger_h',
],
];
// Текстовое поле
$options[] = [
'type' => 'textbox',
'name' => 'resize_larger_w',
'title' => __( 'Enter the maximum width (px)', 'robin-image-optimizer' ),
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'Set the maximum images resolution on the long side. For horizontal images, this will be the width, and for vertical images - the height. The resolution of the images will be changed proportionally according to the set value.', 'robin-image-optimizer' ),
'default' => '1600',
];
// Текстовое поле
$options[] = [
'type' => 'textbox',
'name' => 'resize_larger_h',
'title' => __( 'Enter the maximum height (px)', 'robin-image-optimizer' ),
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'Set the maximum images resolution on the long side. For horizontal images, this will be the width, and for vertical images - the height. The resolution of the images will be changed proportionally according to the set value.', 'robin-image-optimizer' ),
'default' => '1600',
];
$options[] = [
'type' => 'list',
'way' => 'checklist',
'name' => 'allowed_formats',
'title' => __( 'Optimize formats', 'robin-image-optimizer' ),
'data' => [
[ 'image/jpeg', 'JPG' ],
[ 'image/png', 'PNG' ],
[ 'image/gif', 'GIF' ],
],
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'Choose which formats of images should be optimized and uncheck those that do not need optimization.', 'robin-image-optimizer' ),
'default' => 'image/jpeg,image/png,image/gif',
];
// получаем зарегистрированные размеры изображений
$wp_image_sizes = wrio_get_image_sizes();
$wio_image_sizes = [];
foreach ( $wp_image_sizes as $key => $value ) {
$wio_image_sizes[] = [
$key,
$key . ' - ' . $value['width'] . 'x' . $value['height'],
];
}
$options[] = [
'type' => 'list',
'way' => 'checklist',
'name' => 'allowed_sizes_thumbnail',
'title' => __( 'Optimize thumbnails', 'robin-image-optimizer' ),
'data' => $wio_image_sizes,
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'Choose which sizes of thumbnails should be optimized and uncheck those that do not need optimization.', 'robin-image-optimizer' ),
'default' => 'thumbnail,medium',
];
// cron
$options[] = [
'type' => 'html',
'html' => '<div class="wbcr-factory-page-group-header"><strong>' . __( 'Scheduled and background optimization', 'robin-image-optimizer' ) . '</strong><p>' . __( 'Settings for scheduled and background image optimization.', 'robin-image-optimizer' ) . '</p></div>',
];
$options[] = [
'type' => 'dropdown',
'name' => 'image_optimization_type',
'way' => 'buttons',
'title' => __( 'Background optimization type', 'robin-image-optimizer' ),
'data' => [
[
'schedule',
__( 'Scheduled', 'robin-image-optimizer' ),
__( 'Optimization will take place on a schedule', 'robin-image-optimizer' ),
],
[
'background',
__( 'Background', 'robin-image-optimizer' ),
__( 'Optimization will occur in the background constantly', 'robin-image-optimizer' ),
],
],
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => sprintf(
// translators: %1$s is the bold start tag, %2$s is the bold end tag.
__( '%1$sScheduled optimization%2$s will occur on a scheduled basis.', 'robin-image-optimizer' ),
'<b>',
'</b>'
) . '<br>' . sprintf(
// translators: %1$s is the bold start tag, %2$s is the bold end tag.
__( '%1$sBackground optimization%2$s will occur in the background constantly.', 'robin-image-optimizer' ),
'<b>',
'</b>'
),
'default' => 'schedule',
'events' => [
'schedule' => [
'show' => '#wbcr-io-shedule-options',
],
'background' => [
'hide' => '#wbcr-io-shedule-options',
],
],
];
$group_items[] = [
'type' => 'dropdown',
'way' => 'buttons',
'name' => 'image_autooptimize_shedule_time',
'data' => [
[ 'wio_1_min', __( '1 minute', 'robin-image-optimizer' ) ],
// translators: %s is the number of minutes.
[ 'wio_2_min', sprintf( __( '%s minutes', 'robin-image-optimizer' ), '2' ) ],
// translators: %s is the number of minutes.
[ 'wio_5_min', sprintf( __( '%s minutes', 'robin-image-optimizer' ), '5' ) ],
// translators: %s is the number of minutes.
[ 'wio_10_min', sprintf( __( '%s minutes', 'robin-image-optimizer' ), '10' ) ],
// translators: %s is the number of minutes.
[ 'wio_30_min', sprintf( __( '%s minutes', 'robin-image-optimizer' ), '30' ) ],
[ 'wio_hourly', __( 'Hour', 'robin-image-optimizer' ) ],
[ 'wio_daily', __( 'Day', 'robin-image-optimizer' ) ],
],
'default' => 'wio_5_min',
'title' => __( 'Run every', 'robin-image-optimizer' ),
'hint' => __( 'Select time at which the task will be repeated.', 'robin-image-optimizer' ),
];
$group_items[] = [
'type' => 'textbox',
'name' => 'image_autooptimize_items_number_per_interation',
'title' => __( 'Images per iteration', 'robin-image-optimizer' ),
'layout' => [
'hint-type' => 'icon',
'hint-icon-color' => 'grey',
],
'hint' => __( 'Specify the number of images that will be optimized during the job. For example, if you enter 5 and select 5 min, the plugin will optimize 5 images every 5 minutes.', 'robin-image-optimizer' ),
'default' => '3',
'htmlAttrs' => [
'type' => 'number',
'min' => '1',
'step' => '1',
],
'filter_value' => function ( $value ) {
$int_value = intval( $value );
return $int_value < 1 ? 1 : $int_value;
},
];
$options[] = [
'type' => 'div',
'id' => 'wbcr-io-shedule-options',
'items' => $group_items,
];
$options = apply_filters( 'wbcr/rio/settings_page/options', $options );
$formOptions = [];
$formOptions[] = [
'type' => 'form-group',
'items' => $options,
// 'cssClass' => 'postbox'
];
return $formOptions;
}
/**
* Save advanced options in database
*
* @since 1.3.6
*/
public function beforeFormSave() {
/**
* Used to save webp options. It can also be used to intercept
* other unregistered fields.
*
* @since 1.3.6
*/
do_action( 'wrio/settings_page/berfore_form_save' );
$error_log = (int) WRIO_Plugin::app()->request->post( WRIO_Plugin::app()->getPrefix() . 'error_log', 0 );
if ( ! $error_log ) {
return;
}
$keep_error_log_on_frontend = (int) WRIO_Plugin::app()->request->post( 'wrio_keep_error_log_on_frontend', 0 );
WRIO_Plugin::app()->updatePopulateOption( 'keep_error_log_on_frontend', $keep_error_log_on_frontend );
}
/**
* This method adds advanced options for the "Convert Images to WebP" checkbox.
*
* @since 1.3.6
*/
public function conver_webp_options() {
/**
* This hook prints options for delivering webp images.
*
* @since 1.3.6
*/
do_action( 'wrio/settings_page/conver_webp_options' );
}
/**
* This method adds advanced options for the "Error log" checkbox.
*
* @since 1.3.6
*/
public function error_log_options() {
$this->view->print_template(
'part-settings-page-error-log-options',
[
'keep_error_log_on_frontend' => (int) WRIO_Plugin::app()->getPopulateOption( 'keep_error_log_on_frontend', 0 ),
]
);
}
/**
* Кнопка восстановления изображений
*/
public function rollbackButton() {
?>
<div class="form-group form-group-checkbox factory-control-rollback-button">
<label for="wio-clear-backup-btn" class="col-sm-4 control-label">
<?php esc_html_e( 'Manage backups', 'robin-image-optimizer' ); ?>
<span class="factory-hint-icon factory-hint-icon-red" data-toggle="factory-tooltip"
data-placement="right" title=""
data-original-title="<?php esc_html_e( 'You can restore the original images from a backup or clear them.', 'robin-image-optimizer' ); ?>"
>
?
</span>
</label>
<input type="hidden" value="<?php echo wp_create_nonce( 'wio-iph' ); ?>" id="wio-iph-nonce">
<div class="control-group col-sm-8">
<div class="factory-buttons-way btn-group">
<a class="btn btn-default" id="wio-restore-backup-btn"
data-confirm="<?php esc_html_e( 'Are you sure you want to restore all images? This cannot be undone.', 'robin-image-optimizer' ); ?>"
href="#"><?php esc_html_e( 'Restore', 'robin-image-optimizer' ); ?></a>
<a class="btn btn-default" id="wio-clear-backup-btn"
data-confirm="<?php esc_html_e( 'Are you sure you want to clear the backup folder? All backup images will be permanently deleted.', 'robin-image-optimizer' ); ?>"
href="#"><?php esc_html_e( 'Clear Backup', 'robin-image-optimizer' ); ?></a>
</div>
<div class="progress" id="wio-restore-backup-progress" style="display:none;">
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="0"
aria-valuemin="0" aria-valuemax="100" style="width:0%">
</div>
</div>
<p id="wio-restore-backup-msg"
style="display:none;"><?php esc_html_e( 'Restore completed.', 'robin-image-optimizer' ); ?></p>
<p id="wio-clear-backup-msg"
style="display:none;"><?php esc_html_e( 'The backup folder was cleared.', 'robin-image-optimizer' ); ?></p>
</div>
</div>
<?php
}
}

View File

@@ -0,0 +1,359 @@
<?php
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Class WRIO_StatisticPage
* Класс отвечает за работу страницы статистики
*/
class WRIO_StatisticPage extends WRIO_Page {
/**
* {@inheritdoc}
*/
public $id = 'rio_general';
/**
* {@inheritdoc}
*/
public $type = 'page';
/**
* {@inheritdoc}
*/
public $plugin;
/**
* {@inheritdoc}
*/
public $page_menu_position = 20;
/**
* {@inheritdoc}
*/
public $page_menu_dashicon = 'dashicons-chart-line';
/**
* Menu icon for WordPress admin sidebar.
*
* @var string
*/
public $menu_icon = 'dashicons-images-alt';
/**
* Position in WordPress admin menu (58 = between Comments and Appearance).
*
* @var string
*/
public $menu_position = '58';
/**
* @var string
*/
public $menu_target = null;
/**
* {@inheritdoc}
*
* @var null
*/
public $page_parent_page = null;
/**
* @var bool
*/
public $internal = false;
/**
* @var bool
*/
public $add_link_to_plugin_actions = true;
/**
* Page type
*
* @since 1.3.0
* @var string
*/
protected $scope = 'media-library';
/**
* @param WRIO_Plugin $plugin
*/
public function __construct( WRIO_Plugin $plugin ) {
$this->menu_title = __( 'Robin Image Optimizer', 'robin-image-optimizer' );
$this->menu_sub_title = __( 'Optimize', 'robin-image-optimizer' );
$this->page_menu_short_description = __( 'Compress bulk of images', 'robin-image-optimizer' );
$this->plugin = $plugin;
parent::__construct( $plugin );
add_action( 'admin_enqueue_scripts', [ $this, 'print_i18n' ] );
add_filter( 'wbcr/factory/pages/impressive/print_all_notices', [ $this, 'register_limit_notice' ], 10, 2 );
}
/**
* @param $plugin
* @param $obj
*
* @return void|bool
*/
public function register_limit_notice( $plugin, $obj ) {
if ( ( $this->plugin->getPluginName() !== $plugin->getPluginName() ) || ( 'rio_general' !== $obj->id ) ) {
return false;
}
}
/**
* Подменяем простраинство имен для меню плагина, если активирован плагин
* Меню текущего плагина будет добавлено в общее мен
*
* @return string
*/
public function getMenuScope() {
if ( $this->clearfy_collaboration ) {
// $this->internal = true;
return 'wbcr_clearfy';
}
return 'robin-image-optimizer';
}
/**
* {@inheritdoc}
*/
public function getMenuTitle() {
return $this->menu_title;
}
/**
* {@inheritdoc}
*/
public function getPageTitle() {
return $this->clearfy_collaboration ? __( 'Image optimizer', 'robin-image-optimizer' ) : __( 'Bulk optimization', 'robin-image-optimizer' );
}
/**
* {@inheritdoc}
*/
public function assets( $scripts, $styles ) {
parent::assets( $scripts, $styles );
$this->styles->add( WRIO_PLUGIN_URL . '/admin/assets/css/base-statistic.css' );
$this->scripts->add( WRIO_PLUGIN_URL . '/admin/assets/js/sweetalert2.js' );
$this->styles->add( WRIO_PLUGIN_URL . '/admin/assets/css/sweetalert2.css' );
$this->styles->add( WRIO_PLUGIN_URL . '/admin/assets/css/sweetalert-custom.css' );
$this->scripts->add( WRIO_PLUGIN_URL . '/admin/assets/js/Chart.min.js' );
// $this->scripts->add( WRIO_PLUGIN_URL . '/admin/assets/js/statistic.js' );
$this->scripts->add( WRIO_PLUGIN_URL . '/admin/assets/js/modals.js', [ 'jquery' ], 'wrio-modals' );
$this->scripts->add(
WRIO_PLUGIN_URL . '/admin/assets/js/bulk-optimization.js',
[
'jquery',
'wrio-modals',
]
);
$this->scripts->add( WRIO_PLUGIN_URL . '/admin/assets/js/calculate-attachments.js' );
$this->scripts->add(
WRIO_PLUGIN_URL . '/admin/assets/js/bulk-conversion.js',
[
'jquery',
'wrio-modals',
]
);
if ( defined( 'WBCR_CLEARFY_PLUGIN_ACTIVE' ) ) {
$this->styles->add( WCL_PLUGIN_URL . '/admin/assets/css/general.css' );
}
}
/**
* Print localization only current page
*
* @throws \Exception
* @since 1.3.0
*/
public function print_i18n() {
$page = $this->plugin->request->get( 'page', null );
if ( $page !== $this->getResultId() ) {
return;
}
$backup = new WIO_Backup();
wp_enqueue_script( 'wio-statistic-page', WRIO_PLUGIN_URL . '/admin/assets/js/statistic.js', [ 'jquery' ], WRIO_Plugin::app()->getPluginVersion(), true );
wp_localize_script( 'wio-statistic-page', 'wrio_l18n_bulk_page', $this->get_i18n() );
wp_localize_script(
'wio-statistic-page',
'wrio_settings_bulk_page',
[
'is_premium' => wrio_is_license_activate(),
'is_network_admin' => WRIO_Plugin::app()->isNetworkAdmin() ? 1 : 0,
'is_writable_backup_dir' => $backup->isBackupWritable() ? 1 : 0,
'images_backup' => WRIO_Plugin::app()->getPopulateOption( 'backup_origin_images', false ) ? 1 : 0,
'need_migration' => wbcr_rio_has_meta_to_migrate() ? 1 : 0,
'scope' => $this->scope,
'optimization_nonce' => wp_create_nonce( 'bulk_optimization' ),
'conversion_nonce' => wp_create_nonce( 'bulk_conversion' ),
]
);
}
/**
* {@inheritdoc}
*/
public function showPageContent() {
$is_premium = wrio_is_license_activate();
$statistics = $this->get_statisctic_data();
$template_data = [
'is_premium' => $is_premium,
'scope' => $this->scope,
];
// do_action( 'wbcr/rio/multisite_current_blog' );
// Page header
$this->view->print_template(
'part-page-header',
[
'title' => __( 'Image optimization dashboard', 'robin-image-optimizer' ),
'description' => __( 'Monitor image optimization statistics and run on demand or scheduled optimization.', 'robin-image-optimizer' ),
],
$this
);
// Page tabs
$this->view->print_template( 'part-bulk-optimization-tabs', $template_data, $this );
?>
<div class="wbcr-factory-page-group-body" style="padding:0; border-top: 1px solid #d4d4d4;">
<?php
// Servers
$this->view->print_template( 'part-bulk-optimization-servers', $template_data, $this );
// Total
$this->view->print_template(
'part-bulk-optimization-total',
array_merge(
$template_data,
[
'stats' => $statistics->get(),
]
),
$this
);
// Statistic
$this->view->print_template(
'part-bulk-optimization-statistic',
array_merge(
$template_data,
[
'stats' => $statistics->get(),
]
),
$this
);
// Optimization log
$this->view->print_template(
'part-bulk-optimization-log',
array_merge(
$template_data,
[
'process_log' => $statistics->get_last_optimized_images(),
]
),
$this
);
?>
</div>
<script type="text/html" id="wrio-tmpl-bulk-optimization">
<?php $this->view->print_template( 'modal-bulk-optimization' ); ?>
</script>
<script type="text/html" id="wrio-tmpl-webp-conversion">
<?php $this->view->print_template( 'modal-webp-conversion' ); ?>
</script>
<?php
// do_action( 'wbcr/rio/multisite_restore_blog' );
}
/**
* @return object|\WRIO_Image_Statistic
* @since 1.3.0
*/
protected function get_statisctic_data() {
return WRIO_Image_Statistic::get_instance();
}
/**
* @return array
* @since 1.3.0
*/
protected function get_i18n() {
$modal_optimization_cron_button = __( 'Scheduled optimization', 'robin-image-optimizer' );
$modal_conversion_cron_button = __( 'Scheduled conversion', 'robin-image-optimizer' );
$modal_optimization_cron_button_stop = __( 'Stop schedule optimization', 'robin-image-optimizer' );
$modal_conversion_cron_button_stop = __( 'Stop schedule conversion', 'robin-image-optimizer' );
$optimize_type = WRIO_Plugin::app()->getOption( 'image_optimization_type', 'schedule' );
if ( wrio_is_license_activate() && $optimize_type === 'background' ) {
$modal_optimization_cron_button = __( 'Background optimization', 'robin-image-optimizer' );
$modal_conversion_cron_button = __( 'Background conversion', 'robin-image-optimizer' );
$modal_optimization_cron_button_stop = __( 'Stop background optimization', 'robin-image-optimizer' );
$modal_conversion_cron_button_stop = __( 'Stop background conversion', 'robin-image-optimizer' );
}
return [
'server_down_warning' => __( 'Your selected optimization server is down. This means that you cannot optimize images through this server. Try selecting another optimization server.', 'robin-image-optimizer' ),
// translators: the status of server.
'server_status_down' => __( 'Down', 'robin-image-optimizer' ),
// translators: the status of server.
'server_status_stable' => __( 'Stable', 'robin-image-optimizer' ),
'modal_error' => __( 'Error', 'robin-image-optimizer' ),
'modal_cancel' => __( 'Cancel', 'robin-image-optimizer' ),
'modal_confirm' => __( 'Confirm', 'robin-image-optimizer' ),
'modal_optimization_title' => __( 'Select optimization way', 'robin-image-optimizer' ),
'modal_optimization_manual_button' => __( 'Optimize now', 'robin-image-optimizer' ),
'modal_optimization_cron_button' => $modal_optimization_cron_button,
'modal_optimization_cron_button_stop' => $modal_optimization_cron_button_stop,
'optimization_complete' => __( 'All images from the media library are optimized.', 'robin-image-optimizer' ),
// translators: %s is the number of remaining images
'optimization_inprogress' => sprintf( __( 'Optimization in progress. %s images remaining.', 'robin-image-optimizer' ), '<span id="wio-total-unoptimized">%s</span>' ),
'modal_conversion_title' => __( 'Select conversion way', 'robin-image-optimizer' ),
'modal_conversion_manual_button' => __( 'Convert now', 'robin-image-optimizer' ),
'modal_conversion_cron_button' => $modal_conversion_cron_button,
'modal_conversion_cron_button_stop' => $modal_conversion_cron_button_stop,
'conversion_complete' => __( 'All images from the media library are optimized.', 'robin-image-optimizer' ),
// translators: %s is the number of remaining images
'conversion_inprogress' => sprintf( __( 'Conversion in progress. %s images remaining.', 'robin-image-optimizer' ), '<span id="wio-total-unoptimized">%s</span>' ),
'webp_button_start' => __( 'Convert to WebP', 'robin-image-optimizer' ),
'avif_button_start' => __( 'Convert to AVIF', 'robin-image-optimizer' ),
'modal_avif_conversion_title' => __( 'Select AVIF conversion way', 'robin-image-optimizer' ),
'need_migrations' => __( 'To start optimizing, you must complete migration from old plugin version.', 'robin-image-optimizer' ),
'leave_page_warning' => __( 'Optimization is still in progress. Are you sure you want to leave?', 'robin-image-optimizer' ),
'process_without_backup' => __( 'Do you want to start optimization without backup?', 'robin-image-optimizer' ),
'button_resume' => __( 'Resume', 'robin-image-optimizer' ),
'button_completed' => __( 'Completed', 'robin-image-optimizer' ),
'button_start' => __( 'Optimize', 'robin-image-optimizer' ),
'button_stop' => __( 'Stop', 'robin-image-optimizer' ),
// Don't Need a Parachute?
// If you keep this option deactivated, you won't be able to re-optimize your images to another compression level and restore your original images in case of need.
];
}
}

View File

@@ -0,0 +1,2 @@
<?php
// silence is golden