Replace model data access workaround with twigbridge patch

This commit is contained in:
Igor Scheller 2022-06-10 12:31:37 +02:00
parent 078d8516fb
commit 743a79ceea
11 changed files with 417 additions and 137 deletions

View File

@ -22,8 +22,8 @@
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-PDO": "*",
"ext-SimpleXML": "*",
"ext-pdo": "*",
"ext-simplexml": "*",
"ext-xml": "*",
"doctrine/dbal": "^3.2",
"erusev/parsedown": "^1.7",
@ -39,6 +39,7 @@
"psr/container": "^1.1",
"psr/http-server-middleware": "^1.0",
"psr/log": "^1.1",
"rcrowe/twigbridge": "^0.14.0",
"respect/validation": "^1.1",
"symfony/http-foundation": "^5.4",
"symfony/mailer": "^5.4",

413
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5e78f62411dd27e5217899de3d1b22be",
"content-hash": "bdf21b9044a2dbeca7086150547fe74c",
"packages": [
{
"name": "composer/package-versions-deprecated",
@ -1308,6 +1308,59 @@
],
"time": "2022-06-09T08:26:02+00:00"
},
{
"name": "illuminate/bus",
"version": "v8.83.16",
"source": {
"type": "git",
"url": "https://github.com/illuminate/bus.git",
"reference": "d2a8ae4bfd881086e55455e470776358eab27eae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/bus/zipball/d2a8ae4bfd881086e55455e470776358eab27eae",
"reference": "d2a8ae4bfd881086e55455e470776358eab27eae",
"shasum": ""
},
"require": {
"illuminate/collections": "^8.0",
"illuminate/contracts": "^8.0",
"illuminate/pipeline": "^8.0",
"illuminate/support": "^8.0",
"php": "^7.3|^8.0"
},
"suggest": {
"illuminate/queue": "Required to use closures when chaining jobs (^7.0)."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "8.x-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Bus\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Bus package.",
"homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2022-03-07T15:02:42+00:00"
},
{
"name": "illuminate/collections",
"version": "v8.77.1",
@ -1529,6 +1582,123 @@
},
"time": "2021-12-20T15:27:32+00:00"
},
{
"name": "illuminate/events",
"version": "v8.83.16",
"source": {
"type": "git",
"url": "https://github.com/illuminate/events.git",
"reference": "b7f06cafb6c09581617f2ca05d69e9b159e5a35d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/events/zipball/b7f06cafb6c09581617f2ca05d69e9b159e5a35d",
"reference": "b7f06cafb6c09581617f2ca05d69e9b159e5a35d",
"shasum": ""
},
"require": {
"illuminate/bus": "^8.0",
"illuminate/collections": "^8.0",
"illuminate/container": "^8.0",
"illuminate/contracts": "^8.0",
"illuminate/macroable": "^8.0",
"illuminate/support": "^8.0",
"php": "^7.3|^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "8.x-dev"
}
},
"autoload": {
"files": [
"functions.php"
],
"psr-4": {
"Illuminate\\Events\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Events package.",
"homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2021-09-15T14:32:50+00:00"
},
{
"name": "illuminate/filesystem",
"version": "v8.83.16",
"source": {
"type": "git",
"url": "https://github.com/illuminate/filesystem.git",
"reference": "73db3e9a233ed587ba54f52ab8580f3c7bc872b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/filesystem/zipball/73db3e9a233ed587ba54f52ab8580f3c7bc872b2",
"reference": "73db3e9a233ed587ba54f52ab8580f3c7bc872b2",
"shasum": ""
},
"require": {
"illuminate/collections": "^8.0",
"illuminate/contracts": "^8.0",
"illuminate/macroable": "^8.0",
"illuminate/support": "^8.0",
"php": "^7.3|^8.0",
"symfony/finder": "^5.4"
},
"suggest": {
"ext-ftp": "Required to use the Flysystem FTP driver.",
"illuminate/http": "Required for handling uploaded files (^7.0).",
"league/flysystem": "Required to use the Flysystem local and FTP drivers (^1.1).",
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).",
"league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).",
"league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).",
"psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).",
"symfony/filesystem": "Required to enable support for relative symbolic links (^5.4).",
"symfony/mime": "Required to enable support for guessing extensions (^5.4)."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "8.x-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Filesystem\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Filesystem package.",
"homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2022-01-15T15:00:40+00:00"
},
{
"name": "illuminate/macroable",
"version": "v8.77.1",
@ -1575,6 +1745,54 @@
},
"time": "2021-11-16T13:57:03+00:00"
},
{
"name": "illuminate/pipeline",
"version": "v8.83.16",
"source": {
"type": "git",
"url": "https://github.com/illuminate/pipeline.git",
"reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/pipeline/zipball/23aeff5b26ae4aee3f370835c76bd0f4e93f71d2",
"reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2",
"shasum": ""
},
"require": {
"illuminate/contracts": "^8.0",
"illuminate/support": "^8.0",
"php": "^7.3|^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "8.x-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Pipeline\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Pipeline package.",
"homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2021-03-26T18:39:16+00:00"
},
{
"name": "illuminate/support",
"version": "v8.77.1",
@ -1643,6 +1861,60 @@
},
"time": "2021-12-21T14:59:41+00:00"
},
{
"name": "illuminate/view",
"version": "v8.83.16",
"source": {
"type": "git",
"url": "https://github.com/illuminate/view.git",
"reference": "5e73eef48d9242532f81fadc14c816a01bfb1388"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/view/zipball/5e73eef48d9242532f81fadc14c816a01bfb1388",
"reference": "5e73eef48d9242532f81fadc14c816a01bfb1388",
"shasum": ""
},
"require": {
"ext-json": "*",
"illuminate/collections": "^8.0",
"illuminate/container": "^8.0",
"illuminate/contracts": "^8.0",
"illuminate/events": "^8.0",
"illuminate/filesystem": "^8.0",
"illuminate/macroable": "^8.0",
"illuminate/support": "^8.0",
"php": "^7.3|^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "8.x-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\View\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate View package.",
"homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2022-04-14T13:47:10+00:00"
},
{
"name": "league/oauth2-client",
"version": "2.6.1",
@ -2677,6 +2949,82 @@
},
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "rcrowe/twigbridge",
"version": "v0.14.0",
"source": {
"type": "git",
"url": "https://github.com/rcrowe/TwigBridge.git",
"reference": "f4968efb99537cc1b37c5bf20280614aadc31825"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/f4968efb99537cc1b37c5bf20280614aadc31825",
"reference": "f4968efb99537cc1b37c5bf20280614aadc31825",
"shasum": ""
},
"require": {
"illuminate/support": "^6|^7|^8|^9",
"illuminate/view": "^6|^7|^8|^9",
"php": "^7.2.5 || ^8.0",
"twig/twig": "~3.0"
},
"require-dev": {
"ext-json": "*",
"laravel/framework": "^6|^7|^8|^9",
"mockery/mockery": "^1.3.1",
"phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.7",
"squizlabs/php_codesniffer": "^3.6"
},
"suggest": {
"laravelcollective/html": "For bringing back html/form in Laravel 5.x",
"twig/extensions": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.13-dev"
},
"laravel": {
"providers": [
"TwigBridge\\ServiceProvider"
],
"aliases": {
"Twig": "TwigBridge\\Facade\\Twig"
}
}
},
"autoload": {
"psr-4": {
"TwigBridge\\": "src",
"TwigBridge\\Tests\\": "tests"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Rob Crowe",
"email": "hello@vivalacrowe.com"
},
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"description": "Adds the power of Twig to Laravel",
"keywords": [
"laravel",
"twig"
],
"support": {
"issues": "https://github.com/rcrowe/TwigBridge/issues",
"source": "https://github.com/rcrowe/TwigBridge/tree/v0.14.0"
},
"time": "2022-03-08T17:21:17+00:00"
},
{
"name": "respect/validation",
"version": "1.1.31",
@ -3074,6 +3422,69 @@
],
"time": "2021-07-12T14:48:14+00:00"
},
{
"name": "symfony/finder",
"version": "v5.4.8",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
"reference": "9b630f3427f3ebe7cd346c277a1408b00249dad9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/finder/zipball/9b630f3427f3ebe7cd346c277a1408b00249dad9",
"reference": "9b630f3427f3ebe7cd346c277a1408b00249dad9",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1|^3",
"symfony/polyfill-php80": "^1.16"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Finder\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/finder/tree/v5.4.8"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2022-04-15T08:07:45+00:00"
},
{
"name": "symfony/http-foundation",
"version": "v5.4.2",

View File

@ -6,7 +6,6 @@ namespace Engelsystem\Controllers\Admin\Schedule;
use Carbon\Carbon;
use Engelsystem\Controllers\BaseController;
use Engelsystem\Controllers\CleanupModel;
use Engelsystem\Controllers\HasUserNotifications;
use Engelsystem\Helpers\Schedule\Event;
use Engelsystem\Helpers\Schedule\Room;
@ -29,7 +28,6 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface;
class ImportSchedule extends BaseController
{
use CleanupModel;
use HasUserNotifications;
/** @var DatabaseConnection */
@ -104,7 +102,6 @@ class ImportSchedule extends BaseController
public function edit(Request $request): Response
{
$schedule = ScheduleUrl::find($request->getAttribute('id'));
$this->cleanupModelNullValues($schedule);
return $this->response->withView(
'admin/schedule/edit.twig',

View File

@ -3,7 +3,6 @@
namespace Engelsystem\Controllers\Admin;
use Engelsystem\Controllers\BaseController;
use Engelsystem\Controllers\CleanupModel;
use Engelsystem\Controllers\HasUserNotifications;
use Engelsystem\Http\Redirector;
use Engelsystem\Http\Request;
@ -14,7 +13,6 @@ use Psr\Log\LoggerInterface;
class FaqController extends BaseController
{
use HasUserNotifications;
use CleanupModel;
/** @var LoggerInterface */
protected $log;
@ -116,8 +114,6 @@ class FaqController extends BaseController
*/
protected function showEdit(?Faq $faq): Response
{
$this->cleanupModelNullValues($faq);
return $this->response->withView(
'pages/faq/edit.twig',
['faq' => $faq] + $this->getNotifications()

View File

@ -3,7 +3,6 @@
namespace Engelsystem\Controllers\Admin;
use Engelsystem\Controllers\BaseController;
use Engelsystem\Controllers\CleanupModel;
use Engelsystem\Controllers\HasUserNotifications;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Http\Redirector;
@ -15,7 +14,6 @@ use Psr\Log\LoggerInterface;
class NewsController extends BaseController
{
use HasUserNotifications;
use CleanupModel;
/** @var Authenticator */
protected $auth;
@ -80,10 +78,6 @@ class NewsController extends BaseController
*/
protected function showEdit(?News $news, bool $isMeetingDefault = false): Response
{
if ($news) {
$this->cleanupModelNullValues($news);
}
return $this->response->withView(
'pages/news/edit.twig',
[

View File

@ -4,7 +4,6 @@ namespace Engelsystem\Controllers\Admin;
use Carbon\Carbon;
use Engelsystem\Controllers\BaseController;
use Engelsystem\Controllers\CleanupModel;
use Engelsystem\Controllers\HasUserNotifications;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Http\Redirector;
@ -16,7 +15,6 @@ use Psr\Log\LoggerInterface;
class QuestionsController extends BaseController
{
use HasUserNotifications;
use CleanupModel;
/** @var Authenticator */
protected $auth;
@ -69,7 +67,6 @@ class QuestionsController extends BaseController
->orderBy('answered_at')
->orderByDesc('created_at')
->get();
$this->cleanupModelNullValues($questions);
return $this->response->withView(
'pages/questions/overview.twig',
@ -167,8 +164,6 @@ class QuestionsController extends BaseController
*/
protected function showEdit(?Question $question): Response
{
$this->cleanupModelNullValues($question);
return $this->response->withView(
'pages/questions/edit.twig',
['question' => $question, 'is_admin' => true] + $this->getNotifications()

View File

@ -1,38 +0,0 @@
<?php
namespace Engelsystem\Controllers;
use ArrayAccess;
use Illuminate\Database\Eloquent\Model;
trait CleanupModel
{
/**
* Used to replace null values with en empty string
*
* Required because isset on a null value returns false which gets interpreted as missing properties by Twig
*
* @param Model[]|ArrayAccess|Model $models
* @param string[] $attributes
*/
protected function cleanupModelNullValues($models, array $attributes = [])
{
if (!$models) {
return;
}
$models = $models instanceof Model ? [$models] : $models;
foreach ($models as $model) {
/** @var Model $model */
$attributes = $attributes ?: array_merge(
array_keys($model->getAttributes()),
array_keys($model->getCasts()),
$model->getFillable(),
$model->getDates()
);
foreach ($attributes as $attribute) {
$model->$attribute = is_null($model->$attribute) ? '' : $model->$attribute;
}
}
}
}

View File

@ -13,7 +13,6 @@ use Psr\Log\LoggerInterface;
class QuestionsController extends BaseController
{
use HasUserNotifications;
use CleanupModel;
/** @var Authenticator */
protected $auth;
@ -66,7 +65,6 @@ class QuestionsController extends BaseController
->orderByDesc('answered_at')
->orderBy('created_at')
->get();
$this->cleanupModelNullValues($questions);
return $this->response->withView(
'pages/questions/overview.twig',

View File

@ -19,6 +19,7 @@ use Symfony\Component\VarDumper\VarDumper;
use Twig\Environment as Twig;
use Twig\Extension\CoreExtension as TwigCore;
use Twig\Loader\LoaderInterface as TwigLoaderInterface;
use TwigBridge\Extension\Laravel\Model as TwigModel;
class TwigServiceProvider extends ServiceProvider
{
@ -30,6 +31,7 @@ class TwigServiceProvider extends ServiceProvider
'csrf' => Csrf::class,
'develop' => Develop::class,
'globals' => Globals::class,
'twigmodel' => TwigModel::class,
'session' => Session::class,
'legacy' => Legacy::class,
'markdown' => Markdown::class,

View File

@ -1,55 +0,0 @@
<?php
namespace Engelsystem\Test\Unit\Controllers;
use Engelsystem\Test\Unit\Controllers\Stub\CleanupModelImplementation;
use Engelsystem\Test\Unit\Controllers\Stub\TestModel;
use Engelsystem\Test\Unit\HasDatabase;
use Engelsystem\Test\Unit\TestCase;
class CleanupModelTest extends TestCase
{
use HasDatabase;
/**
* @covers \Engelsystem\Controllers\CleanupModel::cleanupModelNullValues
*/
public function testCleanupModelNullValues()
{
$cleanup = new CleanupModelImplementation();
$model = new TestModel();
$model->foo = null;
$model2 = new TestModel();
$model3 = new TestModel();
$model4 = null;
$cleanup->cleanup($model);
$cleanup->cleanup([$model2]);
$cleanup->cleanup($model3, ['text']);
$cleanup->cleanup($model4);
$this->assertTrue(isset($model->text));
$this->assertTrue(isset($model->created_at));
$this->assertTrue(isset($model->foo));
$this->assertEquals('', $model->text);
$this->assertTrue(isset($model2->text));
$this->assertTrue(isset($model3->text));
$this->assertNull($model3->another_text);
$this->assertNull($model3->foo);
$this->assertNull($model4);
}
/**
* Setup the DB
*/
public function setUp(): void
{
parent::setUp();
$this->initDatabase();
}
}

View File

@ -1,21 +0,0 @@
<?php
namespace Engelsystem\Test\Unit\Controllers\Stub;
use ArrayAccess;
use Engelsystem\Controllers\CleanupModel;
use Illuminate\Database\Eloquent\Model;
class CleanupModelImplementation
{
use CleanupModel;
/**
* @param Model|ArrayAccess|Model[] $model
* @param array $attributes
*/
public function cleanup($model, array $attributes = []): void
{
$this->cleanupModelNullValues($model, $attributes);
}
}