Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 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
22 changes: 15 additions & 7 deletions assets/src/admin/media-sharing/components/browser-uploader.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import { useState, useRef } from '@wordpress/element';
* Internal dependencies
*/
import { uploadMedia, updateExistingAttachment, checkIfAllSitesConnected, isSyncAttachment as isSyncAttachmentApi } from '../../../components/api';
import { getFrameProperty, showSnackbarNotice } from '../../../js/utils';
import { getExtensions, getFrameProperty, getMimeTypes, restrictMediaFrameUploadTypes, showSnackbarNotice } from '../../../js/utils';

//
const UPLOAD_NONCE = window.OneMediaMediaFrame?.uploadNonce || '';
const ALLOWED_MIME_TYPES = window.OneMediaMediaFrame?.allowedMimeTypes !== 'undefined'
? Object.values( window.OneMediaMediaFrame?.allowedMimeTypes )
const ALLOWED_MIME_TYPES_MAP = typeof window.OneMediaMediaFrame?.allowedMimeTypesMap !== 'undefined'
? window.OneMediaMediaFrame?.allowedMimeTypesMap
: [];

const BrowserUploaderButton = ( {
Expand Down Expand Up @@ -108,10 +108,13 @@ const BrowserUploaderButton = ( {
},
multiple: false,
library: {
type: ALLOWED_MIME_TYPES,
type: getMimeTypes( ALLOWED_MIME_TYPES_MAP ),
is_onemedia_sync: false,
},
} );

restrictMediaFrameUploadTypes( frame, getExtensions( ALLOWED_MIME_TYPES_MAP ).join( ',' ) );

frame.on( 'open', () => {
const frameEl = frame.el;
if ( frameEl ) {
Expand Down Expand Up @@ -191,10 +194,13 @@ const BrowserUploaderButton = ( {
},
multiple: false,
library: {
type: ALLOWED_MIME_TYPES,
type: getMimeTypes( ALLOWED_MIME_TYPES_MAP ),
is_onemedia_sync: false,
},
} );

restrictMediaFrameUploadTypes( frame, getExtensions( ALLOWED_MIME_TYPES_MAP ).join( ',' ) );

frame.on( 'open', () => {
const frameEl = frame.el;
if ( frameEl ) {
Expand Down Expand Up @@ -252,8 +258,10 @@ const BrowserUploaderButton = ( {
return;
}

const mimeTypes = getMimeTypes( ALLOWED_MIME_TYPES_MAP );

// Validate file type.
if ( ! ALLOWED_MIME_TYPES.length > 0 || ! ALLOWED_MIME_TYPES.includes( file.type ) ) {
if ( ! mimeTypes.length > 0 || ! mimeTypes.includes( file.type ) ) {
setNotice( {
type: 'error',
message: __( 'Please select a valid image file.', 'onemedia' ),
Expand Down Expand Up @@ -346,7 +354,7 @@ const BrowserUploaderButton = ( {
<input
className="onemedia-hidden-file-input"
type="file"
accept={ ALLOWED_MIME_TYPES.join( ',' ) }
accept={ getMimeTypes( ALLOWED_MIME_TYPES_MAP ).join( ',' ) }
ref={ fileInputRef }
onChange={ handleFileSelect }
/>
Expand Down
13 changes: 8 additions & 5 deletions assets/src/admin/media-sharing/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@ import BrowserUploaderButton from './components/browser-uploader';
import ShareMediaModal from './components/ShareMediaModal';
import VersionModal from './components/VersionModal';
import { fetchSyncedSites as fetchSyncedSitesApi, fetchMediaItems as fetchMediaItemsApi, fetchBrandSites as fetchBrandSitesApi, shareMedia as shareMediaApi, uploadMedia } from '../../components/api';
import { getNoticeClass, trimTitle, debounce, getFrameProperty } from '../../js/utils';
import { getNoticeClass, trimTitle, debounce, getFrameProperty, restrictMediaFrameUploadTypes, getExtensions } from '../../js/utils';
import fallbackImage from '../../images/fallback-image.svg';

const MEDIA_PER_PAGE = 12;
const ONEMEDIA_PLUGIN_TAXONOMY_TERM = 'onemedia';
const UPLOAD_NONCE = window.OneMediaMediaSharing?.uploadNonce || '';
const ONEMEDIA_MEDIA_SHARING = window.OneMediaMediaSharing || {};
const ALLOWED_MIME_TYPES_MAP = typeof window.OneMediaMediaFrame?.allowedMimeTypesMap !== 'undefined'
? window.OneMediaMediaFrame?.allowedMimeTypesMap
: [];

const MediaSharingApp = ( {
imageType = '',
Expand Down Expand Up @@ -199,7 +202,7 @@ const MediaSharingApp = ( {
}
};

const handleEditMedia = ( mediaId, currentImageType ) => {
const handleEditMedia = ( mediaId ) => {
if ( getFrameProperty( 'wp.media' ) ) {
// Create edit media frame.
const editFrame = window.wp.media( {
Expand All @@ -210,11 +213,12 @@ const MediaSharingApp = ( {
multiple: false,
library: {
type: 'image',
onemedia_sync_media_filter:
ONEMEDIA_PLUGIN_TAXONOMY_TERM === currentImageType ? true : false,
is_onemedia_sync: true,
},
} );

restrictMediaFrameUploadTypes( editFrame, getExtensions( ALLOWED_MIME_TYPES_MAP ).join( ',' ), true );

editFrame.on( 'open', function() {
// Reset the selection state.
editFrame.state().get( 'selection' ).reset();
Expand Down Expand Up @@ -516,7 +520,6 @@ const MediaSharingApp = ( {
e.stopPropagation();
handleEditMedia(
media.id,
imageType,
);
} }
title={ __( 'Edit Media', 'onemedia' ) }
Expand Down
25 changes: 5 additions & 20 deletions assets/src/css/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,7 @@
}
}

.onemedia_page_onemedia-media-sharing,
.media_page_onemedia-media-sharing {
.toplevel_page_onemedia {

.components-tooltip {
white-space: pre-line;
Expand All @@ -270,8 +269,8 @@
}

.media-toolbar-secondary .attachment-filters {
width: 100%;
max-width: 100%;
width: 100% !important;
max-width: 100% !important;
}
}
}
Expand Down Expand Up @@ -502,23 +501,9 @@
}
}

.onemedia-selec-sync-media-frame{

.onemedia-synced-media{
pointer-events: none;
}
}

.onemedia-select-non-sync-media-frame {
.onemedia-selec-sync-media-frame {

.onemedia-synced-media {
display: none;
}
}

.onemedia-edit-media-frame {

.onemedia-non-synced-media {
display: none;
pointer-events: none;
}
}
6 changes: 3 additions & 3 deletions assets/src/js/media-frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function isSyncAttachment( attachmentOrElement ) {

// Handle Backbone model
if ( typeof attachmentOrElement.get === 'function' ) {
return isSyncValue( attachmentOrElement.get( 'is_sync_attachment' ) );
return isSyncValue( attachmentOrElement.get( 'is_onemedia_sync' ) );
}

// Not a DOM element
Expand All @@ -55,7 +55,7 @@ function isSyncAttachment( attachmentOrElement ) {
if ( wpMedia && wpMedia.attachment ) {
const attachment = wpMedia.attachment( attachmentId );
if ( attachment && attachment.get ) {
return isSyncValue( attachment.get( 'is_sync_attachment' ) );
return isSyncValue( attachment.get( 'is_onemedia_sync' ) );
}
}

Expand All @@ -80,7 +80,7 @@ function customizeSyncMediaFrame() {
originalAttachmentRender.apply( this, arguments );

// Add custom class if synced.
if ( this.model.get( 'is_sync_attachment' ) === true ) {
if ( this.model.get( 'is_onemedia_sync' ) === true ) {
// this.el is the native DOM element
const element = this.el;

Expand Down
113 changes: 113 additions & 0 deletions assets/src/js/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,46 @@

import type { NoticeType } from '../admin/settings/page';

declare global {
interface Window {
wp: {
Uploader: {
queue: unknown;
};
media: {
attachment( id: number ): {
get( key: string ): unknown;
} | undefined;
};
};
}
}

type WPMediaUploader = {
settings: {
multipart_params: Record<string, unknown>;
}
setOption(
key: 'filters' | 'multi_selection' | string,
value: string | object | boolean,
): void;
};

type WPMediaFrame = {
once( event: 'uploader:ready' | string, cb: () => void ): void;
uploader: {
uploader: {
uploader: WPMediaUploader;
};
};
on( event: 'ready' | string, cb: () => void ): void;
state(): {
get( key: 'library' | string ): {
observe( queue: unknown ): void;
} | undefined;
};
};

/**
* Helper function to validate if a string is a well-formed URL.
*
Expand Down Expand Up @@ -194,6 +234,76 @@ const showSnackbarNotice = ( detail: NoticeType ): void => {
document.dispatchEvent( event );
};

/**
* Restrict upload types in a WordPress media frame.
*
* @param {WPMediaFrame} frame - The WordPress media frame to restrict.
* @param {string} allowedTypes - Comma-separated list of allowed file extensions.
* @param {boolean} is_sync - Whether the upload is for sync (default false).
*
* @return {void}
*/
const restrictMediaFrameUploadTypes = ( frame : WPMediaFrame, allowedTypes: string, is_sync:boolean = false ) => {
/**
* Using mime_type will restrict the upload types in media modal,
* Which we don't want as we only need to restrict for OneMedia uploader frame.
*
* @see https://wordpress.stackexchange.com/questions/343320/restrict-file-types-in-the-uploader-of-a-wp-media-frame
*/
frame.once( 'uploader:ready', () => {
const uploader = frame.uploader.uploader.uploader;

// Get existing multipart_params first
const existingParams = uploader.settings.multipart_params || {};

uploader.setOption( 'filters',
{
mime_types: [
{ extensions: allowedTypes },
],
},
);

// Trick to re-init field
uploader.setOption( 'multi_selection', false );

// Set is_onemedia_sync param
uploader.setOption( 'multipart_params', {
...existingParams,
is_onemedia_sync: is_sync,
} );
} );

/**
* Observe the library to link with uploader queue.
*
* @see https://core.trac.wordpress.org/ticket/34465
*/
frame.on( 'ready', function() {
const library = frame.state().get( 'library' );
if ( library && window.wp.Uploader && window.wp.Uploader.queue ) {
library.observe( window.wp.Uploader.queue );
}
} );
};

/**
* Get MIME types from a MIME map.
* @param {Object} mimeMap
*/
function getMimeTypes( mimeMap : Object ) : string[] {
return [ ...new Set( Object.values( mimeMap ) ) ];
}

/**
* Get extensions from a MIME map.
* @param {Object} mimeMap
*/
function getExtensions( mimeMap : Object ) : string[] {
return Object.keys( mimeMap )
.flatMap( ( key ) => key.split( '|' ) );
}

export {
isURL,
isValidUrl,
Expand All @@ -204,4 +314,7 @@ export {
observeElement,
getFrameProperty,
showSnackbarNotice,
restrictMediaFrameUploadTypes,
getMimeTypes,
getExtensions,
};
30 changes: 15 additions & 15 deletions inc/Modules/Core/Assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,21 @@ final class Assets implements Registrable {
public static function get_localized_data(): array {
if ( empty( self::$localized_data ) ) {
self::$localized_data = [
'restUrl' => esc_url( home_url( '/wp-json' ) ),
'restNonce' => wp_create_nonce( 'wp_rest' ),
'apiKey' => Settings::get_api_key(),
'settingsLink' => esc_url( admin_url( 'admin.php?page=onemedia-settings' ) ),
'siteType' => Settings::get_site_type(),
'siteName' => get_bloginfo( 'name' ),
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'uploadNonce' => wp_create_nonce( 'onemedia_upload_media' ),
'allowedMimeTypes' => Utils::get_supported_mime_types(),
'mediaSyncNonce' => wp_create_nonce( 'onemedia_check_sync_status' ),
'allLabel' => __( 'All media', 'onemedia' ),
'syncLabel' => __( 'Synced', 'onemedia' ),
'notSyncLabel' => __( 'Not Synced', 'onemedia' ),
'filterLabel' => __( 'Sync Status', 'onemedia' ),
'syncStatus' => Attachment::SYNC_STATUS_POSTMETA_KEY,
'restUrl' => esc_url( home_url( '/wp-json' ) ),
'restNonce' => wp_create_nonce( 'wp_rest' ),
'apiKey' => Settings::get_api_key(),
'settingsLink' => esc_url( admin_url( 'admin.php?page=onemedia-settings' ) ),
'siteType' => Settings::get_site_type(),
'siteName' => get_bloginfo( 'name' ),
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'uploadNonce' => wp_create_nonce( 'onemedia_upload_media' ),
'allowedMimeTypesMap' => Utils::get_supported_mime_types(),
'mediaSyncNonce' => wp_create_nonce( 'onemedia_check_sync_status' ),
'allLabel' => __( 'All media', 'onemedia' ),
'syncLabel' => __( 'Synced', 'onemedia' ),
'notSyncLabel' => __( 'Not Synced', 'onemedia' ),
'filterLabel' => __( 'Sync Status', 'onemedia' ),
'syncStatus' => Attachment::SYNC_STATUS_POSTMETA_KEY,
];
}

Expand Down
Loading