BRACKETS-by-TRIAD / craftable

Admin panel builder / CRUD generator for Laravel.
https://getcraftable.com
MIT License
981 stars 192 forks source link

Media upload #56

Closed isaicus closed 5 years ago

isaicus commented 5 years ago

Hi there, I have some trouble using media upload. I used the basic code from documentation and I have some issues.

I have created one more role (User) setting the permissions for this role into Database ( same as for the Administrator ), added the gate for User, actually everything works just fine inside my app but not the media upload. when I am logged in as Administrator (Administrator role) it uploads the media into laravel "uploads" folder but I get nothing submitted into "media" mysql table and I guess that is the reason that I get no previous uploaded images into edit view (even that those are uploaded).

when I am logged in as a regular user (User role) I get "this action is unauthorised" (and the User roles already has admin.upload permission into database). To make it work I had to comment the $this->authorize( 'admin.upload' ); in FileUploadController.php but still I get no media library data into my database and no conversions folders (like thumbs etc.) even if I have already registered my conversions.

I read and read throughout the code, tried to understand spatie/medialibrary but with no results. I am new to Laravel and Vue (basic knowledge) and your craftable package helped me to understand allot of Laravel so that's why I won't give up until I get it to work.

Thanks :)

palypster commented 5 years ago

Let's solve the first problem first :) So you're saying an Administrator role can perform an upload of a media for an eloquent model (say an Article) that is using MediaLibrary (https://docs.getcraftable.com/v2/#/media?id=basic-usage). Upload occurs, you can see the media under the uploads folder but then you cannot see anything in the media table. But there is a media table.

First, you know that the model must be saved first before the media can be processed, assigned to it and the conversions to be generated, right?

If yes, then try to retrieve the article and try to retrieve the media using (https://docs.getcraftable.com/v2/#/media?id=retrieve), what do you get?

isaicus commented 5 years ago

Ok, so all I have tried to do is on an already saved model, in the edit page. I followed your instructions and tried to retrieve the media and $model->getMedia('myCollection') returns an empty array so I get an undefined offset: 0. But I think this is normal taking into consideration that I have nothing to retrieve from media table...

I tried to look for the methods that manage the DB insert in the hasMediaCollectionTrait and hasMediaCollection interface but I got nothing ( something that calls against media table, something related to media table, something related to my model and another model that manages db insert ).

I have also tried to search for some eloquent relations between my model and media library.

I have nothing left to search for :)

palypster commented 5 years ago

Ok, so all I have tried to do is on an already saved model, in the edit page. My point was, that the act of assigning the media to the model is done when the model is saved. So if you are creating a new model, then you need to save the model after you upload the media. Btw, it doesn't matter if you are using edit page or create page. The point is you have to hit the save button on the model itself, because this triggers the assigning of the media. Can you confirm you are doing that?

The trick how this is done is using the bootHasMediaCollectionsTrait: https://github.com/BRACKETS-by-TRIAD/media/blob/master/src/HasMedia/HasMediaCollectionsTrait.php#L203 What it does is (if the auto-process is turned on, should be on by default) it processes the special media data structure from the request on the saving event of the model, process them (do some conversions if needed) and assign them to the just saving model.

Can you confirm you don't override the default media-collections.auto_process config? Can you confirm you are using dedicated UI utility to upload media (https://docs.getcraftable.com/v2/#/admin-ui?id=media-upload) (it's required to sent the data in a specific json structure - but if you are following the documenation, everything should be set up correctly).

isaicus commented 5 years ago

Yes, I expect the media to be uploaded and media saved into DB after hitting save button. Autoprocessmedia is ON, I tried to do the uplad process using the provided craftable-ui, with the ducumentation directions. So from what I read there all I have to do is to prepare the model and controller and the data to be inserted will be processed by the admin-ui. When I have seen that it was not working I started to dig into the problem.

If the autoprocessmedia is off I have to deal with passing media data from upload form to request object and I tried this but reading code from baseform all I see is the code that deals with wysiwyg upload. Where can I find the code that deals with dropzone ( I want to intercept the passing data from form to request ).

But again, I want to make it work as it was intended to because it is all I need, with default configuration.

In the documentation is tgere a line that I don't get "The $request->gallery should be an array in following format:" ( and there goes the format )

My question is, the provided upload form will automatically do that for me, will provide the array to the model?

palypster commented 5 years ago

Yes, it should do it. :( I'm lost, I don't understand why it is not working for you :( It should be working, you can try it yourself on the demo: https://demo.getcraftable.com/admin/posts It is working for us in other project as well. Can you please send me your Bitbucket account and I can assign your account to the source code of this demo and you can try it out yourself, if it's working?

@kratochvilam any ideas?

isaicus commented 5 years ago

Will it help if I show you the code? Where is the file that passes media data from form to controller located ?

My Bitbucket account is isaicus

palypster commented 5 years ago

Following the demo project, image you have an article Post. Then you should see a Form.js file demo/resources/assets/admin/js/post/Form.js with similar content:

import AppForm from '../components/Form/AppForm';

Vue.component('post-form', {
    mixins: [AppForm],
    data: function() {
        return {
            form: {
                title:  '' ,
                perex:  '' ,
                published_at:  '' ,
                enabled:  false ,

            },
            mediaCollections: ['cover', 'gallery', 'pdf']
        }
    }

});

Mixin AppForm uses (indirectly) the BaseForm mixin. The line handling the the upload form is: https://github.com/BRACKETS-by-TRIAD/craftable-frontend/blob/master/assets/js/base-components/Form/BaseForm.js#L236

isaicus commented 5 years ago

Can you please add my bitbucket account ( isaicus ) to source code? Thanks

isaicus commented 5 years ago

ok, I have checked your demo source code and the only difference that I have noticed is how I include the upload field.

I have included the field directly in views/admin/post/components/form-elements.blade.php and not in the edit.blade.php or create.blade.php. Could that be the problem? I will test it when I get my hands on my computer and let you know. Thanks so much for all your help.

palypster commented 5 years ago

I doubt that this may cause the problem. There must be something else, but I'm out of ideas :(

isaicus commented 5 years ago

Ok, so I modified the files accordingly to your demo and when I looked in the console I get two errors

  1. [Error] Unhandled Promise Rejection: TypeError: undefined is not an object (evaluating 'Object.keys(errors)') keys (admin.js:46017) onFail (admin.js:46017) onFail promiseReactionJob

  2. [Error] Failed to load resource: the server responded with a status of 500 (Internal Server Error) (2, line 0)

( id is one of my models it refers to a picture id )

and also one warning

[Warning] MediaUploader warning: Media input must have a unique name, 'picture_id' is already defined in regular inputs. (admin.js, line 45973)

isaicus commented 5 years ago

Just to be sure, I started with a fresh copy of craftable and kept it simple, now I get no errors but still no entries into media table.

isaicus commented 5 years ago

Managed to do a temporary fix by commenting the redirect action after form submit in craftable/assets/js/base-components/Form/BaseForm.js

onSuccess(data) { this.submiting = false; /* if (data.redirect) { window.location.replace(data.redirect) }*/ }

palypster commented 5 years ago

Wow, thanks for a big debug. We'll have a look why this may cause any error. Very interesting.

isaicus commented 5 years ago

ok, so let me know please if you have any updates. I am very interested in this package. Thanks

palypster commented 5 years ago

Quick question - before you have commenting the redirect, during your tests, were you waiting until the media upload has finished before submiting the form? I suppose yes, but if not, that would explained everything :)

isaicus commented 5 years ago

yes I have waited for media to upload, and it dit, my problem was with that the media data was not inserted into media table so I had no reference for that image to be accessed in any way (to view it or delete it or so)

palypster commented 5 years ago

In that case I don't understand, how can your temp-fix work. What you have done is you have commented the line saying: Once the model is saved (and all the media is processed) successfully, then redirect back to the listing. So if it was not inserting to the media table with that line turned on, how can it start inserting with that line commented out. It just doesn't make any sense :-/ Do you have any ideas?

isaicus commented 5 years ago

I know what you are saying, it is crazy but that is why took me so long to find a fix because reading the code everything looked fine. And that commenting was for debug purposes in a try to break it into stages and see what each stage does, it is not like I would ever think that that was the problem :)

Actually the fix works just fine for me because instead of redirecting now I get a confirmation message that the model was saved, wich I think is more natural.

lchachurski commented 5 years ago

it uploads the media into laravel "uploads" folder but I get nothing submitted into "media" mysql table

I had the same issue when I've placed code inside card-body div like this:

                    <div class="card-body">

                        @include('admin.property.components.form-elements')

                        @include('brackets/admin-ui::admin.includes.media-uploader', [
                            'mediaCollection' => app(App\Models\Property::class)->getMediaCollection('gallery'),
                            'media' => $property->getThumbs200ForCollection('gallery'),
                            'label' => 'Gallery'
                        ])
                    </div>

Changing it to the following fixed the issue

                    <div class="card-body">

                        @include('admin.property.components.form-elements')

                    </div>

                    @include('brackets/admin-ui::admin.includes.media-uploader', [
                        'mediaCollection' => app(App\Models\Property::class)->getMediaCollection('gallery'),
                        'media' => $property->getThumbs200ForCollection('gallery'),
                        'label' => 'Gallery'
                    ])
casper123 commented 5 years ago

I'm also having the same issue. My file is uploaded under storage/uploads but no record is inserted in media table in database

casper123 commented 5 years ago

onSuccess

@isaicus 's solution works well for me as well

palypster commented 5 years ago

@SamuelT-ST please have a look on this issue, if it's also present in our upcoming update of brackets/media package?

casper123 commented 5 years ago

@palypster , it does happen with latest package as well. I downloaded this package yesterday and found this issue.

palypster commented 5 years ago

But @SamuelT-ST is currently working on a new version, not published yet. I'm curious if the problem occurs there as well.

Ravenna commented 5 years ago

I am using "brackets/media": "^2.0" and am seeing the same issue. i have tested a clean install and the problem re-occurs. Media gets uploaded to folder but no records in the db.

I have not tried commenting anything out as that would get replaced anytime I run composer. Any advice?

palypster commented 5 years ago

Sorry, we really are unable to reproduce this one. I'm closing the issue now.

talyosha commented 4 years ago

I'm also having the same issue. I transcribed @isaicus solution in this way :

base-components/Form/BaseForm.js:

**onSuccess: function onSuccess(data) {
  this.submiting = false;
  new Promise(resolve => setTimeout(resolve, 3000));

  if (data.redirect) {
    window.location.replace(data.redirect);
  }
}**