Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Fix block editor + patterns #1005

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
2 changes: 1 addition & 1 deletion js/block-editor.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-plugins'), 'version' => '8f1f83558398bdc930fd');
<?php return array('dependencies' => array('react', 'wp-api-fetch', 'wp-components', 'wp-data', 'wp-i18n'), 'version' => 'c8e1eb2b75a7df74cf6a');
2 changes: 1 addition & 1 deletion js/block-editor.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions php/class-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -1265,6 +1265,30 @@ public function register_settings( $pages ) {
return $pages;
}

/**
* Checks if the URL is an asset.
*
* @param string $url The URL to check.
*
* @return bool
*/
public function is_asset( $url ) {
global $wpdb;

// Bail early if it's not an URL.
if ( empty( parse_url( $url, PHP_URL_HOST ) ) ) {
return false;
}

$url = Utils::clean_url( $url );

$wpdb->cld_table = Utils::get_relationship_table();
$prepare = $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->cld_table WHERE sized_url = %s AND sync_type = 'asset';", $url );
$result = $wpdb->get_var( $prepare ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.NotPrepared

return (bool) $result;
}

/**
* Get the plugins table structure.
*
Expand Down
126 changes: 125 additions & 1 deletion php/class-delivery.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ public function init() {
add_action( 'before_delete_post', array( $this, 'delete_size_relationship' ) );
add_action( 'delete_attachment', array( $this, 'delete_size_relationship' ) );
add_action( 'cloudinary_register_sync_types', array( $this, 'register_sync_type' ), 30 );
add_action( 'rest_request_before_callbacks', array( $this, 'maybe_unset_attributes' ), 10, 3 );
add_action(
'the_post',
function ( $post ) {
Expand All @@ -158,6 +159,71 @@ function ( $post ) {
}
}

/**
* Determine if attributes should be added to image tags.
*
* @param WP_REST_Response $response The response object.
* @param WP_REST_Server $handler The request handler.
* @param WP_REST_Request|null $request The request object, if available.
*
* @return void
*/
public function maybe_unset_attributes( $response, $handler, $request ) {
$route = $request->get_route();

if (
(bool) $request->get_header( 'x-cld-fetch-from-editor' )
|| (
false !== strpos( $route, 'wp/v2/media' )
&& 'edit' === $request->get_param( 'context' )
)
) {
// This has a priority of 10 so can be overridden by other filters.
add_filter(
'cloudinary_unset_attributes',
'__return_true'
);

add_filter(
'cloudinary_apply_breakpoints',
'__return_false'
);

add_filter(
'cloudinary_parse_element',
static function ( $tag_element ) {
$tag_element['breakpoints'] = false;
return $tag_element;
}
);

add_filter(
'cloudinary_skip_responsive_breakpoints',
'__return_true'
);

if ( false === strpos( $route, 'wp/v2/blocks/' ) ) {
add_filter(
'cloudinary_tag_skip_classes',
function ( $skip, $tag_element ) {
// Bail on additional assets.
return $this->plugin->get_component( 'assets' )->is_asset( $tag_element['atts']['src'] );
},
10,
2
);

add_filter(
'cloudinary_parse_element',
function ( $element ) {
unset( $element['atts']['class'] );
return $element;
}
);
}
}
}

/**
* Maybe filter out Cloudinary URLs in post meta.
*
Expand Down Expand Up @@ -816,6 +882,7 @@ public function process_featured_image( $html, $post_id, $attachment_id ) {
if ( empty( $html ) ) {
return $html; // Ignore empty tags.
}

$tags = $this->get_media_tags( $html, 'img' );
$tags = array_map( array( $this, 'parse_element' ), $tags );
$tags = array_filter( $tags );
Expand Down Expand Up @@ -1109,8 +1176,36 @@ protected function standardize_tag( $tag_element ) {
if ( isset( $tag_element['format'] ) ) {
$tag_element['atts']['data-format'] = $tag_element['format'];
}

/**
* Maybe skip the classes for th tag element.
*
* @hook cloudinary_tag_skip_classes
* @since 3.2.4
* @default {false}
*
* @param $skip {bool} True to unset attributes.
* @param $tag_element {array} The tag element.
*
* @retun {bool}
*/
$skip_classes = apply_filters( 'cloudinary_tag_skip_classes', false, $tag_element );

// Add wp-{media-type}-{id} class name.
if ( empty( $tag_element['atts']['class'] ) || ! in_array( 'wp-' . $tag_element['type'] . '-' . $tag_element['id'], $tag_element['atts']['class'], true ) ) {
if (
! $skip_classes
&&
(
empty( $tag_element['atts']['class'] )
||
(
is_array( $tag_element['atts']['class'] )
&&
! in_array( 'wp-' . $tag_element['type'] . '-' . $tag_element['id'], $tag_element['atts']['class'], true )
)
)
) {
$tag_element['atts']['class'] = ! empty( $tag_element['atts']['class'] ) ? $tag_element['atts']['class'] : array();
$tag_element['atts']['class'][] = 'wp-' . $tag_element['type'] . '-' . $tag_element['id'];
}

Expand Down Expand Up @@ -1171,6 +1266,32 @@ protected function standardize_tag( $tag_element ) {
$att = implode( ' ', $parts );
}

/**
* Unset the attributes to avoid block errors in the admin.
*
* @hook cloudinary_unset_attributes
* @since 3.2.4
* @default {false}
*
* @param $unset {bool} True to unset attributes.
* @param $tag_element {array} The tag element.
*
* @retun {bool}
*/
if ( apply_filters( 'cloudinary_unset_attributes', false, $tag_element ) ) {
unset(
$tag_element['atts']['data-public-id'],
$tag_element['atts']['data-format'],
$tag_element['atts']['width'],
$tag_element['atts']['height'],
$tag_element['atts']['data-crop'],
$tag_element['atts']['srcset'],
$tag_element['atts']['data-responsive']
);

return $tag_element;
}

// Add transformations attribute.
$transformations = $this->media->get_transformations_from_string( $tag_element['atts']['src'] );
if ( false !== $this->media->get_crop_from_transformation( $transformations ) ) {
Expand Down Expand Up @@ -1207,6 +1328,7 @@ protected function standardize_tag( $tag_element ) {
* @return {string}
*/
$permalink = apply_filters( 'cloudinary_edit_asset_permalink', add_query_arg( 'asset', $tag_element['id'], $base_url ) );

$tag_element['atts']['data-permalink'] = $permalink;
}

Expand Down Expand Up @@ -1423,6 +1545,7 @@ public function parse_element( $element ) {
}
}
}

if ( ! empty( $attributes['class'] ) ) {
if ( preg_match( '/wp-post-(\d+)+/', $attributes['class'], $match ) ) {
$tag_element['context'] = (int) $match[1];
Expand All @@ -1443,6 +1566,7 @@ public function parse_element( $element ) {
$attributes['class'][] = 'cld-overwrite';
$tag_element['overwrite_transformations'] = true;
}

$inline_transformations = $this->get_transformations_maybe( $raw_url );
if ( $inline_transformations ) {
// Ensure that we don't get duplicated transformations.
Expand Down
16 changes: 16 additions & 0 deletions php/delivery/class-responsive-breakpoints.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,22 @@ public function add_features( $tag_element ) {
return $tag_element;
}

/**
* Do not add the responsive breakpoint features.
*
* @hook cloudinary_skip_responsive_breakpoints
* @since 3.2.4
* @default {false}
*
* @param $skip_features {bool} True to skip adding in the features.
* @param $tag_element {array} The tag element.
*
* @return {bool}
*/
if ( apply_filters( 'cloudinary_skip_responsive_breakpoints', false, $tag_element ) ) {
return $tag_element;
}

// Bypass file formats that shouldn't have Responsive Images.
if (
in_array(
Expand Down
41 changes: 39 additions & 2 deletions src/js/blocks.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,55 @@
/**
* WordPress dependencies
*/
import apiFetch from '@wordpress/api-fetch';

/**
* Internal dependencies
*/
import Video from './components/video';
import Featured from './components/featured-image';
import Terms from './components/terms-inspector';
import MaybeReloadAfterSave from './components/maybe-reload-after-save';

// jQuery, because reasons.
window.$ = window.jQuery;

// Register middleware for @wordpress/api-fetch to indicate the fetch is coming from the editor.
// Taken from https://github.com/Automattic/jetpack/blob/trunk/projects/plugins/jetpack/extensions/editor.js.
apiFetch.use( ( options, next ) => {
// Skip explicit cors requests.
if ( options.mode === 'cors' ) {
return next( options );
}

// If a URL is set, skip if it's not same-origin.
// @see https://html.spec.whatwg.org/multipage/origin.html#same-origin
if ( options.url ) {
try {
const url = new URL( options.url, location.href );
if (
url.protocol !== location.protocol ||
url.hostname !== location.hostname ||
url.port !== location.port
) {
return next( options );
}
} catch {
// Huh? Skip it.
return next( options );
}
}

// Ok, add header.
if ( ! options.headers ) {
options.headers = {};
}
options.headers[ 'x-cld-fetch-from-editor' ] = 'true';
return next( options );
} );

// Global Constants
export const cloudinaryBlocks = {
Video,
Featured,
Terms,
MaybeReloadAfterSave,
};
25 changes: 0 additions & 25 deletions src/js/components/maybe-reload-after-save.js

This file was deleted.