Closed Stuart92 closed 2 years ago
So sorry - I just saw the example directory and see what you mean. Sorry to bother you.
For those interested, there is a basic sample here: https://github.com/VanOns/laraberg/blob/main/example/resources/js/app.js The upload of the image would need to be handled appropriately in the sample mediaupload function.
On second thought - can you please clarify whether passing the file object to an ajax function is sufficient data to save the uploaded image in an application?
Hi!
That depends on the Ajax function you're using. Laraberg itself does not do anything for handling file uploads, our laraberg-nova package has an implementation that's suitable for the most common situations: https://github.com/VanOns/laraberg-nova/blob/main/resources/js/media-upload.js
Hope that helps!
Hi Maurice - Thank you for the quick reply. This looks very helpful - I will give it a try. Cheers.
For those that are interested, here's how I went about this. Note that my JS is quite poor, so there may be a better way to go about this:
Initializing Laraberg:
import uuidv4 from './uuidv4';
import mediaUpload from './media-upload';
const settings = {}
settings.mediaUpload = mediaUpload(
uuidv4(),
(e) => {
console.log(e);
}
);
Laraberg.init('#laraberg-content', settings);
uuidv4.js comes from https://github.com/VanOns/laraberg-nova/blob/main/resources/js/uuidv4.js
In media-upload.js
import uuidv4 from './uuidv4';
const mediaUpload = (draftId, onError = () => {}) => {
const endpoint = '/upload-attachment';
return async({filesList, onFileChange}) => {
const promises = Array.from(filesList).map(async (file) => {
const data = new FormData();
data.append('Content-Type', file.type);
data.append('attachment', file);
try {
var ajaxData;
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: endpoint,
async: false,
data: data,
processData: false,
contentType: false,
type: 'POST',
success: function(data){
if(data.uploaded == true) {
ajaxCallBack(data);
}
},
error: function(err){
console.log(err);
}
});
function ajaxCallBack(data){
ajaxData = data;
}
return {
id: uuidv4(),
name: ajaxData.fileName,
url: ajaxData.url
}
}
catch (e) {
onError(e)
}
});
const uploadedFiles = await Promise.all(promises);
onFileChange(uploadedFiles);
}
};
export default mediaUpload;
You'll need to define a POST route for /upload-attachment, and handle the file upload in a controller method. The controller method should return the filename, path to file, and uploaded boolean (success/fail).
And, to Maurice - thank you again for your help. I noticed that the "Image" and "Gallery" blocks work nicely, but the "Cover" (adding a background image) and "Media & Content" blocks do nothing when uploading an image. I'll keep the issue open in case you'd like to address that here (though, I appreciate that you're possibly very busy and won't be able to address the issue). Thanks!
A tip if you still want to use the Laravel File Manager package in v2 like v1:
Use the old code from v1.0: https://github.com/VanOns/laraberg/blob/v1.x/src/resources/js/laravel-filemanager/index.js
Load the required assets like the documentation has stated.
Register the component LaravelFilemanager like v1:
https://github.com/VanOns/laraberg/blob/v1.x/src/resources/js/laravel-filemanager/index.js Make sure to load the correct config @ openLFM function
class LaravelFilemanager extends Laraberg.wordpress.element.Component {
constructor (props) {
super(props)
this.state = {
media: []
}
}
getMediaType = (path) => {
const video = ['mp4', 'm4v', 'mov', 'wmv', 'avi', 'mpg', 'ogv', '3gp', '3g2']
const audio = ['mp3', 'm4a', 'ogg', 'wav']
const extension = path.split('.').slice(-1).pop()
if (video.includes(extension)) {
return 'video'
} else if (audio.includes(extension)) {
return 'audio'
} else {
return 'image'
}
}
onSelect = (url, path) => {
this.props.value = null
const { multiple, onSelect } = this.props
const media = {
url: url,
type: this.getMediaType(path)
}
if (multiple) { this.state.media.push(media) }
onSelect(multiple ? this.state.media : media)
}
openModal = () => {
let type = 'file'
if (this.props.allowedTypes.length === 1 && this.props.allowedTypes[0] === 'image') {
type = 'image'
}
this.openLFM(type, this.onSelect)
}
openLFM = (type, cb) => {
const routePrefix = '/laravel-filemanager'
window.open(routePrefix + '?type=' + type, 'FileManager', 'width=900,height=600')
window.SetUrl = function (items) {
if (items[0]) {
cb(items[0].url, items[0].name)
}
}
}
render () {
const { render } = this.props
return render({ open: this.openModal })
}
}
Laraberg.wordpress.hooks.addFilter( 'editor.MediaUpload', 'core/edit-post/components/media-upload/replace-media-upload', () => LaravelFilemanager )
Disable the old media button like v1:
- https://github.com/VanOns/laraberg/blob/v1.x/src/resources/js/lib/element-ready.js
- https://github.com/VanOns/laraberg/blob/v1.x/src/resources/js/lib/configure-editor.js
elementRendered('.components-form-file-upload button', element => element.remove())
function elementRendered (selector, callback) { const renderedElements = [] const observer = new MutationObserver((mutations) => { const elements = document.querySelectorAll(selector) elements.forEach(element => { if (!renderedElements.includes(element)) { renderedElements.push(element) callback(element) } }) }) observer.observe(document.documentElement, { childList: true, subtree: true }) return observer }
Load Laraberg with a empty mediupload:
const mediaUpload = ({filesList, onFileChange}) => {} Laraberg.init('content-gutenberg', { mediaUpload });
@dennisnienhuis - Thank you so very much for this - I would not have figured that out in a million years! Your code was plug-and-play.
The only oddity is that depending on the block type, a different LFM folder is opened for me. I.e. adding an image to a "Cover" or "Media & Text" block opens the folder I'd expect to see for the user, and "Image" and "Gallery" open a different folder. I can't quite figure out the reason for that.
@Stuart92 Glad that it worked! Thats because a filter is used on the openModal function:
let type = 'file'
if (this.props.allowedTypes.length === 1 && this.props.allowedTypes[0] === 'image') {
type = 'image'
}
See URL for example for the gallery block:
and for "Media & Text":
To show all file types use:
window.open(routePrefix, 'FileManager', 'width=900,height=600')
This will prevent opening different types, like stated on the github page of laravel filemanager. "Supports two categories: files and images. Each type works in different directory."
I don't know the impact of this if an user is uploading for example documents and non image files.
Ah, I see - thank you for clarifying. I have opted to always open the "file" directory, and it seems like most block elements appropriately throw an error when the wrong file type is selected. Thanks again, @mauricewijnia and @dennisnienhuis
Hi Maurice,
Thanks so much for releasing V2 - really appreciate your work on it! It seems to be a big step forward in terms of being cleanly integrated.
I was using Laravel File Manager with V1, and I see you have noted "This can be solved by implementing your own mediaUpload function and passing it as an editor setting." - would you be able to provide a bit more documentation there? Any suggestions on what media library / file manager to integrate with?
Thanks, Stuart