Skip to content

Commit

Permalink
Merge pull request #56 from av3nger/release/1.9.4
Browse files Browse the repository at this point in the history
Release/1.9.4
  • Loading branch information
av3nger authored Dec 13, 2024
2 parents 46c206b + e37b2dd commit 2c95719
Show file tree
Hide file tree
Showing 34 changed files with 1,284 additions and 129 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
= 1.9.4 - 14.12.2024 =

Added:
* Bulk offload actions to the media library list view
* Global option to disable processing in the page head section
* Additional TTL options (3, 6 and 9 months)

Changed:
* Improved UI/UX
* Improved logging to better catch offload errors

Fixed:
* Fix logs layout spanning off-screen
* Undefined array key PHP warning (props @ablears)

= 1.9.3 - 07.10.2024 =

Added:
Expand Down
17 changes: 16 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Donate link: https://www.paypal.com/donate/?business=JRR6QPRGTZ46N&no_recurring=
Requires at least: 5.6
Requires PHP: 7.0
Tested up to: 6.7
Stable tag: 1.9.3
Stable tag: 1.9.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Expand Down Expand Up @@ -102,6 +102,21 @@ If something is still not working for you, please let me know by creating a supp

== Changelog ==

= 1.9.4 - 14.12.2024 =

Added:
* Bulk offload actions to the media library list view
* Global option to disable processing in the page head section
* Additional TTL options (3, 6 and 9 months)

Changed:
* Improved UI/UX
* Improved logging to better catch offload errors

Fixed:
* Fix logs layout spanning off-screen
* Undefined array key PHP warning (props @ablears)

= 1.9.3 - 07.10.2024 =

Added:
Expand Down
1 change: 0 additions & 1 deletion app/class-core.php
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,6 @@ public function set_error( $code = '', string $message = '' ) {
if ( '' === $code ) {
self::$error = false;
} else {
do_action( 'cf_images_log', $message );
self::$error = new WP_Error( $code, $message );
}
}
Expand Down
152 changes: 132 additions & 20 deletions app/class-media.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ public function __construct() {

// Image actions.
add_action( 'delete_attachment', array( $this, 'remove_from_cloudflare' ) );

// Bulk dropdown actions in the media library.
add_filter( 'bulk_actions-upload', array( $this, 'bulk_media_actions' ) );
add_filter( 'handle_bulk_actions-upload', array( $this, 'bulk_action_handler' ), 10, 3 );
add_action( 'admin_notices', array( $this, 'bulk_action_admin_notice' ) );
}

/**
Expand Down Expand Up @@ -164,53 +169,57 @@ public function media_custom_column( string $column_name, int $post_id ) {
<?php echo esc_html( implode( ' | ', $status ) ); ?>
<?php do_action( 'cf_images_media_custom_column', (int) $post_id ); ?>
</span>
<ul>
<li role="list" dir="rtl">
<a href="#" aria-haspopup="listbox"><?php esc_html_e( 'Actions', 'cf-images' ); ?></a>
<ul role="listbox">
<div class="dropdown is-hoverable">
<div class="dropdown-trigger">
<a href="#" aria-haspopup="true" aria-controls="dropdown-menu">
<?php esc_html_e( 'Actions', 'cf-images' ); ?>
</a>
</div>
<div class="dropdown-menu" id="dropdown-menu" role="menu">
<div class="dropdown-content">
<?php if ( ! empty( $meta ) ) : ?>
<li><a href="#" class="cf-images-undo" data-id="<?php echo esc_attr( $post_id ); ?>">
<a href="#" class="dropdown-item cf-images-undo" data-id="<?php echo esc_attr( $post_id ); ?>">
<img src="<?php echo esc_url( CF_IMAGES_DIR_URL . 'assets/images/icons/cloud-off.svg' ); ?>" alt="<?php esc_attr_e( 'Remove from Cloudflare', 'cf-images' ); ?>" />
<?php esc_html_e( 'Remove from Cloudflare', 'cf-images' ); ?>
</a></li>
</a>
<?php if ( $deleted ) : ?>
<li><a href="#" class="cf-images-restore" data-id="<?php echo esc_attr( $post_id ); ?>">
<<a href="#" class="dropdown-item cf-images-restore" data-id="<?php echo esc_attr( $post_id ); ?>">
<img src="<?php echo esc_url( CF_IMAGES_DIR_URL . 'assets/images/icons/download.svg' ); ?>" alt="<?php esc_attr_e( 'Restore in media library', 'cf-images' ); ?>" />
<?php esc_html_e( 'Restore in media library', 'cf-images' ); ?>
</a></li>
</a>
<?php elseif ( apply_filters( 'cf_images_module_enabled', false, 'full-offload' ) ) : ?>
<li><a href="#" class="cf-images-delete" data-id="<?php echo esc_attr( $post_id ); ?>">
<a href="#" class="dropdown-item cf-images-delete" data-id="<?php echo esc_attr( $post_id ); ?>">
<img src="<?php echo esc_url( CF_IMAGES_DIR_URL . 'assets/images/icons/delete.svg' ); ?>" alt="<?php esc_attr_e( 'Remove from media library', 'cf-images' ); ?>" />
<?php esc_html_e( 'Delete files on WordPress', 'cf-images' ); ?>
</a></li>
</a>
<?php endif; ?>
<?php else : ?>
<li><a href="#" class="cf-images-offload" data-id="<?php echo esc_attr( $post_id ); ?>">
<a href="#" class="dropdown-item cf-images-offload" data-id="<?php echo esc_attr( $post_id ); ?>">
<?php if ( $skipped ) : ?>
<img src="<?php echo esc_url( CF_IMAGES_DIR_URL . 'assets/images/icons/unpause.svg' ); ?>" alt="<?php esc_attr_e( 'Re-upload to Cloudflare', 'cf-images' ); ?>" />
<?php esc_html_e( 'Re-upload to Cloudflare', 'cf-images' ); ?>
<?php else : ?>
<img src="<?php echo esc_url( CF_IMAGES_DIR_URL . 'assets/images/icons/cloud.svg' ); ?>" alt="<?php esc_attr_e( 'Upload to Cloudflare', 'cf-images' ); ?>" />
<?php esc_html_e( 'Upload to Cloudflare', 'cf-images' ); ?>
<?php endif; ?>
</a></li>
</a>
<?php if ( ! $skipped ) : ?>
<li><a href="#" class="cf-images-skip" data-id="<?php echo esc_attr( $post_id ); ?>">
<a href="#" class="dropdown-item cf-images-skip" data-id="<?php echo esc_attr( $post_id ); ?>">
<img src="<?php echo esc_url( CF_IMAGES_DIR_URL . 'assets/images/icons/pause.svg' ); ?>" alt="<?php esc_attr_e( 'Ignore and skip image', 'cf-images' ); ?>" />
<?php esc_html_e( 'Ignore and skip image', 'cf-images' ); ?>
</a></li>
</a>
<?php endif; ?>
<?php endif; ?>
<?php if ( apply_filters( 'cf_images_module_enabled', false, 'image-ai' ) ) : ?>
<li><a href="#" class="cf-images-ai-alt" data-id="<?php echo esc_attr( $post_id ); ?>">
<a href="#" class="dropdown-item cf-images-ai-alt" data-id="<?php echo esc_attr( $post_id ); ?>">
<img src="<?php echo esc_url( CF_IMAGES_DIR_URL . 'assets/images/icons/wand.svg' ); ?>" alt="<?php esc_attr_e( 'Generate alt text', 'cf-images' ); ?>" />
<?php esc_html_e( 'Generate alt text', 'cf-images' ); ?>
</a></li>
</a>
<?php endif; ?>
<?php do_action( 'cf_images_media_module_actions', (int) $post_id ); ?>
</ul>
</li>
</ul>
</div>
</div>
</div>
<?php
}

Expand Down Expand Up @@ -392,6 +401,13 @@ public function upload_image( $metadata, int $attachment_id, string $action = ''
if ( ! isset( $metadata['file'] ) ) {
update_post_meta( $attachment_id, '_cloudflare_image_skip', true );
do_action( 'cf_images_error', 404, __( 'Media file not found', 'cf-images' ) );
do_action(
'cf_images_log',
sprintf( /* translators: %d: attachment ID */
esc_html__( 'Unable to offload image. Media file not found. Attachment ID: %d.', 'cf-images' ),
absint( $attachment_id )
)
);
return $metadata;
}

Expand All @@ -403,6 +419,13 @@ public function upload_image( $metadata, int $attachment_id, string $action = ''
if ( ! wp_attachment_is_image( $attachment_id ) || false !== strpos( $mime, 'image/svg' ) ) {
update_post_meta( $attachment_id, '_cloudflare_image_skip', true );
do_action( 'cf_images_error', 415, __( 'Unsupported media type', 'cf-images' ) );
do_action(
'cf_images_log',
sprintf( /* translators: %d: attachment ID */
esc_html__( 'Unable to offload image. Unsupported media type. Attachment ID: %d.', 'cf-images' ),
absint( $attachment_id )
)
);
return $metadata;
}

Expand All @@ -415,7 +438,7 @@ public function upload_image( $metadata, int $attachment_id, string $action = ''
}

$url = wp_parse_url( get_site_url() );
if ( is_multisite() && ! is_subdomain_install() ) {
if ( is_multisite() && ! is_subdomain_install() && isset( $url['path'] ) ) {
$host = $url['host'] . $url['path'];
} else {
$host = $url['host'];
Expand Down Expand Up @@ -453,6 +476,14 @@ public function upload_image( $metadata, int $attachment_id, string $action = ''
}
} catch ( Exception $e ) {
do_action( 'cf_images_error', $e->getCode(), $e->getMessage() );
do_action(
'cf_images_log',
sprintf( /* translators: %1$d: attachment ID, %2$s: error message */
esc_html__( 'Unable to offload image. Attachment ID: %1$d. Error: %2$s', 'cf-images' ),
absint( $attachment_id ),
esc_html( $e->getMessage() )
)
);
}

return $metadata;
Expand Down Expand Up @@ -487,6 +518,14 @@ public function remove_from_cloudflare( int $post_id ) {
}
} catch ( Exception $e ) {
do_action( 'cf_images_error', $e->getCode(), $e->getMessage() );
do_action(
'cf_images_log',
sprintf( /* translators: %1$d: attachment ID, %2$s: error message */
esc_html__( 'Unable to remove image from Cloudflare. Attachment ID: %1$d. Error: %2$s', 'cf-images' ),
absint( $post_id ),
esc_html( $e->getMessage() )
)
);
}
}

Expand Down Expand Up @@ -663,6 +702,14 @@ public function ajax_restore_image( $attachment_id = null ) {
wp_create_image_subsizes( $original, $attachment_id );
} catch ( Exception $e ) {
do_action( 'cf_images_error', $e->getCode(), $e->getMessage() );
do_action(
'cf_images_log',
sprintf( /* translators: %1$d: attachment ID, %2$s: error message */
esc_html__( 'Unable to restore image. Attachment ID: %1$d. Error: %2$s', 'cf-images' ),
absint( $attachment_id ),
esc_html( $e->getMessage() )
)
);
}

delete_post_meta( $attachment_id, '_cloudflare_image_offloaded' );
Expand Down Expand Up @@ -763,4 +810,69 @@ public function orderby_column( WP_Query $query ): WP_Query {

return $query;
}

/**
* Filters the items in the bulk actions menu of the list table.
*
* @since 1.9.4
*
* @param array $actions An array of the available bulk actions.
*
* @return array
*/
public function bulk_media_actions( array $actions ): array {
$actions['cf-offload'] = esc_html__( 'Upload to Cloudflare', 'cf-images' );

return $actions;
}

/**
* Fires when a custom bulk action should be handled.
*
* @since 1.9.4
*
* @param string $redirect_to The redirect URL.
* @param string $action The action being taken.
* @param array $items The items to take the action on. Accepts an array of IDs of attachments.
*/
public function bulk_action_handler( string $redirect_to, string $action, array $items ): string {
if ( 'cf-offload' !== $action || empty( $items ) ) {
return $redirect_to;
}

foreach ( $items as $id ) {
$this->upload_image( wp_get_attachment_metadata( $id ), $id );
}

return add_query_arg( 'cf_offload_done', count( $items ), $redirect_to );
}

/**
* Show success notice.
*
* @since 1.9.4
*/
public function bulk_action_admin_notice() {
$items_count = filter_input( INPUT_GET, 'cf_offload_done', FILTER_SANITIZE_NUMBER_INT );

if ( ! $items_count ) {
return;
}

printf(
'<div id="message" class="updated notice is-dismissible"><p>' .
/* translators: %d - number of items processed */
esc_html__( '%d image(s) offloaded to Cloudflare.', 'cf-images' ) . '</p></div>',
(int) $items_count
);

// Remove the query parameter after showing the notice.
$current_url = remove_query_arg( 'cf_offload_done' );
echo '<script type="text/javascript">
if (history.pushState) {
const newurl = "' . esc_url_raw( $current_url ) . '";
window.history.pushState({path: newurl}, "", newurl);
}
</script>';
}
}
1 change: 1 addition & 0 deletions app/class-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class Settings {
'logging' => false,
'rss-feeds' => false,
'no-offload-user' => false, // Do not offload images for logged-in users.
'process-head' => false,
);

/**
Expand Down
2 changes: 1 addition & 1 deletion app/integrations/class-aio-seo.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function integration_options( array $options, string $slug ): array {
array(
'name' => 'image_object',
'label' => esc_html__( 'Replace ImageObject', 'cf-images' ),
'description' => esc_html__( 'Use Cloudflare image for the ImageObject in the application/ld+json schema.', 'cf-images' ),
'description' => esc_html__( 'Use Cloudflare image for the ImageObject in the application/ld+json schema. Requires the `Process images in head` option to be enabled in Settings - Misc Options.', 'cf-images' ),
'value' => apply_filters( 'cf_images_integration_option_value', false, 'image_object' ),
),
);
Expand Down
4 changes: 2 additions & 2 deletions app/integrations/class-rank-math.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,13 @@ public function integration_options( array $options, string $slug ): array {
array(
'name' => 'image_object',
'label' => esc_html__( 'Replace ImageObject', 'cf-images' ),
'description' => esc_html__( 'Use Cloudflare image for the ImageObject in the application/ld+json schema.', 'cf-images' ),
'description' => esc_html__( 'Use Cloudflare image for the ImageObject in the application/ld+json schema. Requires the `Process images in head` option to be enabled in Settings - Misc Options.', 'cf-images' ),
'value' => apply_filters( 'cf_images_integration_option_value', false, 'image_object' ),
),
array(
'name' => 'head',
'label' => esc_html__( 'Replace images in head', 'cf-images' ),
'description' => esc_html__( 'Use Cloudflare images in the head page element.', 'cf-images' ),
'description' => esc_html__( 'Use Cloudflare images in the head page element. Requires the `Process images in head` option to be enabled in Settings - Misc Options.', 'cf-images' ),
'value' => apply_filters( 'cf_images_integration_option_value', false, 'head' ),
),
);
Expand Down
1 change: 1 addition & 0 deletions app/modules/class-image-ai.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ private function caption_image( int $attachment_id ) {
}
} catch ( Exception $e ) {
do_action( 'cf_images_error', $e->getCode(), $e->getMessage() );
do_action( 'cf_images_log', $e->getMessage() );
return new WP_Error( 'caption_error', $e->getMessage() );
}
}
Expand Down
4 changes: 2 additions & 2 deletions app/modules/class-image-compress.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,10 @@ public function media_lib_actions( int $attachment_id ) {
return;
}
?>
<li><a href="#" class="cf-images-compress" data-id="<?php echo esc_attr( $attachment_id ); ?>">
<a href="#" class="dropdown-item cf-images-compress" data-id="<?php echo esc_attr( $attachment_id ); ?>">
<img src="<?php echo esc_url( CF_IMAGES_DIR_URL . 'assets/images/icons/minimize.svg' ); ?>" alt="<?php esc_attr_e( 'Compress image', 'cf-images' ); ?>" />
<?php esc_html_e( 'Compress image', 'cf-images' ); ?>
</a></li>
</a>
<?php
}

Expand Down
2 changes: 1 addition & 1 deletion app/modules/class-logging.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ private function init_log_file() {
* @return void
*/
public function log( $message, ...$args ) {
if ( ( empty( $message ) && empty( $args ) ) || is_admin() ) {
if ( ( empty( $message ) && empty( $args ) ) || ( is_admin() && ! wp_doing_ajax() ) ) {
return;
}

Expand Down
4 changes: 4 additions & 0 deletions app/modules/class-module.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ protected function can_run( int $attachment_id = 0 ): bool {
return false;
}

if ( doing_action( 'wp_head' ) && ! $this->is_module_enabled( false, 'process-head' ) ) {
return false;
}

if ( did_action( 'wp' ) && ! $this->is_module_enabled( false, 'rss-feeds' ) && is_feed() ) {
return false;
}
Expand Down
1 change: 1 addition & 0 deletions app/traits/trait-stats.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ private function fetch_stats( Image $image ) {
update_option( 'cf-images-stats', $stats, false );
} catch ( Exception $e ) {
do_action( 'cf_images_error', $e->getCode(), $e->getMessage() );
do_action( 'cf_images_log', $e->getMessage() );
}
}

Expand Down
Loading

0 comments on commit 2c95719

Please sign in to comment.