Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion php/class-plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Cloudinary\Delivery\Lazy_Load;
use Cloudinary\Delivery\Responsive_Breakpoints;
use Cloudinary\Assets as CLD_Assets;
use Cloudinary\Integrations\Elementor;
use Cloudinary\Integrations\WPML;
use Cloudinary\Media\Gallery;
use Cloudinary\Sync\Storage;
Expand All @@ -31,7 +32,7 @@ final class Plugin {
*
* @since 0.1
*
* @var Admin|CLD_Assets|Connect|Dashboard|Deactivation|Delivery|Extensions|Gallery|Lazy_Load|Media|Meta_Box|Relate|Report|Responsive_Breakpoints|REST_API|State|Storage|SVG|Sync|URL[]|WPML|null
* @var Admin|CLD_Assets|Connect|Dashboard|Deactivation|Delivery|Extensions|Gallery|Lazy_Load|Media|Meta_Box|Relate|Report|Responsive_Breakpoints|REST_API|State|Storage|SVG|Sync|URL[]|WPML|Elementor|null
*/
public $components;
/**
Expand Down Expand Up @@ -136,6 +137,7 @@ public function plugins_loaded() {
$this->components['metabox'] = new Meta_Box( $this );
$this->components['url'] = new URL( $this );
$this->components['wpml'] = new WPML( $this );
$this->components['elementor'] = new Elementor( $this );
$this->components['special_offer'] = new Special_Offer( $this );
}

Expand Down
130 changes: 130 additions & 0 deletions php/integrations/class-elementor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php
/**
* Elementor integration class for the Cloudinary plugin.
*
* @package Cloudinary
*/

namespace Cloudinary\Integrations;

use Elementor\Core\Files\CSS\Post;
use Elementor\Element_Base;
use Elementor\Plugin;

/**
* Class Elementor
*/
class Elementor extends Integrations {

/**
* List of Elementor background image settings keys, along with their device and CSS suffix.
*
* @var array
*/
const ELEMENTOR_BACKGROUND_IMAGES = array(
'_background_image' => array(
'device' => 'desktop',
'suffix' => '',
),
'_background_hover_image' => array(
'device' => 'desktop',
'suffix' => ':hover',
),
'_background_image_tablet' => array(
'device' => 'tablet',
'suffix' => '',
),
'_background_hover_image_tablet' => array(
'device' => 'tablet',
'suffix' => ':hover',
),
'_background_image_mobile' => array(
'device' => 'mobile',
'suffix' => '',
),
'_background_hover_image_mobile' => array(
'device' => 'mobile',
'suffix' => ':hover',
),
);

/**
* Check if the integration can be enabled.
*
* @return bool
*/
public function can_enable() {
return class_exists( 'Elementor\Plugin' );
}

/**
* Register hooks for the integration.
*
* @return void
*/
public function register_hooks() {
add_action( 'elementor/element/parse_css', array( $this, 'replace_background_images_in_css' ), 10, 2 );
add_action( 'cloudinary_flush_cache', array( $this, 'clear_elementor_css_cache' ) );
}

/**
* Replace all background images URLs with Cloudinary URLs, within the generated Elementor CSS file.
*
* @param Post $post_css The post CSS object.
* @param Element_Base $element The Elementor element.
* @return void
*/
public function replace_background_images_in_css( $post_css, $element ) {
$settings = $element->get_settings_for_display();
$media = $this->plugin->get_component( 'media' );
$delivery = $this->plugin->get_component( 'delivery' );

if ( ! $media || ! $delivery ) {
return;
}

foreach ( self::ELEMENTOR_BACKGROUND_IMAGES as $background_key => $background_data ) {
// We need to have the ID from the image to proceed.
if ( ! isset( $settings[ $background_key ]['id'] ) ) {
continue;
}

$media_id = $settings[ $background_key ]['id'];
$media_size = isset( $settings[ $background_key ]['size'] ) ? $settings[ $background_key ]['size'] : array();

// Skip if the media is not deliverable via Cloudinary.
if ( ! $delivery->is_deliverable( $media_id ) ) {
continue;
}

// Generate the Cloudinary URL.
$cloudinary_url = $media->cloudinary_url( $media_id, $media_size );

// Build the CSS selector and rule.
$css_selector = $post_css->get_element_unique_selector( $element ) . $background_data['suffix'];
$css_rule = array( 'background-image' => "url('$cloudinary_url')" );

// Retrieve the specific media query rule for non-desktop devices.
$media_query = null;
if ( 'desktop' !== $background_data['device'] ) {
$media_query = array( 'max' => $background_data['device'] );
}

// Override the CSS rule in Elementor.
$post_css->get_stylesheet()->add_rules( $css_selector, $css_rule, $media_query );
}
}

/**
* Clear Elementor CSS cache.
* This is called when Cloudinary cache is flushed, so that any change in media URLs is reflected in Elementor CSS files.
*
* @return void
*/
public function clear_elementor_css_cache() {
if ( class_exists( 'Elementor\Plugin' ) ) {
$elementor = Plugin::instance();
$elementor->files_manager->clear_cache();
}
}
}