diff --git a/projects/packages/jetpack-mu-wpcom/changelog/wpcom-media-url-import b/projects/packages/jetpack-mu-wpcom/changelog/wpcom-media-url-import new file mode 100644 index 0000000000000..27db5a6914fdc --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/changelog/wpcom-media-url-import @@ -0,0 +1,4 @@ +Significance: minor +Type: added + +Implement media import via URL diff --git a/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php b/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php index ec3435b3fbc18..4bc2a39096518 100644 --- a/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php +++ b/projects/packages/jetpack-mu-wpcom/src/class-jetpack-mu-wpcom.php @@ -152,6 +152,7 @@ public static function load_wpcom_user_features() { require_once __DIR__ . '/features/wpcom-dashboard-widgets/wpcom-dashboard-widgets.php'; require_once __DIR__ . '/features/wpcom-locale/sync-locale-from-calypso-to-atomic.php'; require_once __DIR__ . '/features/wpcom-media/wpcom-external-media-import.php'; + require_once __DIR__ . '/features/wpcom-media/wpcom-media-url-import.php'; require_once __DIR__ . '/features/wpcom-plugins/wpcom-plugins.php'; require_once __DIR__ . '/features/wpcom-profile-settings/profile-settings-link-to-wpcom.php'; require_once __DIR__ . '/features/wpcom-profile-settings/profile-settings-notices.php'; diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import-form/index.jsx b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import-form/index.jsx new file mode 100644 index 0000000000000..571144b698c67 --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import-form/index.jsx @@ -0,0 +1,109 @@ +import { __ } from '@wordpress/i18n'; +import clsx from 'clsx'; +import { useState } from 'react'; + +import './style.scss'; + +const WpcomMediaUrlImportForm = ( { ajaxUrl, action, nonce } ) => { + const [ url, setUrl ] = useState( '' ); + + const [ show, setShow ] = useState( false ); + const [ isUploading, setIsUploading ] = useState( false ); + const [ isUploaded, setIsUploaded ] = useState( false ); + + const handleUrlChange = e => { + setUrl( e.target.value ); + }; + + const handleSubmit = async e => { + if ( isUploading ) { + return false; + } + try { + new URL( url ); // eslint-disable-line no-new + } catch { + return false; + } + e.preventDefault(); + + const formData = new FormData(); + formData.append( 'action', action ); + formData.append( 'image_url', url ); + formData.append( '_ajax_nonce', nonce ); + + setIsUploading( true ); + + const response = await fetch( ajaxUrl, { + method: 'POST', + body: formData, + } ); + + const { success, data } = await response.json(); + + if ( success ) { + window.wp.media.model.Attachment.get( data.attachment_id ).fetch( { + success: function ( attachment ) { + window.wp.media.frame.content.get().collection.add( attachment ); + + setIsUploading( false ); + + setIsUploaded( true ); + setTimeout( () => { + setIsUploaded( false ); + setUrl( '' ); + }, 2000 ); + }, + } ); + } else { + setIsUploading( false ); + // window.alert( data[ 0 ].message ); + } + + return false; + }; + + const renderLink = () => { + return ( + setShow( true ) }> + { __( 'Upload from URL', 'jetpack-mu-wpcom' ) } + + ); + }; + + const renderForm = () => { + let buttonText = __( 'Upload', 'jetpack-mu-wpcom' ); + if ( isUploaded ) { + buttonText = __( 'Uploaded!', 'jetpack-mu-wpcom' ); + } else if ( isUploading ) { + buttonText = __( 'Uploading…', 'jetpack-mu-wpcom' ); + } + + return ( +
+ + +
+ ); + }; + + return
{ show ? renderForm() : renderLink() }
; +}; + +export default WpcomMediaUrlImportForm; diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import-form/style.scss b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import-form/style.scss new file mode 100644 index 0000000000000..67d6bc15312e5 --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import-form/style.scss @@ -0,0 +1,7 @@ +.wpcom-media-url-import-form { + input { + width: 100%; + max-width: 600px; + margin-bottom: 5px; + } +} diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import.js b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import.js new file mode 100644 index 0000000000000..af016efa56375 --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import.js @@ -0,0 +1,21 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import WpcomMediaUrlImportForm from './wpcom-media-url-import-form'; + +const props = typeof window === 'object' ? window.JETPACK_MU_WPCOM_MEDIA_URL_IMPORT : {}; + +document.addEventListener( 'DOMContentLoaded', function () { + const observer = new MutationObserver( mutations => { + mutations.forEach( mutation => { + if ( mutation.addedNodes.length > 0 ) { + const container = document.getElementById( 'wpcom-media-url-import' ); + if ( container ) { + const root = ReactDOM.createRoot( container ); + root.render( ); + observer.disconnect(); + } + } + } ); + } ); + observer.observe( document.body, { childList: true, subtree: true } ); +} ); diff --git a/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import.php b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import.php new file mode 100644 index 0000000000000..e33baa8ea91c9 --- /dev/null +++ b/projects/packages/jetpack-mu-wpcom/src/features/wpcom-media/wpcom-media-url-import.php @@ -0,0 +1,63 @@ + +
+ admin_url( 'admin-ajax.php' ), + 'action' => 'wpcom_media_url_import', + 'nonce' => wp_create_nonce('wpcom_media_url_import'), + ) + ); + + wp_add_inline_script( + $handle, + "window.JETPACK_MU_WPCOM_MEDIA_URL_IMPORT = $data;", + 'before' + ); +} +add_action('post-plupload-upload-ui', 'enqueue_wpcom_media_url_import' ); + +require_once JETPACK__PLUGIN_DIR . 'class.json-api-endpoints.php'; +class DummyEndpoint extends WPCOM_JSON_API_Endpoint { + public function callback( $path = '', $blog_id = 0 ) {} +} + +function wpcom_handle_media_url_import() { + check_ajax_referer( 'wpcom_media_url_import' ); + + $image_url = esc_url_raw( $_POST['image_url'] ); + + $endpoint = new DummyEndpoint( array() ); + $result = $endpoint->handle_media_creation_v1_1( array(), array( $image_url ) ); + + if ( count( $result['media_ids'] ) > 0 ) { + $attachment_id = $result['media_ids'][0]; + return wp_send_json_success( array( 'attachment_id' => $attachment_id ) ); + } + if ( count( $result['errors'] ) > 0 ) { + $error = $result['errors'][0]; + return wp_send_json_error( new WP_Error( $error['error'], $error['message'] ) ); + } +} +add_action('wp_ajax_wpcom_media_url_import', 'wpcom_handle_media_url_import'); diff --git a/projects/packages/jetpack-mu-wpcom/webpack.config.js b/projects/packages/jetpack-mu-wpcom/webpack.config.js index 1329b074d4b9d..b4883c2857302 100644 --- a/projects/packages/jetpack-mu-wpcom/webpack.config.js +++ b/projects/packages/jetpack-mu-wpcom/webpack.config.js @@ -47,6 +47,7 @@ module.exports = [ './src/features/wpcom-documentation-links/wpcom-documentation-links.ts', 'wpcom-external-media-import-page': './src/features/wpcom-media/wpcom-external-media-import.js', + 'wpcom-media-url-import': './src/features/wpcom-media/wpcom-media-url-import.js', 'wpcom-plugins-banner': './src/features/wpcom-plugins/js/banner.js', 'wpcom-plugins-banner-style': './src/features/wpcom-plugins/css/banner.css', 'wpcom-profile-settings-link-to-wpcom':