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

Implement upload media from URL #41089

Draft
wants to merge 1 commit into
base: trunk
Choose a base branch
from
Draft
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
5 changes: 4 additions & 1 deletion projects/packages/jetpack-mu-wpcom/.phan/baseline.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
// PhanNoopNew : 5 occurrences
// PhanTypeMismatchArgumentInternal : 4 occurrences
// PhanTypeMismatchReturnProbablyReal : 4 occurrences
// PhanParamTooMany : 3 occurrences
// PhanTypePossiblyInvalidDimOffset : 3 occurrences
// PhanEmptyFQSENInCallable : 2 occurrences
// PhanParamTooMany : 2 occurrences
// PhanTypeArraySuspicious : 2 occurrences
// PhanTypeArraySuspiciousNullable : 2 occurrences
// PhanTypeMismatchDefault : 2 occurrences
Expand All @@ -37,6 +37,8 @@
// PhanTypeMismatchReturnNullable : 1 occurrence
// PhanTypeNonVarPassByRef : 1 occurrence
// PhanTypeVoidArgument : 1 occurrence
// PhanUndeclaredExtendedClass : 1 occurrence
// PhanUndeclaredMethod : 1 occurrence

// Currently, file_suppressions and directory_suppressions are the only supported suppressions
'file_suppressions' => [
Expand All @@ -57,6 +59,7 @@
'src/features/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-launchpad.php' => ['PhanPluginDuplicateConditionalNullCoalescing'],
'src/features/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-site-migration-migrate-guru-key.php' => ['PhanUndeclaredClassMethod'],
'src/features/wpcom-endpoints/class-wpcom-rest-api-v2-endpoint-site-migration-wpcom-migration-key.php' => ['PhanUndeclaredClassMethod'],
'src/features/wpcom-media/wpcom-media-url-import.php' => ['PhanParamTooMany', 'PhanUndeclaredExtendedClass', 'PhanUndeclaredMethod'],
'tests/lib/functions-wordpress.php' => ['PhanRedefineFunction'],
'tests/php/features/block-patterns/class-wpcom-block-patterns-from-api-test.php' => ['PhanDeprecatedFunction'],
'tests/php/features/coming-soon/class-coming-soon-test.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentProbablyReal'],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Implement media import via URL
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-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';
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 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 (
<a href="#" onClick={ () => setShow( true ) }>
{ __( 'Upload from URL', 'jetpack-mu-wpcom' ) }
</a>
);
};

const renderForm = () => {
let buttonText = __( 'Upload', 'jetpack-mu-wpcom' );
if ( isUploaded ) {
buttonText = __( 'Uploaded!', 'jetpack-mu-wpcom' );
} else 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 || isUploaded }
/>
<button
className={ clsx( 'button', 'button-primary', {
'updating-message': isUploading,
'updated-message': isUploaded,
} ) }
onClick={ handleSubmit }
readOnly={ isUploading }
disabled={ isUploaded }
>
{ buttonText }
</button>
</form>
);
};

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

export default WpcomMediaUrlImportForm;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.wpcom-media-url-import-form {
input {
width: 100%;
max-width: 600px;
margin-bottom: 5px;
}
}
Original file line number Diff line number Diff line change
@@ -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( <WpcomMediaUrlImportForm { ...props } /> );
observer.disconnect();
}
}
} );
} );
observer.observe( document.body, { childList: true, subtree: true } );
} );
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php
/**
* WordPress.com media URL import functionality.
*
* @package automattic/jetpack-mu-wpcom
*/

/**
* Appends the wpcom media UL import form.
*/
function wpcom_media_url_import() {
?>
<div id="wpcom-media-url-import"></div>
<?php

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

$data = wp_json_encode(
array(
'ajaxUrl' => 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'
);
}

/**
* AJAX handler for the wpcom media URL import.
*/
function wpcom_handle_media_url_import() {
check_ajax_referer( 'wpcom_media_url_import' );

if ( ! isset( $_POST['image_url'] ) ) {
return;
}
$image_url = esc_url_raw( wp_unslash( $_POST['image_url'] ) );

require_once JETPACK__PLUGIN_DIR . 'class.json-api-endpoints.php';
$endpoint = new class( array() ) extends WPCOM_JSON_API_Endpoint {
// phpcs:ignore Squiz.Commenting.FunctionComment.Missing, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
public function callback( $path = '', $blog_id = 0 ) {}
};

$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'] ) );
}
}

if ( current_user_can( 'upload_files' ) ) {
add_action( 'post-plupload-upload-ui', 'wpcom_media_url_import', 20 );
add_action( 'wp_ajax_wpcom_media_url_import', 'wpcom_handle_media_url_import' );
}
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-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':
Expand Down
Loading