outl1ne / nova-page-manager

Static page and region manager for Laravel Nova - designed for headless CMS's.
MIT License
178 stars 38 forks source link

Problems with uploading files #123

Closed matthijssm closed 1 year ago

matthijssm commented 2 years ago

Hi,

First of all, thank you for this great package! I have an issue with uploading files from version 5.1+. Whenever I try to upload something in an image field or the SEO image I get a success notification but the files have not been upload nor been changed in the database. I found that 5.0.8 is the latest version where everything works correctly. But that version does not support the flexible-content package.

I tried installing this package into a new empty project but I got the same issue.

matthijssm commented 2 years ago

Thanks @KasparRosin for this fix. This does indeed fix the issue with the SEO image. However when I use an Image field it still does not upload. Also I found that the validation rules do not work with this package.

KasparRosin commented 2 years ago

@matthijssm Hei

However when I use an Image field it still does not upload.

Do you mean within the page fields? Can you share a quick snippet of the code.

1stevengrant commented 1 year ago

I'm noticing this too @matthijssm @KasparRosin

I've introduced a VaporImage field

Text::make('SEO Title'),
            Textarea::make('SEO Description'),
            VaporImage::make('SEO Image')
                ->help('This should be high res. so that we can manipulate size etc throughout the app')
                ->path('seo_images')
                ->thumbnail(function ($value) {
                    return $value
                        ? novaThumbnail($value)
                        : null;
                })
                ->storeAs(function ($request) {
                    $img = $request->input('vaporFile')['seo_image'];

                    return str_replace('tmp/', '', $img['key']) . '.' . $img['extension'];
                }),

this is in the context of a region

KasparRosin commented 1 year ago

Hey! We would appreciates pull requests on this matter. Since our go to media library is our own outl1ne/nova-media-hub, it might take some time until we get around to fix the issues related to nova's image field or other third-party image fields.

1stevengrant commented 1 year ago

Hey!

We would appreciates pull requests on this matter.

Since our go to media library is our own outl1ne/nova-media-hub, it might take some time until we get around to fix the issues related to nova's image field or other third-party image fields.

Nice- does that work on Vapor?

KasparRosin commented 1 year ago

@1stevengrant, hard to say. I'm not that familiar with vapor. Essentially how nova-media-hub works, is that it has a table, where it saves all the file related information. Now when you select an image to use, it will only store that image's id the data column of page-manager.

ferdiunal commented 1 year ago

Hi, if you update the fillFields method with the following for the VaporImage field upload problem, the problem will be fixed.

    protected function fillFields($request, $attributeKey, $baseFields, $model)
    {
        $flexibleAttrRegKey = $this->getFlexibleAttributeRegisterKey();

        $locales = ['__', ...array_keys(NPM::getLocales())];
        $body = $request->get($attributeKey, []);
        $files = $request->files->get($attributeKey, []);
        $data = array_merge_recursive($body, $files);

        foreach ($locales as $locale) {
            $dataAttributes = [];
            $fileAttributes = [];
            $localeData = $data[$locale] ?? [];

            $flexibleKeys = null;
            if ($flexibleAttrRegKey && isset($localeData[$flexibleAttrRegKey])) {
                $flexibleKeys = json_decode($localeData[$flexibleAttrRegKey], true);
                $localeData[$flexibleAttrRegKey] = $flexibleKeys;
            }

            foreach ($localeData as $k => $v) {
                $fullKey = "{$attributeKey}->{$locale}->{$k}";

                if ($v instanceof UploadedFile) {
                    $fileAttributes[$fullKey] = $v;
                } else if ($k === "vaporFile" && is_array($v)) { // The update is here.
                    foreach ($v as $n => $f) {
                        $fullKey = "{$attributeKey}->{$locale}->{$n}";
                        $dataAttributes["vaporFile"] = [$fullKey => $f];
                    }
                } else if ($flexibleKeys) {
                    if ($k === $flexibleAttrRegKey) {
                        // Modify flexible registration keys
                        $dataAttributes[$fullKey] = array_map(fn ($fKey) => "{$attributeKey}->{$locale}->{$fKey}", $flexibleKeys);
                    } else if (in_array($k, $flexibleKeys)) {
                        // Decode flexible values
                        $dataAttributes[$fullKey] = $this->getFlexibleCompatibleValue($v);
                    } else {
                        $dataAttributes[$fullKey] = $v;
                    }
                } else {
                    $dataAttributes[$fullKey] = $v;
                }
            }

            $fakeRequest = new NovaRequest([], $dataAttributes, [], [], $fileAttributes);
            $fakeRequest->headers = new HeaderBag(['Content-Type' => 'multipart/form-data']);
            $fakeRequest->setMethod(NovaRequest::METHOD_POST);

            $fields = $baseFields->map(fn ($field) => $this->transformFieldAttributes($field, "{$attributeKey}->{$locale}"));
            $fields->resolve((object) array_merge($dataAttributes, $fileAttributes));
            $fields->map->fill($fakeRequest, $model);
        }
    }
Tarpsvo commented 1 year ago

@ferdiunal's PR went live in 5.9.0! :) Thanks a ton!