From 9ba432e197c22d299217fbe168e9c6600a60bd7f Mon Sep 17 00:00:00 2001 From: Samuel Georges Date: Tue, 10 Dec 2024 14:30:25 +1100 Subject: [PATCH 1/5] Move custom redirector to core This was previously found in the User plugin and is a black box; nearly impossible to find from the `Redirect` facade, the `october\rain` library should provide an interface to change the key name, that is, if Laravel doesn't add this common feature in a later version --- src/Foundation/Application.php | 4 +- src/Router/CoreRedirector.php | 54 +++++++++++++++++++++++++++ src/Router/RoutingServiceProvider.php | 19 ++++++++++ 3 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 src/Router/CoreRedirector.php diff --git a/src/Foundation/Application.php b/src/Foundation/Application.php index b7c8fafa7..073262b3e 100644 --- a/src/Foundation/Application.php +++ b/src/Foundation/Application.php @@ -327,7 +327,7 @@ public function registerCoreContainerAliases() 'cache.psr6' => [\Symfony\Component\Cache\Adapter\Psr16Adapter::class, \Symfony\Component\Cache\Adapter\AdapterInterface::class, \Psr\Cache\CacheItemPoolInterface::class], 'config' => [\Illuminate\Config\Repository::class, \Illuminate\Contracts\Config\Repository::class], 'cookie' => [\Illuminate\Cookie\CookieJar::class, \Illuminate\Contracts\Cookie\Factory::class, \Illuminate\Contracts\Cookie\QueueingFactory::class], - 'db' => [\October\Rain\Database\DatabaseManager::class], + 'db' => [\Illuminate\Database\DatabaseManager::class], 'db.connection' => [\Illuminate\Database\Connection::class, \Illuminate\Database\ConnectionInterface::class], 'db.schema' => [\Illuminate\Database\Schema\Builder::class], 'encrypter' => [\Illuminate\Encryption\Encrypter::class, \Illuminate\Contracts\Encryption\Encrypter::class], @@ -347,7 +347,7 @@ public function registerCoreContainerAliases() 'queue' => [\Illuminate\Queue\QueueManager::class, \Illuminate\Contracts\Queue\Factory::class, \Illuminate\Contracts\Queue\Monitor::class], 'queue.connection' => [\Illuminate\Contracts\Queue\Queue::class], 'queue.failer' => [\Illuminate\Queue\Failed\FailedJobProviderInterface::class], - 'redirect' => [\Illuminate\Routing\Redirector::class], + 'redirect' => [\October\Rain\Router\CoreRedirector::class], 'redis' => [\Illuminate\Redis\RedisManager::class, \Illuminate\Contracts\Redis\Factory::class], 'redis.connection' => [\Illuminate\Redis\Connections\Connection::class, \Illuminate\Contracts\Redis\Connection::class], 'request' => [\Illuminate\Http\Request::class, \Symfony\Component\HttpFoundation\Request::class], diff --git a/src/Router/CoreRedirector.php b/src/Router/CoreRedirector.php new file mode 100644 index 000000000..d43a43324 --- /dev/null +++ b/src/Router/CoreRedirector.php @@ -0,0 +1,54 @@ +session->pull('url.cms.intended', $default); + + return $this->to($path, $status, $headers, $secure); + } + + /** + * getIntendedUrl from the session. + */ + public function getIntendedUrl() + { + if (!App::runningInFrontend()) { + return parent::getIntendedUrl(); + } + + return $this->session->get('url.cms.intended'); + } + + /** + * setIntendedUrl in the session. + */ + public function setIntendedUrl($url) + { + if (!App::runningInFrontend()) { + return parent::setIntendedUrl($url); + } + + $this->session->put('url.cms.intended', $url); + return $this; + } +} diff --git a/src/Router/RoutingServiceProvider.php b/src/Router/RoutingServiceProvider.php index 80a5630b8..bb60049ad 100644 --- a/src/Router/RoutingServiceProvider.php +++ b/src/Router/RoutingServiceProvider.php @@ -45,4 +45,23 @@ protected function registerRouter() return new CoreRouter($app['events'], $app); }); } + + /** + * registerRedirector + */ + protected function registerRedirector() + { + $this->app->singleton('redirect', function ($app) { + $redirector = new CoreRedirector($app['url']); + + // If the session is set on the application instance, we'll inject it into + // the redirector instance. This allows the redirect responses to allow + // for the quite convenient "with" methods that flash to the session. + if (isset($app['session.store'])) { + $redirector->setSession($app['session.store']); + } + + return $redirector; + }); + } } From 0f7f220669365b131f7db9b45974a399477845ee Mon Sep 17 00:00:00 2001 From: Samuel Georges Date: Sun, 5 Jan 2025 09:04:38 +1100 Subject: [PATCH 2/5] Allow custom presence verifier in model validation --- src/Database/Traits/Validation.php | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/Database/Traits/Validation.php b/src/Database/Traits/Validation.php index cdc68ecb8..08169e53a 100644 --- a/src/Database/Traits/Validation.php +++ b/src/Database/Traits/Validation.php @@ -250,19 +250,38 @@ protected function getRelationValidationValue($relationName) * the validator use a different database connection than the default connection. * @return \Illuminate\Validation\Validator */ - protected static function makeValidator($data, $rules, $customMessages, $attributeNames, $connection = null) + protected static function makeValidator($data, $rules, $customMessages, $attributeNames, $connection = null, $verifier = null) { - $validator = Validator::make($data, $rules, $customMessages, $attributeNames); + // @deprecated make required arg (v4) desired signature below + // makeValidator($data, $rules, $customMessages, $attributeNames, $verifier) + // + if ($verifier === null) { + $verifier = App::make('validation.presence'); + } + // @deprecated set via getValidationPresenceVerifier (v4) if ($connection !== null) { - $verifier = App::make('validation.presence'); $verifier->setConnection($connection); - $validator->setPresenceVerifier($verifier); } + $validator = Validator::make($data, $rules, $customMessages, $attributeNames); + $validator->setPresenceVerifier($verifier); + return $validator; } + /** + * getValidationPresenceVerifier + */ + protected function getValidationPresenceVerifier() + { + $verifier = App::make('validation.presence'); + + $verifier->setConnection($this->getConnectionName()); + + return $verifier; + } + /** * forceSave the model even if validation fails * @return bool @@ -394,7 +413,8 @@ public function validate($rules = null, $customMessages = null, $attributeNames $rules, $customMessages, $attrNames, - $this->getConnectionName() + $this->getConnectionName(), + $this->getValidationPresenceVerifier() ); $success = $validator->passes(); From 62b3c45a1c1ca7bdaa392694ee64b04200dae608 Mon Sep 17 00:00:00 2001 From: Samuel Georges Date: Sun, 5 Jan 2025 10:50:30 +1100 Subject: [PATCH 3/5] Expand belongsToMany scope --- src/Database/Concerns/HasRelationships.php | 2 +- src/Database/Traits/Multisite.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Database/Concerns/HasRelationships.php b/src/Database/Concerns/HasRelationships.php index 60222b248..9f12479f4 100644 --- a/src/Database/Concerns/HasRelationships.php +++ b/src/Database/Concerns/HasRelationships.php @@ -904,7 +904,7 @@ protected function performDeleteOnRelations() } // Belongs-To-Many should clean up after itself by default - if ($type === 'belongsToMany') { + if (in_array($type, ['belongsToMany', 'morphToMany', 'morphedByMany'])) { if (!Arr::get($options, 'detach', true)) { return; } diff --git a/src/Database/Traits/Multisite.php b/src/Database/Traits/Multisite.php index 944e715e4..313f968f6 100644 --- a/src/Database/Traits/Multisite.php +++ b/src/Database/Traits/Multisite.php @@ -177,7 +177,7 @@ public function canDeleteMultisiteRelation($name, $type = null): bool $type = $this->getRelationType($name); } - if (!in_array($type, ['belongsToMany', 'morphedByMany', 'belongsTo', 'hasOne', 'hasMany', 'attachOne', 'attachMany'])) { + if (!in_array($type, ['belongsToMany', 'morphToMany', 'morphedByMany', 'belongsTo', 'hasOne', 'hasMany', 'attachOne', 'attachMany'])) { return false; } From e8aca81cb72ecfa625f9ef3c26234e6190490749 Mon Sep 17 00:00:00 2001 From: Samuel Georges Date: Sun, 5 Jan 2025 10:55:13 +1100 Subject: [PATCH 4/5] Fixes morphToMany support The inverse switch of morphToMany appears to be handled internally by the relation object (inverse flag) --- src/Database/Traits/Multisite.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Database/Traits/Multisite.php b/src/Database/Traits/Multisite.php index 313f968f6..e3baa40a8 100644 --- a/src/Database/Traits/Multisite.php +++ b/src/Database/Traits/Multisite.php @@ -188,7 +188,7 @@ public function canDeleteMultisiteRelation($name, $type = null): bool /** * defineMultisiteRelation will modify defined relations on this model so they share * their association using the shared identifier (`site_root_id`). Only these relation - * types support relation sharing: `belongsToMany`, `morphedByMany`, + * types support relation sharing: `belongsToMany`, `morphToMany`, `morphedByMany`, * `belongsTo`, `hasOne`, `hasMany`, `attachOne`, `attachMany`. */ protected function defineMultisiteRelation($name, $type = null) @@ -203,7 +203,7 @@ protected function defineMultisiteRelation($name, $type = null) } // Override the local key to the shared root identifier - if (in_array($type, ['belongsToMany', 'morphedByMany'])) { + if (in_array($type, ['belongsToMany', 'morphToMany', 'morphedByMany'])) { $this->$type[$name]['parentKey'] = 'site_root_id'; } elseif (in_array($type, ['belongsTo', 'hasOne', 'hasMany'])) { From 4b34ed4508b0f82137dd045c15e6c0d25d64166b Mon Sep 17 00:00:00 2001 From: Samuel Georges Date: Sun, 5 Jan 2025 11:04:42 +1100 Subject: [PATCH 5/5] Fixes logic error preventing multisite relation cleanup --- src/Database/Traits/Multisite.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Database/Traits/Multisite.php b/src/Database/Traits/Multisite.php index e3baa40a8..1fb31edb5 100644 --- a/src/Database/Traits/Multisite.php +++ b/src/Database/Traits/Multisite.php @@ -169,16 +169,18 @@ protected function defineMultisiteRelations() */ public function canDeleteMultisiteRelation($name, $type = null): bool { + // Attribute is exclusive to parent model without propagation if (!$this->isAttributePropagatable($name)) { - return false; + return true; } if ($type === null) { $type = $this->getRelationType($name); } + // Type is not supported by multisite if (!in_array($type, ['belongsToMany', 'morphToMany', 'morphedByMany', 'belongsTo', 'hasOne', 'hasMany', 'attachOne', 'attachMany'])) { - return false; + return true; } // The current record counts for one so halt if we find more