wp_create_nonce('ime-admin-nonce'),
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'initial_tab' => ime_current_tab(),
'request_failed' => __( 'The request failed. Please try again.', 'imagemagick-engine' ),
'path_found' => __( 'Command found.', 'imagemagick-engine' ),
'regen_running' => __( 'Regenerating images', 'imagemagick-engine' ),
'regen_paused' => __( 'Regeneration in progress', 'imagemagick-engine' ),
/* translators: %d: number of minutes */
'regen_eta_fmt' => __( 'about %d min remaining', 'imagemagick-engine' ),
/* translators: %d: number of images */
'regen_done_fmt' => __( 'Finished. Processed %d images.', 'imagemagick-engine' ),
/* translators: %d: number of images */
'regen_failed_fmt' => __( '%d failed', 'imagemagick-engine' ),
'regen_ended' => __( 'This run is no longer active. It either finished or expired.', 'imagemagick-engine' ),
/* translators: 1: number of images processed, 2: total number of images */
'regen_ended_progress_fmt' => __( 'Last known progress: %1$s of %2$s images.', 'imagemagick-engine' ),
];
// Engine detection (ime_mode_valid() for all four engines) is only read by
// the imeSettings component, which exists only on this plugin's own page.
// Running it on every media screen forks proc_open() under WP_DEBUG and
// writes ime_options on every page load.
if ( get_current_screen() && $ime_page === get_current_screen()->id ) {
$engine_state = ime_resolve_engine_state();
$data['enabled'] = $engine_state['enabled'];
$data['mode'] = (string) $engine_state['mode'];
}
wp_localize_script( 'ime-admin', 'ime_admin', $data );
}
/* Enqueue admin page style */
function ime_admin_print_styles() {
wp_enqueue_style( 'ime-admin-style', plugins_url( '/css/ime-admin.css', dirname( __DIR__ ) . '/imagemagick-engine.php' ), [], constant( 'IME_VERSION' ) );
}
/* Add settings to plugin action links */
function ime_filter_plugin_actions( $links, $file ) {
if ( $file == plugin_basename( dirname( __DIR__ ) . '/imagemagick-engine.php' ) ) {
$settings_link = ''
. __( 'Settings', 'imagemagick-engine' ) . '';
array_unshift( $links, $settings_link ); // before other links
}
return $links;
}
/*
* Add admin information if attachment is converted using plugin
*/
function ime_filter_media_meta( $content, $post ) {
if ( ! ime_mode_valid() ) {
return $content;
}
if ( ! wp_image_editor_supports( [ 'mime_type' => $post->post_mime_type ] ) ) {
return $content;
}
$metadata = wp_get_attachment_metadata( $post->ID );
$ime = false;
if ( is_array( $metadata ) && array_key_exists( 'image-converter', $metadata ) ) {
foreach ( $metadata['image-converter'] as $size => $converter ) {
if ( $converter != 'IME' ) {
continue;
}
$ime = true;
break;
}
}
if ( $ime ) {
$initial_message = __( 'Resized using ImageMagick Engine', 'imagemagick-engine' );
$resize = __( 'Resize image', 'imagemagick-engine' );
$force = '1';
} else {
$initial_message = '';
$resize = __( 'Resize using ImageMagick Engine', 'imagemagick-engine' );
$force = '0';
}
$handle_sizes = ime_get_option( 'handle_sizes' );
$sizes = [];
foreach ( $handle_sizes as $s => $h ) {
if ( ! $h || 'skip' === $h ) {
continue;
}
$sizes[] = $s;
}
// Every configured size is None: there is nothing this button could do
// except fail with "Select at least one image size.", so don't render it.
if ( empty( $sizes ) ) {
return $content;
}
$content .= '
';
$content .= sprintf(
''
. ''
. ''
. ''
. '',
absint( $post->ID ),
esc_attr( implode( '|', $sizes ) ),
esc_attr( $force ),
esc_attr( $initial_message ),
esc_html( $resize )
);
return $content;
}
// Define available modes
function ime_get_available_modes(): array {
return array(
'php' => __( 'Imagick PHP module', 'imagemagick-engine' ),
'gmagick' => __( 'Gmagick PHP module', 'imagemagick-engine' ),
'cli' => __( 'ImageMagick command-line', 'imagemagick-engine' ),
'graphicsmagick' => __( 'GraphicsMagick command-line', 'imagemagick-engine' ),
);
}
/**
* Resolve the engine to use and whether the plugin is effectively enabled.
*
* Falls back to the first valid engine when the stored mode is missing or
* unavailable, so the rendered form and the JavaScript state cannot disagree.
*
* @return array{mode: ?string, enabled: bool, valid: array}
*/
function ime_resolve_engine_state() {
$valid = ime_get_available_modes();
foreach ( $valid as $m => $ignore ) {
$valid[ $m ] = ime_mode_valid( $m );
}
$mode = ime_get_option( 'mode' );
if ( ! isset( $valid[ $mode ] ) || ! $valid[ $mode ] ) {
$mode = null;
}
if ( is_null( $mode ) ) {
foreach ( $valid as $m => $is_valid ) {
if ( $is_valid ) {
$mode = $m;
break;
}
}
}
$enabled = (bool) ( ime_get_option( 'enabled' ) && $mode );
return [
'mode' => $mode,
'enabled' => $enabled,
'valid' => $valid,
];
}
/**
* Render one engine choice as a selectable card.
*
* @param string $mode Engine key, e.g. 'php'.
* @param string $label Human-readable engine name.
* @param bool $valid Whether the engine is usable on this server.
* @param string $detail Version string or reason it is unavailable.
* @param string $current_mode Currently selected engine key.
* @param string $path_field_html Optional markup rendered inside the card when selected.
*/
function ime_render_engine_card( $mode, $label, $valid, $detail, $current_mode, $path_field_html = '' ) {
$id = 'ime-engine-' . $mode;
$desc = $id . '-status';
$icon = $valid ? 'dashicons-yes-alt' : 'dashicons-dismiss';
$state = $valid
? __( 'Available', 'imagemagick-engine' )
: __( 'Not available', 'imagemagick-engine' );
$classes = 'ime-engine-card' . ( $valid ? '' : ' ime-engine-card--unavailable' );
?>
0 ) {
check_admin_referer( 'ime-options' );
}
$sizes = ime_available_image_sizes();
/* Should we update settings? */
if ( isset( $_POST['update_settings'] ) ) {
$new_enabled = isset( $_POST['enabled'] ) && ! ! $_POST['enabled'];
ime_set_option( 'enabled', $new_enabled );
if ( isset( $_POST['mode'] ) ) {
$posted_mode = sanitize_key( wp_unslash( $_POST['mode'] ) );
if ( array_key_exists( $posted_mode, ime_get_available_modes() ) ) {
ime_set_option( 'mode', $posted_mode );
}
}
if ( isset( $_POST['cli_path'] ) ) {
ime_set_option( 'cli_path', ime_try_realpath( sanitize_text_field( wp_unslash( $_POST['cli_path'] ) ) ) );
delete_transient( 'ime_cli_valid' );
}
if ( isset( $_POST['gm_path'] ) ) {
ime_set_option( 'gm_path', ime_try_realpath( sanitize_text_field( wp_unslash( $_POST['gm_path'] ) ) ) );
delete_transient( 'ime_gm_valid' );
}
$new_quality = [
'quality' => -1,
'size' => 70,
];
if ( isset( $_POST['quality-quality'] ) ) {
if ( is_numeric( $_POST['quality-quality'] ) ) {
$new_quality['quality'] = min( 100, max( 0, intval( $_POST['quality-quality'] ) ) );
} elseif ( empty( $_POST['quality-quality'] ) ) {
$new_quality['quality'] = -1;
}
}
if ( isset( $_POST['quality-size'] ) ) {
if ( is_numeric( $_POST['quality-size'] ) ) {
$new_quality['size'] = min( 100, max( 0, intval( $_POST['quality-size'] ) ) );
} elseif ( empty( $_POST['quality-size'] ) ) {
$new_quality['size'] = -1;
}
}
ime_set_option( 'quality', $new_quality );
$new_interlace = isset( $_POST['interlace'] ) && ! ! $_POST['interlace'];
ime_set_option( 'interlace', $new_interlace );
$new_keep_exif = isset( $_POST['keep_exif'] ) && ! ! $_POST['keep_exif'];
ime_set_option( 'keep_exif', $new_keep_exif );
// Only saved when the setting is shown, so older WordPress versions keep the stored value.
if ( ime_client_side_processing_available() ) {
$new_disable_csp = isset( $_POST['disable_client_side_processing'] ) && ! ! $_POST['disable_client_side_processing'];
ime_set_option( 'disable_client_side_processing', $new_disable_csp );
}
$new_handle_sizes = [];
foreach ( $sizes as $s => $name ) {
$new_mode = isset( $_POST[ 'handle-mode-' . $s ] ) ? $_POST[ 'handle-mode-' . $s ] : 'skip';
if ( in_array( $new_mode, $ime_available_quality_modes ) ) {
$mode = $new_mode;
} else {
$mode = 'quality';
}
$new_handle_sizes[ $s ] = $mode;
}
ime_set_option( 'handle_sizes', $new_handle_sizes );
ime_store_options();
wp_admin_notice(
__( 'Settings updated', 'imagemagick-engine' ),
[
'type' => 'success',
'dismissible' => true,
]
);
}
$engine_state = ime_resolve_engine_state();
$modes_valid = $engine_state['valid'];
$current_mode = $engine_state['mode'];
$enabled = $engine_state['enabled'];
$any_valid = in_array( true, $modes_valid, true );
$cli_path = ime_get_option( 'cli_path' );
if ( is_null( $cli_path ) ) {
$cli_path = ime_im_cli_command();
}
$cli_path_ok = ime_im_cli_check_command( $cli_path );
$gm_path = ime_get_option( 'gm_path' );
if ( is_null( $gm_path ) ) {
$gm_path = ime_im_cli_command( true );
}
$gm_path_ok = ime_im_cli_check_command( $gm_path, true );
$quality = ime_get_option( 'quality' );
if ( ! is_array( $quality ) ) {
$n = [
'quality' => -1,
'size' => 70,
];
if ( is_numeric( $quality ) && $quality > 0 ) {
$n['quality'] = $quality;
}
$quality = $n;
}
$interlace = ime_get_option( 'interlace' );
$keep_exif = ime_get_option( 'keep_exif' );
$disable_client_side_processing = ime_get_option( 'disable_client_side_processing' );
$handle_sizes = ime_get_option( 'handle_sizes' );
if ( ! $any_valid ) {
wp_admin_notice(
__( 'No valid ImageMagick mode found!', 'imagemagick-engine' ),
[ 'type' => 'error' ]
);
} elseif ( ! $enabled ) {
wp_admin_notice(
__( 'ImageMagick Engine is not enabled.', 'imagemagick-engine' ),
[ 'type' => 'warning' ]
);
}
?>