Giter Club home page Giter Club logo

asset-manager-framework's Introduction

Asset Manager Framework

This WordPress plugin provides a framework for replacing the contents of the standard WordPress media library with assets from an external provider such as a DAM, another WordPress website, or a central site within a Multisite installation.

It handles the necessary integration with WordPress (Ajax endpoints and Backbone components) leaving you to focus on just the server-side API connection to your DAM.

The intention is that the media manager, the block editor, the classic editor, the REST API, XML-RPC, and anything that calls wp.media() should "just work" and not need to implement changes in order to support a media library that is powered by an external provider.

Installation

Install with Composer:

composer require humanmade/asset-manager-framework

Status

Current status: Alpha. Generally very functional but several features still in development.

The following features work as expected:

  • Block editor: All media features
  • Classic editor: All media features
  • Media screen: All features
  • Widgets: All media widgets
  • Customizer:
    • Background Image
    • Logo (functions if you skip cropping)
    • Site Icon (unable to skip cropping of large images)
  • REST API media endpoints
  • XML-RPC requests for media
  • Any code that calls wp.media() to open the media manager and work with the selected attachments

The following custom field libraries have been tested and are compatible out of the box:

  • CMB2
  • Advanced Custom Fields (ACF)
  • Fieldmanager

The following third party plugins are supported via an included integration layer:

  • MultilingualPress 3

The following new features are planned but not yet implemented:

The following features will not be supported:

  • Side-loading media from an external media provider. The intention of this framework is that media files remain remotely hosted.
  • Built-in handling of authentication required to communicate with your external media provider. This responsibility lies within your implementation. Consider using the Keyring plugin if an OAuth connection is required.
  • Built-in support for any given media provider (such as AEM Assets, Aprimo, Bynder, or ResourceSpace). This is a framework built to be extended in order to connect it to a media provider.

Known Implementations

  • AMF WordPress for using another WordPress site, or another site on a Multisite network, as source for your media library.
  • AMF Unsplash for using Unsplash as a source.

Implementation

There are two main aspects to the plugin.

  1. Allow the media manager grid to display external items which are not existing attachments.
  2. Subsequently create a local attachment for an external item when it's selected for use.

The design decision behind this is that allowing for external items to be browsed in the media manager is quite straight forward, but unless each item is associated with a local attachment then most of the rest of WordPress breaks when you go to use an item. Previous attempts to do this have involved lying about attachment IDs, or switching to another site on a Multisite network to provide a media item. Neither approach is desirable because such lies need to be maintained and eventually you run into a situation where your lies become unravelled.

Asset Manager Framework instead allows external media items to be browsed in the media library grid, but as soon as an item is selected for use (eg. to be inserted into a post or used as a featured image), an attachment is created for the media item, and this gets returned by the media manager.

The actual media file does not get sideloaded into WordPress - it intentionally remains at its external URL. The correct external URL gets referred to as necessary, while a local object attachment is maintained that can be referenced and queried within WordPress.

Integration

There are two steps needed to integrate a media provider using the Asset Manager Framework:

  1. Create a provider which extends the AssetManagerFramework\Provider class and implements its get_id(), get_name() and request() methods to fetch results from your external media provider based on query arguments from the media manager.
  2. Hook into the amf/register_providers action to register your provider for use.

Full documentation is coming soon, but for now here's an example of a provider which supplies images from placekitten.com:

use AssetManagerFramework\{
	ProviderRegistry
	Provider,
	MediaList,
	MediaResponse,
	Image
};

class KittenProvider extends Provider {

	public function get_id() {
		return 'kittens';
	}

	public function get_name() {
		return __( 'Place Kitten' );
	}

	protected function request( array $args ) : MediaResponse {
		$kittens = [
			500 => 'Boop',
			600 => 'Fuzzy',
			700 => 'Paws',
		];
		$items = [];

		foreach ( $kittens as $id => $title ) {
			$item = new Image( $id, 'image/jpeg' );
			$item->set_url( sprintf(
				'https://placekitten.com/%1$d/%1$d',
				$id
			) );
			$item->set_title( $title );
			$item->set_width( $id );
			$item->set_height( $id );

			$items[] = $item;
		}

		return new MediaResponse(
			new MediaList( ...$items ),
			count( $kittens ), // Total number of available results.
			count( $kittens )  // Number of items requested per page.
		);
	}

}

add_action( 'amf/register_providers', function ( ProviderRegistry $provider_registry ) {
	$provider_registry->register( new KittenProvider() );
} );

Try it and your media library will be much improved:

Kittens

The MediaResponse object takes a MediaList along with the total number of available items and the number of items requested per page. This is to ensure pagination in the media library (introduced in WordPress 5.8) works.

You also have access to provider instances during registration via the amf/provider filter, so you could use it to decorate providers:

add_filter( 'amf/provider', function ( Provider $provider ) {
	if ( $provider->get_id() !== 'kittens' ) {
		return $provider;
	}

	return new DecoratingProvider( $provider );
} );

This is useful, for example, when you are using a third-party provider implementation and want to change certain behavior.

Local Media

Local media is supported by default and can be used side by side with any additional media providers but can also be controlled by using one the following methods:

  1. Defining the AMF_ALLOW_LOCAL_MEDIA constant as a boolean
  2. Use the amf/allow_local_media filter to return a boolean
  3. Use the amf/local_provider/name filter to change the Local Media label.

The filter will take precedence over the constant.

License: GPLv2

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

asset-manager-framework's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

asset-manager-framework's Issues

Responsive image srcsets on images within post content

When an image is used within post content, the responsive image srcset attribute does not function as expected.

The reason for this is that AMF does not currently populate the sizes array in attachment metadata, and even if it does this will not work with WordPress core's default srcset generation. We'll likely need to handle srcset generation in AMF.

Set the featured image for a non-image media item automatically

When a non-image media item is used, its featured image should be set when one is available and supplied by the provider. The featured image for video and audio powers the poster image when that media item gets used.

This affects video and audio files.

Gallery Support

AMF doesn't currently support galleries officially ( v0.13 )

Compatibility Issue with WooCommerce Variable Products and MultilingualPress

We are getting an issue when creating a Variable Product with WooCommerce and then attempting to translate that error via MultilingualPress.

Steps to recreate:

  • On a multisite install with at least two sites
  • Ensure WooCommerce is installed and network active
  • Ensure MultilingualPress is installed and network active
    • Ensure MultilingualPress has been configured to work with WooCommerce in the settings screen, and the Product post type is translatable
  • Create a new Woo product, give it a test title and some content
  • In the Product data meta box, set the project type to Variable product
  • In the attributes tab Add an attribute, something like Attribute 1 with the values 1 | 2, be sure to save the attributes when you have finished
  • In the Variations tab generate the variations from the attributes
  • Publish the product
  • Scroll down to the Translation for... that relates to the other site on your network
  • Click the Create a new Product, and use it as translation in... radio button
  • Click the post publish button to trigger the translation
  • The following error will occur:
Fatal error: Uncaught Error: Return value of AssetManagerFramework\replace_attached_file() must be of the type string, bool returned
in /usr/src/app/vendor/humanmade/asset-manager-framework/inc/namespace.php on line 217

Call stack:

AssetManagerFramework\replace_attached_file()
wp-includes/class-wp-hook.php:307
WP_Hook::apply_filters()
wp-includes/plugin.php:189
apply_filters()
wp-includes/post.php:744
get_attached_file()
content/plugins/multilingualpress/src/modules/WooCommerce/TranslationUi/Product/MetaboxAction.php:1064
Inpsyde\M\M\W\T\P\MetaboxAction::getSourceProductVariationAttachmentData()
content/plugins/multilingualpress/src/modules/WooCommerce/TranslationUi/Product/MetaboxAction.php:172
Inpsyde\M\M\W\T\P\MetaboxAction::doSaveOperation()
content/plugins/multilingualpress/src/modules/WooCommerce/TranslationUi/Product/MetaboxAction.php:131
Inpsyde\M\M\W\T\P\MetaboxAction::save()
content/plugins/multilingualpress/src/modules/WooCommerce/ProductMetaboxesBehaviorActivator.php:140
Inpsyde\M\M\W\ProductMetaboxesBehaviorActivator::saveMetaboxes()
wp-includes/class-wp-hook.php:309
WP_Hook::apply_filters()
wp-includes/class-wp-hook.php:331
WP_Hook::do_action()
wp-includes/plugin.php:474
do_action()
content/plugins/multilingualpress/src/multilingualpress/TranslationUi/Post/MetaboxAction.php:470
Inpsyde\M\T\P\MetaboxAction::savePost()
content/plugins/multilingualpress/src/multilingualpress/TranslationUi/Post/MetaboxAction.php:279
Inpsyde\M\T\P\MetaboxAction::doSaveOperation()
content/plugins/multilingualpress/src/multilingualpress/TranslationUi/Post/MetaboxAction.php:114
Inpsyde\M\T\P\MetaboxAction::save()
content/plugins/multilingualpress/src/framework/Admin/Metabox/MetaboxUpdater.php:127
Inpsyde\M\F\A\M\MetaboxUpdater::saveMetabox()
content/plugins/multilingualpress/src/framework/Admin/Metabox/Metaboxes.php:455
Inpsyde\M\F\A\M\Metaboxes::saveMetaBoxes()
content/plugins/multilingualpress/src/framework/Admin/Metabox/Metaboxes.php:420
Inpsyde\M\F\A\M\Metaboxes::onPostSave()
content/plugins/multilingualpress/src/framework/Admin/Metabox/Metaboxes.php:245
Inpsyde\M\F\A\M\Metaboxes::Inpsyde\M\F\A\M\{closure}()
wp-includes/class-wp-hook.php:309
WP_Hook::apply_filters()
wp-includes/class-wp-hook.php:331
WP_Hook::do_action()
wp-includes/plugin.php:474
do_action()
wp-includes/post.php:4698
wp_insert_post()
wp-includes/post.php:4789
wp_update_post()
wp-admin/includes/post.php:426
edit_post()
wp-admin/post.php:227

Screenshot 2022-05-18 at 07 12 31

Mitigation

If you override the default image that is added to each product variation, and attempt to translate the product again, the above error does not occur.

Undeclared Node 16 dependency

Running npm run build on Node 18 gives a Error: error:0308010C:digital envelope routines::unsupported error that goes away when dropping down to Node 16, but it's not documented that Node 16 is required.

I propose it be added to the engines section of package.json

Currently selected featured image gets duplicated in amf generated media library

I encountered an issue while trying to replace a featured image in WordPress. When I navigate to the media library generated by AMF, and select a new image, the current featured image gets added/duplicated to the AMF media library.

Steps to Reproduce:

  1. Add a featured image to a post (it could be from the local library or the AMF-generated library).
  2. Click on the "Replace" Featured Image button.
  3. Navigate to the AMF-generated media library.
  4. Select a new image from the library.

I am assuming this is related to Wordpress as I can see js events are generating the li item(currently selected featured image item) to the library are written in Wordpress.

Is there any way I can fix this?

I have tried resetting the current selection when the media dialog is opened, but it doesn't seem to work

wp.media.featuredImage.frame().on('open', function() {
      const frame = wp.media.featuredImage.frame();
      const selection = frame.state().get('selection');
      selection.reset();
    });

Requesting a missing image size can result in a broken / missing file

In WP core there are instances where an implicit image size such as post-thumbnail is requested or referenced such as when setting a featured image. If the AMF provider has not generated appropriate sizes metadata for the current site, and the provider does not support dynamic image sizing then AMF should fall back to the original.

Type error in fix_media_url

I am getting the following error anytime I open the media library or when I attempt to edit/replace an image in a post: Uncaught TypeError: Argument 1 passed to AssetManagerFramework\fix_media_url() must be of the type string, bool given

I am using AMF 0.12.0, AMF WordPress 0.2.1 and Altis Media dev-master.

Steps to reproduce

  1. Open the media library. The loading indicator permanently rotates.

or

  1. Select an image within a post
  2. Click Replace
  3. The loading indicator permanently rotates

However, repeating that process will load the images.
See screengrab: https://www.dropbox.com/s/ocxlqqtcojzd9gd/tachyon-provider-error.mov?raw=1

When I dug into this a bit, it seems like the first time the $size['url'] is requested to pass into fix_media_url, it's coming back with a boolean (false), which fatals. Subsequent requests return the sizes.

Full stack trace is below:

php_1              | [17-Jun-2021 21:18:09 UTC] PHP Fatal error:  Uncaught TypeError: Argument 1 passed to AssetManagerFramework\fix_media_url() must be of the type string, bool given, called in /usr/src/app/extra-packages/asset-manager-framework/inc/namespace.php on line 318 and defined in /usr/src/app/extra-packages/asset-manager-framework/inc/namespace.php:305
php_1              | Stack trace:
php_1              | #0 /usr/src/app/extra-packages/asset-manager-framework/inc/namespace.php(318): AssetManagerFramework\fix_media_url(false, Object(WP_Post))
php_1              | #1 /usr/src/app/wordpress/wp-includes/class-wp-hook.php(294): AssetManagerFramework\fix_media_size_urls(Array, Object(WP_Post))
php_1              | #2 /usr/src/app/wordpress/wp-includes/plugin.php(212): WP_Hook->apply_filters(Array, Array)
php_1              | #3 /usr/src/app/wordpress/wp-includes/media.php(4141): apply_filters('wp_prepare_atta...', Array, Object(WP_Post), Array)
php_1              | #4 [internal function]: wp_prepare_attachment_for_js(Object(WP_Post))
php_1              | #5 /usr/src/app/wordpress/wp-admin/includes/ajax-actions.php(2993): array_map('wp_prepare_atta...', Array)
php_1              | #6 /usr/src/app/extra-packages/asset-manager-framework/inc/LocalProvider.php(24): wp_ajax_query_attachments()
php_1              | #7 /usr/src/app/extra-packages/asset-manager-framework/inc/Provider.php(138): AssetManagerFramework\LocalProvider->request(Array)
php_1              | #8 /usr/src/app/extra-packages/asset-manager-framework/inc/namespace.php(268): AssetManagerFramework\Provider->request_items(Array)
php_1              | #9 /usr/src/app/wordpress/wp-includes/class-wp-hook.php(292): AssetManagerFramework\ajax_query_attachments('')
php_1              | #10 /usr/src/app/wordpress/wp-includes/class-wp-hook.php(316): WP_Hook->apply_filters('', Array)
php_1              | #11 /usr/src/app/wordpress/wp-includes/plugin.php(484): WP_Hook->do_action(Array)
php_1              | #12 /usr/src/app/wordpress/wp-admin/admin-ajax.php(187): do_action('wp_ajax_query-a...')
php_1              | #13 {main}
php_1              |   thrown in /usr/src/app/extra-packages/asset-manager-framework/inc/namespace.php on line 305

Paginating a large collection of images MediaList?

Hi I'm implementing AMF to get media from an API that has a large collection with thousands of images. I don't want to populate all the items in the returned MediaList but would rather use pagination. Is there a way with the current MediaList class to paginate results?

Make this a Composer-only framework

Let's get rid of the hardcoded requires in this library and switch to Composer autoloading with PSR-4. Anything that consumes this library needs to do so via Composer because the year is 2020 after all.

A standalone provider can still bundle AMF in its WordPress plugin, but at the development level it needs to pull it in via Composer.

Make the provider instance filterable

Currently, there is a filter for the provider class to use, and then AMF will take care of instantiating.

If AMF provided a filter for the provider instance, this would allow for both decorating providers (see example below) and constructor injection in general.

This filter would ideally replace the current one, otherwise the provider constructor cannot have mandatory arguments.


Current code:

function get_provider() : Provider {
	static $provider = null;

	if ( $provider ) {
		return $provider;
	}

	$provider_class = apply_filters( 'amf/provider_class', __NAMESPACE__ . '\BlankProvider' );
	$provider = new $provider_class();

	return $provider;
}

Proposed code:

function get_provider() : Provider {
	static $provider = null;

	if ( $provider ) {
		return $provider;
	}

-	$provider_class = apply_filters( 'amf/provider_class', __NAMESPACE__ . '\BlankProvider' );
-	$provider = new $provider_class();
+	$provider = apply_filters( 'amf/provider', new BlankProvider() );

	return $provider;
}

Simple usage:

add_filter( 'amf/provider', function () {
    return new CustomProvider( 'some', 'stuff' );
} );

Decorator usage:

add_filter( 'amf/provider', function ( Provider $provider ) {
    return new DecoratingProvider( $provider, 'some', 'stuff' );
} );

The DecoratingProvider could then store the current $provider instance, and delegate to it as necessary, or perform custom logic.

Allow providers to indicate supported mime types / media types

In some contexts the media library can be opened with a media / mime type filter. Not every provider will be able to support every media type so we should filter the list of available providers depending on media type.

Proposed behaviour:

  • Providers are assumed to support any media type by default
  • Providers can override a method to return an array of supported mime types
  • Provider should not be shown in list if it cannot provide the requested media types

Question: Should we support wild card or sub mime types like WP (sort of) does e.g. image/*? Would help.

Future risks for this library

The main reason AMF can work as intended is that the media library in WordPress gets its attachments populated via an admin-ajax.php request which uses a response format which is not a representation of WP_Post objects (see the wp_prepare_attachment_for_js() function). This allows AMF to override what gets returned and displayed in the media library without an attachment having to exist for each media file.

If this were to change in the future then AMF would cease to work. With that in mind I've collected some risks and potential mitigations.

The admin-ajax.php attachment requests in the media manager get replaced

If the media modal or media grid get rebuilt using the REST API (or GraphQL) instead of the existing admin-ajax.php endpoint to fetch attachments then a real attachment would need to exist for each media item, because that's the response format that's expected.

To mitigate this it might be possible to override requests to the REST API for media when browsing the media manager in order to use a different endpoint which returns placeholder IDs for each "attachment". Not ideal, this sends us down the route of lying about attachment IDs which is what this library intended to get us away from.

The Backbone JS for the media manager gets replaced

If the media modal or media grid get rebuilt in React (but continue to use the existing Ajax endpoint for fetching attachments) this would break the extend_toolbar() function which overrides the behaviour of the "Insert" or "Select" buttons in the Backbone view that triggers the creation of an attachment at the point where a media file gets used.

To mitigate this we'd need to ensure AMF can still hook into the point where a media file gets "used" so it can be intercepted and an attachment created just as it does now.

Both of the above

A double hit, and to be honest if one happens it's likely the other will too.

Various degrees of read-only media

From the readme file:

Various degrees of read-only media (to disable uploading, editing, cropping, or deletion)

The idea is that a provider declares what features it supports (via methods on its Provider class) and then AMF takes care of either disabling the functionality in WordPress or communicating the functionality to the provider. This allows, for example, a provider to simply declare that users cannot upload files and AMF takes care of everything.

One potential problem is that WordPress core doesn't use granular capabilities for media, so any changes that need to be made via adjustments to user capabilities might hit a problem. See https://core.trac.wordpress.org/ticket/41332

File uploads

If file uploads are supported by the provider:

  • Need a means for WordPress to pass an uploaded file onto the provider, preferably without it being put into place in the uploads directory
  • Need to consider file uploads via:
    • async-upload.php
    • REST API wp/v2/media endpoint
    • Direct call to wp_handle_upload()
  • Presumably the provider also needs to support editing files (see section below) in order to provide the title, description, caption, etc.

If file uploads are not supported by the provider:

  • Remove the "Upload" buttons shown in various places in WordPress
  • Remove the "Upload files" tab in the media modal, note that this causes a blank screen when a user first opens the media modal and this tab is not visible, needs investigating
  • Remove the "Select Files" button shown below the "No items found" message when there are no results
  • Disable drag and drop upload handler, best achieved by returning an error from the wp_handle_upload_prefilter filter

Editing file data

This means editing of the metadata associated with a file, such as its title, description, and caption. For modifying the actual file via image cropping, see the image cropping section below.

There are three possibilities:

  1. The provider supports editing file data and changes made on the attachment editing screen in WordPress should be pushed to the provider
  • Need a means for changes made to an attachment to be passed onto the provider
  1. The provider does not support editing file data and changes made on the attachment editing screen in WordPress only take effect on the local site
  • No changes necessary, this is the default and current behaviour
  1. The provider does not support editing file data and it should not be possible to make changes locally by editing the attachment, for example for compliance reasons
  • Can be enforced at the user capability level

Image cropping

Currently if an image is cropped WordPress makes a local copy of the file, thus allowing the remote provider to be bypassed.

If the provider supports image cropping:

  • Need a means of passing the cropping coordinates and dimensions on to the provider and potentially being sent back a new URL for the file

If the provider does not support image cropping (probably most providers will not):

  • Need to disable image cropping functionality in WordPress
    • Edit Image link when a file is selected in the media modal
    • Edit Image button in the media grid modal
    • Inline cropping in the Image block type
    • Site Logo
    • Site Icon
    • wp_ajax_crop-image action
    • wp.media() when one of the states is a cropper (example)
    • Header image controls with Select and crop

Deleting files

There are three possibilities:

  1. The provider supports deleting files, and attachment deletion should be pushed to the provider
  • This is potentially a very destructive action and it might be that we simply don't want to support this
  1. The provider does not support deleting files, and attachment deletions in WordPress only take effect on the local site
  • No changes necessary, this is the default and current behaviour
  1. The provider does not support deleting files, and it should not be possible to delete attachments locally
  • Can be enforced at the user capability level

"Insert from URL"

The Image, Audio, and Video block types support using a URL instead of a file from the media library. It's preferable to disable this capability when a DAM in use, but it might not be strictly related to a provider. There could be a use case for retaining or disabling this regardless of whether file uploads are supported.

Maybe implement via a separate filter instead of a declaration by the provider.

Empty image sizes file values

In our implementation when writing a provider for AMF, on local environments where production images are missing, I'm seeing a number of media.php warnings strpos(): Empty needle.

When debugging it appears that for these images, both $dirname and $file are empty.

I added this workaround, to repopulate the file value with the one from $image_meta:

	add_filter( 'wp_calculate_image_srcset_meta', __NAMESPACE__ . '\\insert_missing_meta_sizes_values', 10, 1 );
[..]

/**
 * Some images that are not locally available, have empty values causing warnings.
 *
 * @param array $image_meta
 *
 * @return array Updated image meta sizes array with empty file values replaced.
 */
function insert_missing_meta_sizes_values( array $image_meta ) : array {
	foreach ( $image_meta['sizes'] as $key => $size ) {
		if ( empty( $size['file'] ) ) {
			$image_meta['sizes'][ $key ]['file'] = $image_meta['file'];
		}
	}
	return $image_meta;
}

When I have AMF/Provider disabled, I don't see these warnings. It could be an assumption on AMF's part or something else in our codebase, but wanted to report this in case this helps solving the issue should it be AMF related.

Edit Gallery Provider dropdown

In 0.13 when editing a gallery, a broken toolbar containing a dropdown for listing providers appears. It's unclear if this is intentional or a bug, or what it's intended to do.

Investigate using a field other than post_name for the GUID

When storing and querying for existing attachments, the post_name field it used to store the GUID for the media item, which typically comes directly from the service provider.

The benefit is that querying by post_name in WordPress is a known process and runs queries that hit an index, etc.

The disadvantage is that this gets used as the permalink for a media attachment. It may not be desirable to have a GUID as the permalink slug.

We should investigate whether switching to another field, for example the guid field, would be better.

Needs investigating for performance concerns, needs an upgrade path for existing attachments.

Support for uploads

Related to #13, if a provider allows users to upload files then AMF should provide the necessary integration with WordPress in order to override file uploads and pass them onto the provider. Then the provider only needs to be responsible for handling the upload of the file and returning relevant information about it.

This is of particular interest to AMF WordPress.

Some work has been done on this already, this is the tracking ticket for moving it into AMF.

Considerations

Authentication

  • Needs to be handled by the provider, as always
  • For AMF-WP specifically, the provider could pass on the client's authentication cookies to the remote site, this would work on a Multisite installation but not elsewhere. Alternatively, there would need to be a mechanism for per-user authentication to the remote site via OAuth, JWTs, application passwords, Basic Auth, etc.

File handling

Most likely AMF will need to override the default handling of file upload entry points and pass the appropriate $_FILES values onto the provider.

Entry points:

  • async-upload.php with action=upload-attachment
    • Called when uploading via the media manager
      • Note: ACF, CMB2, and Fieldmanager all use the media manager for uploads
    • Calls wp_ajax_upload_attachment() which calls media_handle_upload()
  • async-upload.php without an action
    • Called when uploading via the Media admin screen
    • Calls media_handle_upload()
  • wp-json/wp/v2/media
    • Called when uploading (or dragging and dropping) directly into a block in the block editor
    • Called by anything uploading via the REST API
    • Calls wp_handle_sideload()
  • media-new.php
    • Used by the fallback "browser uploader" (media-new.php?browser-uploader)
    • Calls media_handle_upload()
  • xmlrpc.php
    • TBD

Legacy entry points that almost certainly won't be supported:

  • Custom_Background::handle_upload()
  • Custom_Image_Header::step_2_manage_upload()
  • media-upload.php

Functions:

  • wp_ajax_upload_attachment()
    • Called via admin-ajax.php
  • media_handle_upload()
    • Calls wp_handle_upload()
      • Calls _wp_handle_upload()
    • Creates an attachment
  • media_handle_sideload()
    • Calls wp_handle_sideload()
      • Calls _wp_handle_upload()
    • Creates an attachment

Error handling

WP core does expose error messages returned by the uploader during the upload process, no issues there AFAIK

Upgrading from v0.12/lower to v0.13 breaks existing media

Despite making changes to support the new API, v0.13 uses a post meta value to store the source URL. This meta is not present in assets used in 0.12, resulting in broken images on sites that upgrade to the new version.

This means either a migration is required to use 0.13, or a fallback needs to be implemented, but neither are mentioned in the release notes.

Issue tracked down to changes in #35

Improve function portability for processing selections

Right now the ajax_select() function handles parsing the $_REQUEST global as well as creating the placeholder attachment post, follow up actions and returning a JSON response.

If this functionality were to be required for an import script, or script that converted local attachments to global ones for example, it would have to be recreated wholesale.

We should split ajax_select() into 2 functions, one that handles the $_REQUEST global and returning JSON, and one that accepts parameters necessary to create the local placeholder attachment posts for global images.

Implement error handling for the media manager Ajax response in WordPress core

https://core.trac.wordpress.org/ticket/49587

This ticket will enable us to show an error message to the user if there is a problem connecting to the asset provider. Currently WP core does not handle an error being returned from the attachments query, and any error results in the eternal spinner of doom.

I started working on this in WordPress/wordpress-develop#1065 but I forgot how difficult it is to figure out the media manager views. If someone wants to pick this up and carry on with it that would be great.

Test with Carbon Fields

https://github.com/htmlburger/carbon-fields

Looks like it passes the post__in parameter to the attachments query, and AMF doesn't currently support this as it unconditionally overrides the attachments query with one that sends the query to the provider. If any of the post ID specific query vars are present, AMF should not override the query. Need to check what Carbon Fields is using this for.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.