821 lines
20 KiB
PHP
821 lines
20 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* Dam class.
|
||
|
*
|
||
|
* Author: Andrei Baicus <andrei@themeisle.com>
|
||
|
* Created on: 04/07/2023
|
||
|
*
|
||
|
* @package \Optimole\Inc
|
||
|
* @author Optimole <friends@optimole.com>
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Class Optml_Dam
|
||
|
*/
|
||
|
class Optml_Dam {
|
||
|
use Optml_Dam_Offload_Utils;
|
||
|
use Optml_Normalizer;
|
||
|
|
||
|
/**
|
||
|
* Hold the settings object.
|
||
|
*
|
||
|
* @var Optml_Settings Settings object.
|
||
|
*/
|
||
|
private $settings;
|
||
|
|
||
|
/**
|
||
|
* The dam endpoint.
|
||
|
*
|
||
|
* @var string
|
||
|
*/
|
||
|
private $dam_endpoint = 'https://dashboard.optimole.com/dam';
|
||
|
|
||
|
const OM_DAM_IMPORTED_FLAG = 'om-dam-imported';
|
||
|
const URL_DAM_FLAG = '/dam:1';
|
||
|
const IS_EDIT_FLAG = 'om-dam-edit';
|
||
|
|
||
|
/**
|
||
|
* Optml_Dam constructor.
|
||
|
*/
|
||
|
public function __construct() {
|
||
|
$this->settings = Optml_Main::instance()->admin->settings;
|
||
|
|
||
|
if ( ! $this->settings->is_connected() ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( $this->settings->get( 'cloud_images' ) === 'enabled' ) {
|
||
|
add_action( 'admin_menu', [ $this, 'add_menu' ] );
|
||
|
add_action( 'print_media_templates', [ $this, 'print_media_template' ] );
|
||
|
add_action( 'wp_enqueue_media', [ $this, 'enqueue_media_scripts' ] );
|
||
|
add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_page_scripts' ] );
|
||
|
}
|
||
|
|
||
|
if ( defined( 'OPTML_DAM_ENDPOINT' ) ) {
|
||
|
$this->dam_endpoint = constant( 'OPTML_DAM_ENDPOINT' );
|
||
|
}
|
||
|
|
||
|
add_filter( 'wp_get_attachment_image_src', [ $this, 'alter_attachment_image_src' ], 10, 4 );
|
||
|
add_filter( 'wp_get_attachment_metadata', [ $this, 'alter_attachment_metadata' ], 10, 2 );
|
||
|
add_filter( 'image_downsize', [ $this, 'catch_downsize' ], 10, 3 );
|
||
|
add_filter( 'wp_prepare_attachment_for_js', [$this, 'alter_attachment_for_js'], 10, 3 );
|
||
|
add_filter( 'wp_image_src_get_dimensions', [$this, 'alter_img_tag_w_h'], 10, 4 );
|
||
|
add_filter( 'get_attached_file', [$this, 'alter_attached_file_response'], 10, 2 );
|
||
|
add_filter( 'wp_calculate_image_srcset', [$this, 'disable_dam_images_srcset'], 1, 5 );
|
||
|
|
||
|
add_filter(
|
||
|
'elementor/image_size/get_attachment_image_html',
|
||
|
[
|
||
|
$this,
|
||
|
'alter_elementor_image_size',
|
||
|
],
|
||
|
10,
|
||
|
4
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Catch image downsize for the DAM imported images.
|
||
|
*
|
||
|
* @param array $image {
|
||
|
* Array of image data.
|
||
|
*
|
||
|
* @type string $0 Image source URL.
|
||
|
* @type int $1 Image width in pixels.
|
||
|
* @type int $2 Image height in pixels.
|
||
|
* @type bool $3 Whether the image is a resized image.
|
||
|
*
|
||
|
* @param int $id attachment id.
|
||
|
* @param string|int[] $size image size.
|
||
|
*
|
||
|
* @return array $image.
|
||
|
*/
|
||
|
public function catch_downsize( $image, $id, $size ) {
|
||
|
return $this->alter_attachment_image_src( $image, $id, $size, false );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Insert attachments.
|
||
|
*
|
||
|
* @param array $images Images array.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function insert_attachments( $images ) {
|
||
|
$ids = [];
|
||
|
|
||
|
$existing = $this->check_existing_attachments( $images );
|
||
|
|
||
|
foreach ( $images as $image ) {
|
||
|
if ( ! isset( $image['isEdit'] ) && array_key_exists( $image['meta']['resourceS3'], $existing ) ) {
|
||
|
$ids[] = $existing[ $image['meta']['resourceS3'] ];
|
||
|
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$id = $this->insert_attachment( $image );
|
||
|
|
||
|
if ( $id === 0 ) {
|
||
|
continue;
|
||
|
}
|
||
|
$ids[] = $id;
|
||
|
}
|
||
|
|
||
|
return $ids;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Insert single attachment
|
||
|
*
|
||
|
* @param array $image Image data.
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
private function insert_attachment( $image ) {
|
||
|
$filename = basename( $image['url'] );
|
||
|
$name = pathinfo( $filename, PATHINFO_FILENAME );
|
||
|
|
||
|
$args = [
|
||
|
'post_title' => $name,
|
||
|
'post_type' => 'attachment',
|
||
|
'post_mime_type' => $image['meta']['mimeType'],
|
||
|
'guid' => $image['url'],
|
||
|
];
|
||
|
|
||
|
$id = wp_insert_attachment( $args );
|
||
|
|
||
|
if ( $id === 0 ) {
|
||
|
return $id;
|
||
|
}
|
||
|
|
||
|
update_post_meta( $id, self::OM_DAM_IMPORTED_FLAG, $image['meta']['resourceS3'] );
|
||
|
|
||
|
if ( isset( $image['isEdit'] ) ) {
|
||
|
update_post_meta( $id, self::IS_EDIT_FLAG, true );
|
||
|
}
|
||
|
|
||
|
$metadata = [];
|
||
|
|
||
|
$metadata['file'] = '/id:' . $image['meta']['resourceS3'] . '/' . get_home_url() . '/' . $filename;
|
||
|
$metadata['mime-type'] = $image['meta']['mimeType'];
|
||
|
|
||
|
if ( isset( $image['meta']['filesize'] ) ) {
|
||
|
$metadata['filesize'] = $image['meta']['fileSize'];
|
||
|
}
|
||
|
|
||
|
if ( isset( $image['meta']['originalWidth'] ) && isset( $image['meta']['originalHeight'] ) ) {
|
||
|
$metadata['width'] = $image['meta']['originalWidth'];
|
||
|
$metadata['height'] = $image['meta']['originalHeight'];
|
||
|
}
|
||
|
|
||
|
wp_update_attachment_metadata( $id, $metadata );
|
||
|
|
||
|
return $id;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Alter attachment image src for DAM imported images.
|
||
|
*
|
||
|
* @param array|false $image {
|
||
|
* Array of image data.
|
||
|
*
|
||
|
* @type string $0 Image source URL.
|
||
|
* @type int $1 Image width in pixels.
|
||
|
* @type int $2 Image height in pixels.
|
||
|
* @type bool $3 Whether the image is a resized image.
|
||
|
* }
|
||
|
*
|
||
|
* @param int $attachment_id attachment id.
|
||
|
* @param string|int[] $size image size.
|
||
|
* @param bool $icon Whether the image should be treated as an icon.
|
||
|
*
|
||
|
* @return array $image.
|
||
|
*/
|
||
|
public function alter_attachment_image_src( $image, $attachment_id, $size, $icon ) {
|
||
|
// Skip if not DAM image.
|
||
|
if ( ! $this->is_dam_imported_image( $attachment_id ) ) {
|
||
|
return $image;
|
||
|
}
|
||
|
|
||
|
$image_url = wp_get_attachment_url( $attachment_id );
|
||
|
$incoming_size = $this->parse_dimension_from_optimized_url( $image_url );
|
||
|
$width = $incoming_size[0];
|
||
|
$height = $incoming_size[1];
|
||
|
|
||
|
// Skip resize in single attachment view on backend.
|
||
|
if ( $this->is_attachment_edit_page( $attachment_id ) ) {
|
||
|
return [
|
||
|
$image_url,
|
||
|
$width,
|
||
|
$height,
|
||
|
false,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
// Use the original size if the requested size is full.
|
||
|
if ( $size === 'full' ) {
|
||
|
$metadata = wp_get_attachment_metadata( $attachment_id );
|
||
|
|
||
|
$image_url = $this->replace_dam_url_args(
|
||
|
[
|
||
|
'width' => $metadata['width'],
|
||
|
'height' => $metadata['height'],
|
||
|
'crop' => false,
|
||
|
],
|
||
|
$image_url
|
||
|
);
|
||
|
|
||
|
return [
|
||
|
$image_url,
|
||
|
$metadata['width'],
|
||
|
$metadata['height'],
|
||
|
false,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
$crop = false;
|
||
|
|
||
|
// Size can be int [] containing width and height.
|
||
|
if ( is_array( $size ) ) {
|
||
|
$width = $size[0];
|
||
|
$height = $size[1];
|
||
|
$crop = true;
|
||
|
} else {
|
||
|
$sizes = $this->get_all_image_sizes();
|
||
|
|
||
|
if ( ! isset( $sizes[ $size ] ) ) {
|
||
|
return [
|
||
|
$image_url,
|
||
|
$width,
|
||
|
$height,
|
||
|
false,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
$width = $sizes[ $size ]['width'];
|
||
|
$height = $sizes[ $size ]['height'];
|
||
|
$crop = (bool) $sizes[ $size ]['crop'];
|
||
|
}
|
||
|
|
||
|
$image_url = $this->replace_dam_url_args(
|
||
|
[
|
||
|
'width' => $width,
|
||
|
'height' => $height,
|
||
|
'crop' => $crop,
|
||
|
],
|
||
|
$image_url
|
||
|
);
|
||
|
|
||
|
return [
|
||
|
$image_url,
|
||
|
$width,
|
||
|
$height,
|
||
|
$crop,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Alter the attachment metadata.
|
||
|
*
|
||
|
* @param array $metadata attachment metadata.
|
||
|
* @param int $id attachment ID.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function alter_attachment_metadata( $metadata, $id ) {
|
||
|
if ( ! $this->is_dam_imported_image( $id ) ) {
|
||
|
return $metadata;
|
||
|
}
|
||
|
|
||
|
return $this->get_altered_metadata_for_remote_images( $metadata, $id );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if the images are already imported.
|
||
|
*
|
||
|
* @param array $images List of images to check.
|
||
|
*
|
||
|
* @return array List of images that are already imported.
|
||
|
*/
|
||
|
private function check_existing_attachments( $images ) {
|
||
|
$already_imported = $this->get_dam_imported_attachments( $images );
|
||
|
|
||
|
// All DAM imports are already in the DB.
|
||
|
if ( count( $already_imported ) === count( $images ) ) {
|
||
|
return $already_imported;
|
||
|
}
|
||
|
|
||
|
// Get the remaining images.
|
||
|
$remaining = array_filter(
|
||
|
$images,
|
||
|
function ( $image ) use ( $already_imported ) {
|
||
|
return ! array_key_exists( $image['meta']['resourceS3'], $already_imported );
|
||
|
}
|
||
|
);
|
||
|
|
||
|
// Offloaded images.
|
||
|
if ( $this->settings->get( 'offload_media' ) === 'enabled' ) {
|
||
|
$offloaded = $this->get_offloaded_attachments( $remaining );
|
||
|
|
||
|
$already_imported = array_merge( $already_imported, $offloaded );
|
||
|
}
|
||
|
|
||
|
return $already_imported;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if the images are already imported.
|
||
|
*
|
||
|
* @param array $images List of images to check.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
private function get_dam_imported_attachments( $images ) {
|
||
|
global $wpdb;
|
||
|
|
||
|
$s3_ids = [];
|
||
|
|
||
|
foreach ( $images as $image ) {
|
||
|
$s3_ids[] = esc_sql( strval( $image['meta']['resourceS3'] ) );
|
||
|
}
|
||
|
|
||
|
$meta_values_str = "'" . join( "', '", $s3_ids ) . "'";
|
||
|
|
||
|
// Select all the posts that have the flag and are in the list of images.
|
||
|
$found_attachments = $wpdb->get_results(
|
||
|
$wpdb->prepare(
|
||
|
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- This query cannot use interpolation.
|
||
|
"SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value IN ( {$meta_values_str} )",
|
||
|
self::OM_DAM_IMPORTED_FLAG
|
||
|
)
|
||
|
);
|
||
|
|
||
|
if ( empty( $found_attachments ) ) {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
$map = [];
|
||
|
|
||
|
// Remap this in a key/value array.
|
||
|
// Also ensures that if there are multiple attachments with the same S3 ID, we only get the one.
|
||
|
// Shouldn't happen, but just in case.
|
||
|
foreach ( $found_attachments as $attachment ) {
|
||
|
// Skip edits.
|
||
|
if ( ! empty( get_post_meta( $attachment->post_id, self::IS_EDIT_FLAG, true ) ) ) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$map[ $attachment->meta_value ] = (int) $attachment->post_id;
|
||
|
}
|
||
|
|
||
|
return $map;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the offloaded attachments.
|
||
|
*
|
||
|
* [ S3 ID => Attachment Post ID ]
|
||
|
*
|
||
|
* @param array $images List of images to check.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
private function get_offloaded_attachments( $images ) {
|
||
|
global $wpdb;
|
||
|
|
||
|
$map = [];
|
||
|
|
||
|
foreach ( $images as $image ) {
|
||
|
$like = '%id:' . $image['meta']['resourceS3'] . '%';
|
||
|
|
||
|
$found_attachments = $wpdb->get_results(
|
||
|
$wpdb->prepare(
|
||
|
"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = %s AND meta_value LIKE %s",
|
||
|
'_wp_attachment_metadata',
|
||
|
$like
|
||
|
)
|
||
|
);
|
||
|
|
||
|
if ( empty( $found_attachments ) ) {
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
$map[ $image['meta']['resourceS3'] ] = (int) $found_attachments[0]->post_id;
|
||
|
}
|
||
|
|
||
|
return $map;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Adds menu item for DAM.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function add_menu() {
|
||
|
if ( defined( 'OPTIOMLE_HIDE_ADMIN_AREA' ) && OPTIOMLE_HIDE_ADMIN_AREA ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
add_submenu_page(
|
||
|
'optimole',
|
||
|
__( 'Cloud Library', 'optimole-wp' ),
|
||
|
__( 'Cloud Library', 'optimole-wp' ),
|
||
|
'manage_options',
|
||
|
'optimole-dam',
|
||
|
[ $this, 'render_dashboard_page' ]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add media template to be used in the media library.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function print_media_template() {
|
||
|
?>
|
||
|
<script type="text/html" id="tmpl-optimole-dam">
|
||
|
<?php $this->render_dashboard_page(); ?>
|
||
|
</script>
|
||
|
<?php
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Render the dashboard page.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function render_dashboard_page() {
|
||
|
?>
|
||
|
<style>
|
||
|
.notice:not(.optml-notice-optin){
|
||
|
display: none !important;
|
||
|
}
|
||
|
</style>
|
||
|
<iframe id="om-dam" style="display: none;" src="<?php echo( $this->build_iframe_url() ); ?>"></iframe>
|
||
|
<div class="om-dam-loader">
|
||
|
<img src="<?php echo esc_url( OPTML_URL . 'assets/img/logo.png' ); ?>" alt="Optimole Logo"
|
||
|
class="om-dam-logo">
|
||
|
<p><?php echo esc_html__( 'Loading', 'optimole-wp' ); ?>...</p>
|
||
|
</div>
|
||
|
<?php
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Build the iFrame URL.
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function build_iframe_url() {
|
||
|
$api_key = $this->settings->get( 'api_key' );
|
||
|
$connected_sites = $this->settings->get( 'cloud_sites' );
|
||
|
|
||
|
if ( empty( $api_key ) ) {
|
||
|
return '';
|
||
|
}
|
||
|
|
||
|
if ( isset( $connected_sites['all'] ) && $connected_sites['all'] === 'true' ) {
|
||
|
$connected_sites = [];
|
||
|
} else {
|
||
|
foreach ( $connected_sites as $site => $status ) {
|
||
|
if ( $status !== 'true' ) {
|
||
|
unset( $connected_sites[ $site ] );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$data = [
|
||
|
'site' => get_site_url(),
|
||
|
'token' => $api_key,
|
||
|
'sites' => array_keys( $connected_sites ),
|
||
|
];
|
||
|
|
||
|
$data = json_encode( $data );
|
||
|
$data = rtrim( base64_encode( $data ), '=' );
|
||
|
|
||
|
return add_query_arg(
|
||
|
[
|
||
|
'data' => $data,
|
||
|
],
|
||
|
$this->dam_endpoint
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Enqueue script for generating cloud media tab.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function enqueue_media_scripts() {
|
||
|
$asset_file = include OPTML_PATH . 'assets/build/media/media-modal.asset.php';
|
||
|
|
||
|
wp_register_script(
|
||
|
OPTML_NAMESPACE . '-media-modal',
|
||
|
OPTML_URL . 'assets/build/media/media-modal.js',
|
||
|
$asset_file['dependencies'],
|
||
|
$asset_file['version'],
|
||
|
true
|
||
|
);
|
||
|
|
||
|
wp_localize_script( OPTML_NAMESPACE . '-media-modal', 'optmlMediaModal', $this->get_localized_vars() );
|
||
|
wp_enqueue_script( OPTML_NAMESPACE . '-media-modal' );
|
||
|
wp_enqueue_style( OPTML_NAMESPACE . '-media-modal', OPTML_URL . 'assets/build/media/media-modal.css' );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Enqueue script for generating admin page.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function enqueue_admin_page_scripts() {
|
||
|
$screen = get_current_screen();
|
||
|
|
||
|
if ( $screen->id !== 'optimole_page_optimole-dam' ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$asset_file = include OPTML_PATH . 'assets/build/media/admin-page.asset.php';
|
||
|
|
||
|
wp_register_script(
|
||
|
OPTML_NAMESPACE . '-admin-page',
|
||
|
OPTML_URL . 'assets/build/media/admin-page.js',
|
||
|
$asset_file['dependencies'],
|
||
|
$asset_file['version'],
|
||
|
true
|
||
|
);
|
||
|
|
||
|
wp_localize_script(
|
||
|
OPTML_NAMESPACE . '-admin-page',
|
||
|
'optmlAdminPage',
|
||
|
[
|
||
|
'siteUrl' => get_site_url(),
|
||
|
]
|
||
|
);
|
||
|
|
||
|
wp_enqueue_script( OPTML_NAMESPACE . '-admin-page' );
|
||
|
|
||
|
wp_enqueue_style( OPTML_NAMESPACE . '-admin-page', OPTML_URL . 'assets/build/media/admin-page.css' );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get localized variables for the media modal.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
private function get_localized_vars() {
|
||
|
$routes = array_keys( Optml_Rest::$rest_routes['dam_routes'] );
|
||
|
|
||
|
foreach ( $routes as $route ) {
|
||
|
$routes[ $route ] = OPTML_NAMESPACE . '/v1/' . $route;
|
||
|
}
|
||
|
|
||
|
return [
|
||
|
'nonce' => wp_create_nonce( 'wp_rest' ),
|
||
|
'routes' => $routes,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Alter the image size for the image widget.
|
||
|
*
|
||
|
* @param string $html the attachment image HTML string.
|
||
|
* @param array $settings Control settings.
|
||
|
* @param string $image_size_key Optional. Settings key for image size.
|
||
|
* Default is `image`.
|
||
|
* @param string $image_key Optional. Settings key for image. Default
|
||
|
* is null. If not defined uses image size key
|
||
|
* as the image key.
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function alter_elementor_image_size( $html, $settings, $image_size_key, $image_key ) {
|
||
|
if ( ! isset( $settings['image'] ) ) {
|
||
|
return $html;
|
||
|
}
|
||
|
|
||
|
$image = $settings['image'];
|
||
|
|
||
|
if ( ! isset( $image['id'] ) ) {
|
||
|
return $html;
|
||
|
}
|
||
|
|
||
|
if ( ! $this->is_dam_imported_image( $image['id'] ) ) {
|
||
|
return $html;
|
||
|
}
|
||
|
|
||
|
if ( ! isset( $settings['image_size'] ) ) {
|
||
|
return $html;
|
||
|
}
|
||
|
|
||
|
if ( $settings['image_size'] === 'custom' ) {
|
||
|
if ( ! isset( $settings['image_custom_dimension'] ) ) {
|
||
|
return $html;
|
||
|
}
|
||
|
|
||
|
$custom_dimensions = $settings['image_custom_dimension'];
|
||
|
|
||
|
if ( ! isset( $custom_dimensions['width'] ) || ! isset( $custom_dimensions['height'] ) ) {
|
||
|
return $html;
|
||
|
}
|
||
|
|
||
|
return $this->replace_dam_url_args( $custom_dimensions, $html );
|
||
|
}
|
||
|
|
||
|
$all_sizes = $this->get_all_image_sizes();
|
||
|
|
||
|
if ( ! isset( $all_sizes[ $settings['image_size'] ] ) ) {
|
||
|
return $html;
|
||
|
}
|
||
|
|
||
|
return $this->replace_dam_url_args( $all_sizes[ $settings['image_size'] ], $html );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Needed as some blocks might use the image sizes.
|
||
|
*
|
||
|
* @param array $response Array of prepared attachment data. @see wp_prepare_attachment_for_js().
|
||
|
* @param WP_Post $attachment Attachment object.
|
||
|
* @param array|false $meta Array of attachment meta data, or false if there is none.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function alter_attachment_for_js( $response, $attachment, $meta ) {
|
||
|
if ( ! $this->is_dam_imported_image( $attachment->ID ) ) {
|
||
|
return $response;
|
||
|
}
|
||
|
|
||
|
$sizes = $this->get_all_image_sizes();
|
||
|
|
||
|
foreach ( $sizes as $size => $args ) {
|
||
|
if ( isset( $response['sizes'][ $size ] ) ) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
$args = [
|
||
|
'height' => $args['height'],
|
||
|
'width' => $args['width'],
|
||
|
'crop' => true,
|
||
|
];
|
||
|
|
||
|
$response['sizes'][ $size ] = array_merge(
|
||
|
$args,
|
||
|
[
|
||
|
'url' => $this->replace_dam_url_args( $args, $response['url'] ),
|
||
|
'orientation' => ( $args['height'] > $args['width'] ) ? 'portrait' : 'landscape',
|
||
|
]
|
||
|
);
|
||
|
}
|
||
|
|
||
|
$url_args = [
|
||
|
'height' => $response['height'],
|
||
|
'width' => $response['width'],
|
||
|
'crop' => false,
|
||
|
];
|
||
|
|
||
|
$response['url'] = $this->replace_dam_url_args( $url_args, $response['url'] );
|
||
|
|
||
|
return $response;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* We have to short-circuit the logic that adds width and height to the img tag.
|
||
|
* It compares the URL basename, and the `file` param for each image.
|
||
|
* This happens for any image that gets its size set non-explicitly
|
||
|
* e.g. an image block with its size set from the sidebar to `thumbnail`).
|
||
|
*
|
||
|
* Optimole has a single basename for all image resizes in its URL.
|
||
|
*
|
||
|
* @param array|false $dimensions Array with first element being the width
|
||
|
* and second element being the height, or
|
||
|
* false if dimensions could not be determined.
|
||
|
* @param string $image_src The image URL (will be Optimole URL).
|
||
|
* @param array $image_meta The image metadata.
|
||
|
* @param int $attachment_id The image attachment ID. Default 0.
|
||
|
*/
|
||
|
public function alter_img_tag_w_h( $dimensions, $image_src, $image_meta, $attachment_id ) {
|
||
|
if ( ! $this->is_dam_imported_image( $attachment_id ) ) {
|
||
|
return $dimensions;
|
||
|
}
|
||
|
|
||
|
// Get the dimensions from the optimized URL.
|
||
|
$incoming_size = $this->parse_dimension_from_optimized_url( $image_src );
|
||
|
$width = $incoming_size[0];
|
||
|
$height = $incoming_size[1];
|
||
|
|
||
|
$sizes = $this->get_all_image_sizes();
|
||
|
|
||
|
// If this is an image size. Return its dimensions.
|
||
|
foreach ( $sizes as $size => $args ) {
|
||
|
if ( (int) $args['width'] !== (int) $width ) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( (int) $args['height'] !== (int) $height ) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
return [
|
||
|
$args['width'],
|
||
|
$args['height'],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
// Fall-through with the original dimensions.
|
||
|
return $dimensions;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Replace the image size params in DAM URLs inside a string.
|
||
|
*
|
||
|
* @param array $args The arguments to replace.
|
||
|
* - width: The width of the image.
|
||
|
* - height: The height of the image.
|
||
|
* - crop: Whether to crop the image.
|
||
|
* @param string $subject The string to replace the arguments in.
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function replace_dam_url_args( $args, $subject ) {
|
||
|
$args = wp_parse_args( $args, [ 'width' => 'auto', 'height' => 'auto', 'crop' => false, 'dam' => true] );
|
||
|
|
||
|
$width = $args['width'];
|
||
|
$height = $args['height'];
|
||
|
$crop = (bool) $args['crop'];
|
||
|
|
||
|
$gravity = Optml_Resize::GRAVITY_CENTER;
|
||
|
|
||
|
if ( $this->settings->get( 'resize_smart' ) === 'enabled' ) {
|
||
|
$gravity = Optml_Resize::GRAVITY_SMART;
|
||
|
}
|
||
|
|
||
|
if ( $width === 0 ) {
|
||
|
$width = 'auto';
|
||
|
}
|
||
|
|
||
|
if ( $height === 0 ) {
|
||
|
$height = 'auto';
|
||
|
}
|
||
|
|
||
|
// Use the proper replacement for the image size.
|
||
|
$replacement = '/w:' . $width . '/h:' . $height;
|
||
|
|
||
|
if ( $crop ) {
|
||
|
$replacement .= '/g:' . $gravity . '/rt:fill';
|
||
|
}
|
||
|
|
||
|
$replacement .= '/q:';
|
||
|
|
||
|
if ( $args['dam'] ) {
|
||
|
$replacement = self::URL_DAM_FLAG . $replacement;
|
||
|
}
|
||
|
|
||
|
return preg_replace( '/\/w:(.*)\/h:(.*)\/q:/', $replacement, $subject );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Elementor checks if the file exists before requesting a specific image size.
|
||
|
*
|
||
|
* Needed because otherwise there won't be any width/height on the `img` tags, breaking lazyload.
|
||
|
*
|
||
|
* Also needed because some
|
||
|
*
|
||
|
* @param string $file The file path.
|
||
|
* @param int $id The attachment ID.
|
||
|
*
|
||
|
* @return bool|string
|
||
|
*/
|
||
|
public function alter_attached_file_response( $file, $id ) {
|
||
|
if ( ! $this->is_dam_imported_image( $id ) ) {
|
||
|
return $file;
|
||
|
}
|
||
|
|
||
|
$metadata = wp_get_attachment_metadata( $id );
|
||
|
|
||
|
if ( isset( $metadata['file'] ) ) {
|
||
|
$uploads = wp_get_upload_dir();
|
||
|
|
||
|
return $uploads['basedir'] . '/' . $metadata['file'];
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Alter the srcSet for DAM images.
|
||
|
*
|
||
|
* @param array $sources Initial source array.
|
||
|
* @param array $size_array Requested size.
|
||
|
* @param string $image_src Image source URL.
|
||
|
* @param array $image_meta Image meta data.
|
||
|
* @param int $attachment_id Image attachment ID.
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
public function disable_dam_images_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id ) {
|
||
|
if ( ! $this->is_dam_imported_image( $attachment_id ) ) {
|
||
|
return $sources;
|
||
|
}
|
||
|
|
||
|
return [];
|
||
|
}
|
||
|
}
|