Skip to content

Commit

Permalink
Media Library: allow uploading media from URL
Browse files Browse the repository at this point in the history
  • Loading branch information
fushar committed Jan 21, 2025
1 parent 6cab52d commit ba93666
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Allows uploading media from URL in Media Library
Original file line number Diff line number Diff line change
Expand Up @@ -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-upload.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';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { __ } from '@wordpress/i18n';
import clsx from 'clsx';
import { useState } from 'react';

import './style.scss';

const WpcomMediaUrlUploadForm = ( { ajaxUrl, action, nonce, isSiteEditor } ) => {
const [ url, setUrl ] = useState( '' );

const [ show, setShow ] = useState( false );
const [ isUploading, setIsUploading ] = 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( '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 ) {
if ( isSiteEditor ) {
const mediaLibraryTab = window.wp.media.frame.state( 'library' );
mediaLibraryTab.trigger( 'open' );

window.wp.media.frame.content.get().collection.add( attachment );

const selection = mediaLibraryTab.get( 'selection' );
selection.reset();
selection.add( [ attachment ] );
} else {
window.wp.media.frame.content.get().collection.add( attachment );
}

setIsUploading( false );
setUrl( '' );
},
} );
} else {
setIsUploading( false );
window.wp.Uploader.errors.add( { file: { name: url }, message: data[ 0 ].message } );
}

return false;
};

const renderLink = () => {
return (
<a href="#" onClick={ () => setShow( true ) }>
{ __( 'Upload from URL', 'jetpack-mu-wpcom' ) }
</a>
);
};

const renderForm = () => {
let buttonText = __( 'Upload', 'jetpack-mu-wpcom' );
if ( isUploading ) {
buttonText = __( 'Uploading…', 'jetpack-mu-wpcom' );
}
return (
<form onSubmit="return false;">
<input
type="url"
value={ url }
onChange={ handleUrlChange }
placeholder={ __( 'Enter media URL', 'jetpack-mu-wpcom' ) }
required
readOnly={ isUploading }
/>
<button
className={ clsx( 'button', 'button-primary', {
'updating-message': isUploading,
} ) }
onClick={ handleSubmit }
readOnly={ isUploading }
>
{ buttonText }
</button>
</form>
);
};

return <div className="wpcom-media-url-upload-form">{ show ? renderForm() : renderLink() }</div>;
};

export default WpcomMediaUrlUploadForm;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.wpcom-media-url-upload-form {
input {
width: 100%;
max-width: 600px;
margin-bottom: 5px;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import WpcomMediaUrlUploadForm from './wpcom-media-url-upload-form';

const props = typeof window === 'object' ? window.JETPACK_MU_WPCOM_MEDIA_URL_UPLOAD : {};

document.addEventListener( 'DOMContentLoaded', function () {
if ( window.wp?.media?.view?.UploaderInline ) {
const originalUploaderInline = window.wp.media.view.UploaderInline;

window.wp.media.view.UploaderInline = originalUploaderInline.extend( {
ready: function () {
originalUploaderInline.prototype.ready.apply( this, arguments );

const container = document.getElementById( 'wpcom-media-url-upload' );
if ( container ) {
const root = ReactDOM.createRoot( container );
root.render( <WpcomMediaUrlUploadForm { ...props } /> );
}
},
} );
}
} );
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php
/**
* Allows uploading media from URL in Media Library.
*
* @package automattic/jetpack-mu-wpcom
*/

/**
* Appends the wpcom media URL upload form.
*/
function wpcom_media_url_upload() {
global $pagenow;

?>
<div id="wpcom-media-url-upload"></div>
<?php

$handle = jetpack_mu_wpcom_enqueue_assets( 'wpcom-media-url-upload', array( 'js', 'css' ) );

$data = wp_json_encode(
array(
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'action' => 'wpcom_media_url_upload',
'nonce' => wp_create_nonce( 'wpcom_media_url_upload' ),
'isSiteEditor' => $pagenow === 'site-editor.php',
)
);

wp_add_inline_script(
$handle,
"window.JETPACK_MU_WPCOM_MEDIA_URL_UPLOAD = $data;",
'before'
);
}

/**
* AJAX handler for the wpcom media URL upload.
*/
function wpcom_handle_media_url_upload() {
check_ajax_referer( 'wpcom_media_url_upload' );

if ( ! isset( $_POST['url'] ) ) {
return;
}

$url = esc_url_raw( wp_unslash( $_POST['url'] ) );

$tmp = download_url( $url );
if ( is_wp_error( $tmp ) ) {
return wp_send_json_error( $tmp );
}

if ( is_multisite() ) {
add_filter( 'wp_handle_sideload_prefilter', 'check_upload_size' );
}

$attachment_id = media_handle_sideload(
array(
'name' => basename( wp_parse_url( $url, PHP_URL_PATH ) ),
'tmp_name' => $tmp,
)
);

if ( file_exists( $tmp ) ) {
wp_delete_file( $tmp );
}

if ( is_wp_error( $attachment_id ) ) {
return wp_send_json_error( $attachment_id );
} else {
return wp_send_json_success( array( 'attachment_id' => $attachment_id ) );
}
}

if ( current_user_can( 'upload_files' ) ) {
add_action( 'post-plupload-upload-ui', 'wpcom_media_url_upload', 20 );
add_action( 'wp_ajax_wpcom_media_url_upload', 'wpcom_handle_media_url_upload' );
}
1 change: 1 addition & 0 deletions projects/packages/jetpack-mu-wpcom/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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-upload': './src/features/wpcom-media/wpcom-media-url-upload.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':
Expand Down

0 comments on commit ba93666

Please sign in to comment.