-
-
Notifications
You must be signed in to change notification settings - Fork 229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resolve mediaModel also for classes that extend Layout. #358
Conversation
Hi @dinandmentink, thanks for the PR. However, if your |
Thanks for the response. So this is the full case (code removed where irrelevant). I have an ApplicationLayout which adds some boilerplate that I use in this application for every layout: <?php
namespace App\Nova\Flexible\Layouts;
use App\Nova\Fields;
use App\Services\Blocks as BlocksService;
use DinandMentink\Markdown\Markdown;
use Laravel\Nova\Fields\Select;
use Spatie\MediaLibrary\HasMedia;
use Whitecube\NovaFlexibleContent\Concerns\HasMediaLibrary;
use Whitecube\NovaFlexibleContent\Flexible;
use Whitecube\NovaFlexibleContent\Layouts\Layout;
abstract class ApplicationLayout extends Layout implements HasMedia
{
use HasMediaLibrary;
protected function backgroundField()
{
return Select::make('Achtergrond', 'background')
->options(BlocksService::BACKGROUNDS)
->stacked()
->displayUsingLabels();
}
protected function markdownField()
{
return Markdown::make('Content')
->stacked();
}
} Then I have an <?php
namespace App\Nova\Flexible\Layouts;
use Whitecube\NovaFlexibleContent\Concerns\HasFlexible;
use Whitecube\NovaFlexibleContent\Flexible;
class ImageColumns extends ApplicationLayout
{
use HasFlexible;
/**
* The layout's unique identifier
*
* @var string
*/
protected $name = 'image-columns';
/**
* The displayed title
*
* @var string
*/
protected $title = 'Kolommen met afbeeldingen';
/**
* Get the fields displayed by the layout.
*
* @return array
*/
public function fields()
{
return [
self::backgroundField(),
Flexible::make('Kolommen', 'columns')
->stacked()
->addLayout(ImageColumn::class)
->button('Kolom toevoegen'),
];
}
public function getColumnsAttribute()
{
return $this->flexible(
'columns',
[
'image-column' => ImageColumn::class,
]
);
}
} And then the <?php
namespace App\Nova\Flexible\Layouts;
use Ebess\AdvancedNovaMediaLibrary\Fields\Images;
class ImageColumn extends ApplicationLayout
{
/**
* The layout's unique identifier
*
* @var string
*/
protected $name = 'image-column';
/**
* The displayed title
*
* @var string
*/
protected $title = 'Kolom met afbeelding';
/**
* Get the fields displayed by the layout.
*
* @return array
*/
public function fields()
{
return [
Images::make('Image', 'image-column_image')
->stacked()
->rules(['required']),
self::markdownField(),
];
}
} In this case the Or am I missing something? Post scriptum. I can get it to work by overwriting the getMediaModel() on ApplicationLayout and change the while to either |
After some more consideration. Would it be better to change the pr to something like: while ($model instanceof Layout || is_subclass_of($model, Layout)) |
Ok, but |
Ok. Thanks for the reply. Let me do some more digging to see what I'm missing. Somewhere along the chain I end up with a Layout instance and no medialibrary. Edit. Honestly, I have no idea: >>> $this->model
=> App\Nova\Flexible\Layouts\ImageColumns {#4860
+mediaConversions: [],
+mediaCollections: [],
}
>>> get_parent_class($this->model)
=> "App\Nova\Flexible\Layouts\ApplicationLayout"
>>> get_parent_class(get_parent_class($this->model))
=> "Whitecube\NovaFlexibleContent\Layouts\Layout" But
From my understanding instanceof or is_subclass_of should go multiple levels deep, but now they don't. |
All I can think of is a namespace problem somewhere. It's hard to say from your example: $this->model instanceof Layout; This check would make it clearer: $this->model instanceof Whitecube\NovaFlexibleContent\Layouts\Layout; This is pretty obvious, but as a quick sanity check, I have confirmed that it does work through multiple levels of inheritance. At least with these dummy classes. |
I will retry with the explicitly named class. Probably I am making a mistake somewhere and ending up with a wrong Layout instance. For now we can close this, I'll reply later on if I find something more substantial. Thanks for the reply and the help. |
Lightbulb. I think I found it. Just checking to see if it makes sense. In namespace Whitecube\NovaFlexibleContent\Concerns;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\MediaCollections\MediaRepository;
use Whitecube\NovaFlexibleContent\FileAdder\FileAdder;
use Whitecube\NovaFlexibleContent\FileAdder\FileAdderFactory;
use Whitecube\NovaFlexibleContent\Flexible;
use Spatie\MediaLibrary\Downloaders\DefaultDownloader;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\MediaCollections\Exceptions\InvalidUrl;
use Laravel\Nova\Http\Requests\NovaRequest;
use Laravel\Nova\Nova;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Ebess\AdvancedNovaMediaLibrary\Fields\Media;
use Whitecube\NovaFlexibleContent\Http\ScopedRequest;
trait HasMediaLibrary {
use InteractsWithMedia;
protected function getMediaModel() : HasMedia
{
$model = Flexible::getOriginModel() ?? $this->model;
while ($model instanceof Layout) {
$model = $model->getMediaModel();
}
if(is_null($model) || !($model instanceof HasMedia)) {
throw new \Exception('Origin HasMedia model not found.');
}
return $model;
} There is no I'll reopen the pr with the use statement. |
384851e
to
7d4264e
Compare
This is an edgecase that I came across that is easy to allow. Situation:
ApplicationLayout
class which I use as a base class instead of Layout to add some application specific functionality which I use in my Layout classes.ImageColumns
layout which has a flexible field ofImageColumn
, the image column has anImages::make("image")
field.This does not correctly resolve because
getMediaModel()
checks againsLayout
, notApplicationLayout
. Usingself
fixes this, but also still works for the regular case.