whitecube / nova-flexible-content

Flexible Content & Repeater Fields for Laravel Nova
MIT License
787 stars 232 forks source link

flexible method returns the data as JSON string instead of collection in console #77

Open mlanth opened 5 years ago

mlanth commented 5 years ago

Trying to implement the layouts as searchable content with Laravel Scout and am trying to access the accessor to get the collection so that it can be parsed into the searchable array for the model it exists in.

When the models are indexed it only provides back the JSON string when using the accessor.

public function getBlocksAttribute() {
        return $this->flexible('content');
    }

This can be reproduced using Tinker as well where the provider check hits true on accessor access, but false if checked outside.

>>> use App\Page;
>>> $p = Page::find(1)
=> App\Page {#3252
     id: 1,
     title: "Testing",
     slug: "testing",
     content: "[{"layout":"wysiwyg","key":"a7522df387e42e9e","attributes":{"body":"<div>Yeah yeah yeah<\/div>"}}]",
     status: 1,
     created_at: "2019-09-12 17:36:15",
     updated_at: "2019-09-12 18:16:40",
     deleted_at: null,
     created_by: 1,
     updated_by: 1,
     deleted_by: null,
   }
>>> $p->blocks
"app()->getProvider(NovaServiceProvider::class) hit."
=> "[{"layout":"wysiwyg","key":"a7522df387e42e9e","attributes":{"body":"<div>Yeah yeah yeah<\/div>"}}]"
>>> app()->getProvider(NovaServiceProvider::class)
=> null
phlisg commented 4 years ago

Same here.

I commented out the if in this function and I seem to get something as described in docs:

/**
     * Parse a Flexible Content attribute
     *
     * @param string $attribute
     * @param array  $layoutMapping
     * @return Whitecube\NovaFlexibleContent\Layouts\Collection
     */
    public function flexible($attribute, $layoutMapping = [])
    {
        $flexible = $this->attributes[$attribute] ?? null;
        /*
          Why is this needed?
        */
        //if(app()->getProvider(NovaServiceProvider::class)) {
        //    return $flexible;
        //}

        return $this->toFlexible($flexible ?: null, $layoutMapping);
    }

Alternatively, one can use toFlexible($value, array $mapping) in the Model to get to the same result

Elandlord commented 4 years ago

I stumbled upon this problem in one of my PHPUnit tests. @phlisg It is probably needed, because within Nova, they use the JSON string instead of the collection.

Within a normal controller app()->getProvider(NovaServiceProvider::class) // returns null

Within my testing environment app()->getProvider(NovaServiceProvider::class) // returns a bootstrapped NovaServiceProvider

If anyone has any ideas on how to fix this, please let me know.

desaintflorent commented 4 years ago

This was driving me crazy ! My phpUnit test was returning an array instead of a flexible class, but a flexible class in the view... I hope somebody great will send a PR for this :)

In the meantime as @phlisg suggested we can do :

public function getFlexibleContentAttribute()
{
     return $this->toFlexible($this->flexible-content); 
}
wijourdil commented 3 years ago

Same thing here, I have to do like this :

public function getFlexibleContentAttribute($value)
{
     return $this->toFlexible($value); 
}

Is it ok or is it a weird workaround ? 😬 I have the feeling to use the package in a bad way by doing this 🤔