Skip to content

Commit

Permalink
Merge branch '3.x' into fix/slug-active-column
Browse files Browse the repository at this point in the history
  • Loading branch information
ifox authored Oct 14, 2024
2 parents 57611d2 + cc26b32 commit 57c38b2
Show file tree
Hide file tree
Showing 21 changed files with 289 additions and 198 deletions.
2 changes: 1 addition & 1 deletion UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ If you are relying on Quill.js specifics (like css classes), use `'type' => 'qui
Previously `withVideo` was true by default, if you relied on this you have to update these media fields to
`'withVideo' => true`.

#### SVG's are now no longer passing thorough glide
#### SVG's are now no longer passing through glide

These are now rendered directly, you can change this by updating config `twill.glide.original_media_for_extensions` to an empty array `[]`

Expand Down
2 changes: 1 addition & 1 deletion config/twill.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

/*
|--------------------------------------------------------------------------
| Application strict url handeling
| Application strict url handling
|--------------------------------------------------------------------------
|
| Setting this value to true will enable strict domain handling.
Expand Down
25 changes: 0 additions & 25 deletions docs/content/1_docs/2_getting-started/3_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,31 +79,6 @@ return [
];
```

Twill registers its own exception handler in all controllers. If you need to customize it (to report errors on a 3rd party service like Sentry or Rollbar for example), you can opt-out from it in your `config/twill.php` file:

```php
<?php

return [
'bind_exception_handler' => false,
];
```

And then extend it from your own `app/Exceptions/Handler.php` class:

```php
<?php

namespace App\Exceptions;

use A17\Twill\Exceptions\Handler as ExceptionHandler;
use Exception;
use Illuminate\Auth\AuthenticationException;

class Handler extends ExceptionHandler
...
```

If you would like to provide custom tables names, use the following configuration options:

```php
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ return [
```

Now with this in place, you can go back to the block editor and add your first image block! But just as before, we have
to update the content of the preview file (`resources/views/site/blocks/text.blade.php`) so that we actually display
to update the content of the preview file (`resources/views/site/blocks/image.blade.php`) so that we actually display
the image!

```blade
Expand Down
45 changes: 5 additions & 40 deletions src/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,16 @@

namespace A17\Twill\Exceptions;

use Illuminate\Contracts\Container\Container;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

/** @deprecated It is not needed anymore and will be removed in v4 */
class Handler extends ExceptionHandler
{
/**
* Get the view used to render HTTP exceptions.
*
* @return string
*/
protected function getHttpExceptionView(HttpExceptionInterface $e)
public function __construct(Container $container)
{
$usesAdminPath = !empty(config('twill.admin_app_path'));
$adminAppUrl = config('twill.admin_app_url', config('app.url'));
parent::__construct($container);

$isSubdomainAdmin = !$usesAdminPath && Str::contains(Request::url(), $adminAppUrl);
$isSubdirectoryAdmin = $usesAdminPath && Str::startsWith(Request::path(), config('twill.admin_app_path'));

return $this->getTwillErrorView($e->getStatusCode(), !$isSubdomainAdmin && !$isSubdirectoryAdmin);
}

/**
* Get the Twill error view used to render a specified HTTP status code.
*
* @param integer $statusCode
* @return string
*/
protected function getTwillErrorView($statusCode, $frontend = false)
{
if ($frontend) {
$view = config('twill.frontend.views_path') . ".errors.$statusCode";

return view()->exists($view) ? $view : "errors::{$statusCode}";
}

$view = "twill.errors.$statusCode";

return view()->exists($view) ? $view : "twill::errors.$statusCode";
}

protected function invalidJson($request, ValidationException $exception)
{
return response()->json($exception->errors(), $exception->status);
trigger_deprecation('area17/twill', '3.4', 'The Twill Exception handler is deprecated and will be removed in v4, go back to extending the laravel ExceptionHandler');
}
}
11 changes: 11 additions & 0 deletions src/Helpers/BlockRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Exception;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Str;

/**
Expand Down Expand Up @@ -119,6 +120,16 @@ private static function getNestedBlocksForData(

$block->setRelation('children', self::getChildren($children));

foreach ($data['browsers'] as $browserName => $browserItems) {
$browserData = collect();
foreach ($browserItems as $browserItem) {
$className = Relation::getMorphedModel($browserItem['endpointType']) ?? $browserItem['endpointType'];
$browserData->push((new $className())->find($browserItem['id']));
}

$block->setRelatedCache($browserName, $browserData);
}

$block->medias = self::getMedias($data);

$class->setRenderData(
Expand Down
3 changes: 0 additions & 3 deletions src/Http/Controllers/Admin/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ class Controller extends BaseController

public function __construct()
{
if (Config::get('twill.bind_exception_handler', true)) {
App::singleton(ExceptionHandler::class, TwillHandler::class);
}
}

/**
Expand Down
43 changes: 32 additions & 11 deletions src/Http/Controllers/Admin/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Contracts\Auth\Factory as AuthFactory;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
Expand Down Expand Up @@ -120,7 +121,11 @@ public function search(Request $request): Collection
})->map(function ($module) use ($request) {
$repository = $this->getRepository($module['name'], $module['repository'] ?? null);

$found = $repository->cmsSearch($request->get('search'), $module['search_fields'] ?? ['title'])->take(10);
$found = $repository->cmsSearch(
$request->get('search'),
$module['search_fields'] ?? ['title'],
isset($module['parentRelationship']) ? fn($q) => $q->whereHas($module['parentRelationship']) : null
)->take(10);

return $found->map(function ($item) use ($module) {
try {
Expand All @@ -136,16 +141,19 @@ public function search(Request $request): Collection
$date = $item->created_at->toIso8601String();
}

$parentRelationship = $module['parentRelationship'] ?? null;
$parent = $item->$parentRelationship;
if (isset($module['parentRelationship'])) {
/** @var BelongsTo $parent */
$parent = call_user_func([$item, $module['parentRelationship']]);
$parent_id = $parent->getParentKey();
}

return [
'id' => $item->id,
'href' => moduleRoute(
$module['name'],
$module['routePrefix'] ?? null,
'edit',
array_merge($parentRelationship ? [$parent->id] : [], [$item->id])
array_filter([$parent_id ?? null, $item->id])
),
'thumbnail' => method_exists($item, 'defaultCmsImage') ? $item->defaultCmsImage(['w' => 100, 'h' => 100]) : null,
'published' => $item->published,
Expand Down Expand Up @@ -251,8 +259,16 @@ private function formatActivity(Activity $activity): ?array
return null;
}

$parentRelationship = $dashboardModule['parentRelationship'] ?? null;
$parent = $activity->subject->$parentRelationship;
if (isset($dashboardModule['parentRelationship'])) {
/** @var BelongsTo $parent */
$parent = call_user_func([$activity->subject, $dashboardModule['parentRelationship']]);
$parent_id = $parent->getParentKey();

if (empty($parent_id)) {
// Prevent module route error
return null;
}
}

// @todo: Improve readability of what is happening here.
return [
Expand All @@ -269,7 +285,7 @@ private function formatActivity(Activity $activity): ?array
$dashboardModule['name'],
$dashboardModule['routePrefix'] ?? null,
'edit',
array_merge($parentRelationship ? [$parent->id] : [], [$activity->subject_id])
array_filter([$parent_id ?? null, $activity->subject_id])
),
] : []) + (! is_null($activity->subject->published) ? [
'published' => $activity->description === 'published' ? true : ($activity->description === 'unpublished' ? false : $activity->subject->published),
Expand Down Expand Up @@ -554,10 +570,15 @@ private function getDrafts(Collection $modules): Collection
if ($repository->hasBehavior('revisions')) {
$query->mine();
}
$parentRelationship = $module['parentRelationship'] ?? null;

return $query->get()->map(function ($draft) use ($module, $parentRelationship) {
$parent = $draft->$parentRelationship;
if (isset($module['parentRelationship'])) {
$query->whereHas($module['parentRelationship']);
}

return $query->get()->map(function ($draft) use ($module) {
if (isset($module['parentRelationship'])) {
$parent_id = call_user_func([$draft, $module['parentRelationship']])->getParentKey();
}

return [
'type' => ucfirst($module['label_singular'] ?? Str::singular($module['name'])),
Expand All @@ -566,7 +587,7 @@ private function getDrafts(Collection $modules): Collection
$module['name'],
$module['routePrefix'] ?? null,
'edit',
array_merge($parentRelationship ? [$parent->id] : [], [$draft->id])
array_filter([$parent_id ?? null, $draft->id])
)
];
});
Expand Down
14 changes: 7 additions & 7 deletions src/Http/Controllers/Admin/ModuleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -1200,6 +1200,7 @@ public function edit(TwillModelContract|int $id): mixed
$this->setBackLink();

$controllerForm = $this->getForm($item);
$controllerForm->registerDynamicRepeaters();

if ($controllerForm->hasForm()) {
$view = 'twill::layouts.form';
Expand All @@ -1221,8 +1222,11 @@ public function edit(TwillModelContract|int $id): mixed
}
}

return View::make($view, $this->form($id))->with(
['formBuilder' => $controllerForm->toFrontend($this->getSideFieldsets($item))]
$sideFieldsets = $this->getSideFieldsets($item);
$sideFieldsets->registerDynamicRepeaters();

return View::make($view, $this->form($id, $item))->with(
['formBuilder' => $controllerForm->toFrontend($sideFieldsets)]
);
}

Expand Down Expand Up @@ -1255,8 +1259,6 @@ public function create(int $parentModuleId = null): JsonResponse|RedirectRespons
return View::exists($view);
});

View::share('form', $this->form(null));

return View::make($view, $this->form(null))->with(
['formBuilder' => $controllerForm->toFrontend($this->getSideFieldsets($emptyModelInstance), true)]
);
Expand Down Expand Up @@ -1381,7 +1383,7 @@ public function preview(int $id): IlluminateView

/**
* @param int $id
* @return \Illuminate\View\View
* @return \Illuminate\Contracts\View\View
*/
public function restoreRevision($id)
{
Expand Down Expand Up @@ -1417,8 +1419,6 @@ public function restoreRevision($id)
);
}

View::share('form', $this->form($id, $item));

return View::make($view, $this->form($id, $item))->with(
['formBuilder' => $controllerForm->toFrontend($this->getSideFieldsets($item))]
);
Expand Down
4 changes: 0 additions & 4 deletions src/Http/Controllers/Front/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ class Controller extends BaseController

public function __construct()
{
if (Config::get('twill.bind_exception_handler', true)) {
App::singleton(ExceptionHandler::class, TwillHandler::class);
}

$this->seo = new Seo();

$this->seo->title = Config::get('twill.seo.site_title');
Expand Down
31 changes: 22 additions & 9 deletions src/Models/Behaviors/HasRelated.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

namespace A17\Twill\Models\Behaviors;

use A17\Twill\Models\Contracts\TwillModelContract;
use A17\Twill\Models\RelatedItem;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;

trait HasRelated
Expand Down Expand Up @@ -52,6 +51,7 @@ public function loadRelated(string $browserName): Collection
/** @var \A17\Twill\Models\Model $model */
if ($model = $item->related) {
$model->setRelation('pivot', $item);
$item->unsetRelation('related');

return $model;
}
Expand All @@ -63,18 +63,26 @@ public function loadRelated(string $browserName): Collection
/**
* Attach items to the model for a browser field.
*
* @param array<int, TwillModelContract> $items
* @param array<int, Model|array> $items
*/
public function saveRelated(array|Collection $items, string $browserName): void
public function saveRelated(array|Collection|Model $items, string $browserName): void
{
$items = is_array($items) || $items instanceof Collection ? $items : [$items];

/** @var Collection<int, RelatedItem> $itemsToProcess */
$itemsToProcess = $this->relatedItems()->where('browser_name', $browserName)->get();

foreach ($items as $position => $item) {
if ($item instanceof Model) {
$id = $item->getKey();
$type = $item->getMorphClass();
} else {
$id = $item['id'];
$type = $item['endpointType'];
}

$firstMatchKey = $itemsToProcess
->where('related_id', $item['id'])
->where('related_type', $item['endpointType'])
->where('browser_name', $browserName)
->where(fn (RelatedItem $item) => $item->related_id == $id && $item->related_type === $type)
// We should only have one item always as you cannot select the same items twice.
->keys()
->first();
Expand All @@ -90,8 +98,8 @@ public function saveRelated(array|Collection $items, string $browserName): void
RelatedItem::create([
'subject_id' => $this->getKey(),
'subject_type' => $this->getMorphClass(),
'related_id' => $item['id'],
'related_type' => $item['endpointType'],
'related_id' => $id,
'related_type' => $type,
'browser_name' => $browserName,
'position' => $position + 1,
]);
Expand All @@ -117,4 +125,9 @@ public function clearAllRelated(): void
{
$this->relatedItems()->delete();
}

public function setRelatedCache($browser, $items): void
{
$this->relatedCache[$browser] = $items;
}
}
Loading

0 comments on commit 57c38b2

Please sign in to comment.