@yield('message')
8889841cREADME.md 0000644 00000006414 15052151126 0006026 0 ustar 00
## About Laravel > **Note:** This repository contains the core code of the Laravel framework. If you want to build an application using Laravel, visit the main [Laravel repository](https://github.com/laravel/laravel). Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as: - [Simple, fast routing engine](https://laravel.com/docs/routing). - [Powerful dependency injection container](https://laravel.com/docs/container). - Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage. - Database agnostic [schema migrations](https://laravel.com/docs/migrations). - [Robust background job processing](https://laravel.com/docs/queues). - [Real-time event broadcasting](https://laravel.com/docs/broadcasting). Laravel is accessible, yet powerful, providing tools needed for large, robust applications. A superb combination of simplicity, elegance, and innovation gives you a complete toolset required to build any application with which you are tasked. ## Learning Laravel Laravel has the most extensive and thorough documentation and video tutorial library of any modern web application framework. The [Laravel documentation](https://laravel.com/docs) is in-depth and complete, making it a breeze to get started learning the framework. If you're not in the mood to read, [Laracasts](https://laracasts.com) contains over 1100 video tutorials covering a range of topics including Laravel, modern PHP, unit testing, JavaScript, and more. Boost the skill level of yourself and your entire team by digging into our comprehensive video library. ## Contributing Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions). ## Code of Conduct In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct). ## Security Vulnerabilities Please review [our security policy](https://github.com/laravel/framework/security/policy) on how to report security vulnerabilities. ## License The Laravel framework is open-sourced software licensed under the [MIT license](LICENSE.md). LICENSE.md 0000644 00000002063 15052151126 0006147 0 ustar 00 The MIT License (MIT) Copyright (c) Taylor Otwell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. src/Illuminate/Events/LICENSE.md 0000644 00000002063 15052151126 0012305 0 ustar 00 The MIT License (MIT) Copyright (c) Taylor Otwell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. src/Illuminate/Events/QueuedClosure.php 0000644 00000005223 15052151126 0014200 0 ustar 00 closure = $closure; } /** * Set the desired connection for the job. * * @param string|null $connection * @return $this */ public function onConnection($connection) { $this->connection = $connection; return $this; } /** * Set the desired queue for the job. * * @param string|null $queue * @return $this */ public function onQueue($queue) { $this->queue = $queue; return $this; } /** * Set the desired delay for the job. * * @param \DateTimeInterface|\DateInterval|int|null $delay * @return $this */ public function delay($delay) { $this->delay = $delay; return $this; } /** * Specify a callback that should be invoked if the queued listener job fails. * * @param \Closure $closure * @return $this */ public function catch(Closure $closure) { $this->catchCallbacks[] = $closure; return $this; } /** * Resolve the actual event listener callback. * * @return \Closure */ public function resolve() { return function (...$arguments) { dispatch(new CallQueuedListener(InvokeQueuedClosure::class, 'handle', [ 'closure' => SerializableClosureFactory::make($this->closure), 'arguments' => $arguments, 'catch' => collect($this->catchCallbacks)->map(function ($callback) { return SerializableClosureFactory::make($callback); })->all(), ]))->onConnection($this->connection)->onQueue($this->queue)->delay($this->delay); }; } } src/Illuminate/Events/EventServiceProvider.php 0000644 00000001054 15052151126 0015526 0 ustar 00 app->singleton('events', function ($app) { return (new Dispatcher($app))->setQueueResolver(function () use ($app) { return $app->make(QueueFactoryContract::class); }); }); } } src/Illuminate/Events/InvokeQueuedClosure.php 0000644 00000001477 15052151126 0015363 0 ustar 00 getClosure(), ...$arguments); } /** * Handle a job failure. * * @param \Laravel\SerializableClosure\SerializableClosure $closure * @param array $arguments * @param array $catchCallbacks * @param \Throwable $exception * @return void */ public function failed($closure, array $arguments, array $catchCallbacks, $exception) { $arguments[] = $exception; collect($catchCallbacks)->each->__invoke(...$arguments); } } src/Illuminate/Events/composer.json 0000644 00000002012 15052151126 0013415 0 ustar 00 { "name": "illuminate/events", "description": "The Illuminate Events package.", "license": "MIT", "homepage": "https://laravel.com", "support": { "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, "authors": [ { "name": "Taylor Otwell", "email": "taylor@laravel.com" } ], "require": { "php": "^7.3|^8.0", "illuminate/bus": "^8.0", "illuminate/collections": "^8.0", "illuminate/container": "^8.0", "illuminate/contracts": "^8.0", "illuminate/macroable": "^8.0", "illuminate/support": "^8.0" }, "autoload": { "psr-4": { "Illuminate\\Events\\": "" }, "files": [ "functions.php" ] }, "extra": { "branch-alias": { "dev-master": "8.x-dev" } }, "config": { "sort-packages": true }, "minimum-stability": "dev" } src/Illuminate/Events/Dispatcher.php 0000644 00000045273 15052151126 0013512 0 ustar 00 container = $container ?: new Container; } /** * Register an event listener with the dispatcher. * * @param \Closure|string|array $events * @param \Closure|string|array|null $listener * @return void */ public function listen($events, $listener = null) { if ($events instanceof Closure) { return collect($this->firstClosureParameterTypes($events)) ->each(function ($event) use ($events) { $this->listen($event, $events); }); } elseif ($events instanceof QueuedClosure) { return collect($this->firstClosureParameterTypes($events->closure)) ->each(function ($event) use ($events) { $this->listen($event, $events->resolve()); }); } elseif ($listener instanceof QueuedClosure) { $listener = $listener->resolve(); } foreach ((array) $events as $event) { if (Str::contains($event, '*')) { $this->setupWildcardListen($event, $listener); } else { $this->listeners[$event][] = $this->makeListener($listener); } } } /** * Setup a wildcard listener callback. * * @param string $event * @param \Closure|string $listener * @return void */ protected function setupWildcardListen($event, $listener) { $this->wildcards[$event][] = $this->makeListener($listener, true); $this->wildcardsCache = []; } /** * Determine if a given event has listeners. * * @param string $eventName * @return bool */ public function hasListeners($eventName) { return isset($this->listeners[$eventName]) || isset($this->wildcards[$eventName]) || $this->hasWildcardListeners($eventName); } /** * Determine if the given event has any wildcard listeners. * * @param string $eventName * @return bool */ public function hasWildcardListeners($eventName) { foreach ($this->wildcards as $key => $listeners) { if (Str::is($key, $eventName)) { return true; } } return false; } /** * Register an event and payload to be fired later. * * @param string $event * @param array $payload * @return void */ public function push($event, $payload = []) { $this->listen($event.'_pushed', function () use ($event, $payload) { $this->dispatch($event, $payload); }); } /** * Flush a set of pushed events. * * @param string $event * @return void */ public function flush($event) { $this->dispatch($event.'_pushed'); } /** * Register an event subscriber with the dispatcher. * * @param object|string $subscriber * @return void */ public function subscribe($subscriber) { $subscriber = $this->resolveSubscriber($subscriber); $events = $subscriber->subscribe($this); if (is_array($events)) { foreach ($events as $event => $listeners) { foreach (Arr::wrap($listeners) as $listener) { if (is_string($listener) && method_exists($subscriber, $listener)) { $this->listen($event, [get_class($subscriber), $listener]); continue; } $this->listen($event, $listener); } } } } /** * Resolve the subscriber instance. * * @param object|string $subscriber * @return mixed */ protected function resolveSubscriber($subscriber) { if (is_string($subscriber)) { return $this->container->make($subscriber); } return $subscriber; } /** * Fire an event until the first non-null response is returned. * * @param string|object $event * @param mixed $payload * @return array|null */ public function until($event, $payload = []) { return $this->dispatch($event, $payload, true); } /** * Fire an event and call the listeners. * * @param string|object $event * @param mixed $payload * @param bool $halt * @return array|null */ public function dispatch($event, $payload = [], $halt = false) { // When the given "event" is actually an object we will assume it is an event // object and use the class as the event name and this event itself as the // payload to the handler, which makes object based events quite simple. [$event, $payload] = $this->parseEventAndPayload( $event, $payload ); if ($this->shouldBroadcast($payload)) { $this->broadcastEvent($payload[0]); } $responses = []; foreach ($this->getListeners($event) as $listener) { $response = $listener($event, $payload); // If a response is returned from the listener and event halting is enabled // we will just return this response, and not call the rest of the event // listeners. Otherwise we will add the response on the response list. if ($halt && ! is_null($response)) { return $response; } // If a boolean false is returned from a listener, we will stop propagating // the event to any further listeners down in the chain, else we keep on // looping through the listeners and firing every one in our sequence. if ($response === false) { break; } $responses[] = $response; } return $halt ? null : $responses; } /** * Parse the given event and payload and prepare them for dispatching. * * @param mixed $event * @param mixed $payload * @return array */ protected function parseEventAndPayload($event, $payload) { if (is_object($event)) { [$payload, $event] = [[$event], get_class($event)]; } return [$event, Arr::wrap($payload)]; } /** * Determine if the payload has a broadcastable event. * * @param array $payload * @return bool */ protected function shouldBroadcast(array $payload) { return isset($payload[0]) && $payload[0] instanceof ShouldBroadcast && $this->broadcastWhen($payload[0]); } /** * Check if the event should be broadcasted by the condition. * * @param mixed $event * @return bool */ protected function broadcastWhen($event) { return method_exists($event, 'broadcastWhen') ? $event->broadcastWhen() : true; } /** * Broadcast the given event class. * * @param \Illuminate\Contracts\Broadcasting\ShouldBroadcast $event * @return void */ protected function broadcastEvent($event) { $this->container->make(BroadcastFactory::class)->queue($event); } /** * Get all of the listeners for a given event name. * * @param string $eventName * @return array */ public function getListeners($eventName) { $listeners = $this->listeners[$eventName] ?? []; $listeners = array_merge( $listeners, $this->wildcardsCache[$eventName] ?? $this->getWildcardListeners($eventName) ); return class_exists($eventName, false) ? $this->addInterfaceListeners($eventName, $listeners) : $listeners; } /** * Get the wildcard listeners for the event. * * @param string $eventName * @return array */ protected function getWildcardListeners($eventName) { $wildcards = []; foreach ($this->wildcards as $key => $listeners) { if (Str::is($key, $eventName)) { $wildcards = array_merge($wildcards, $listeners); } } return $this->wildcardsCache[$eventName] = $wildcards; } /** * Add the listeners for the event's interfaces to the given array. * * @param string $eventName * @param array $listeners * @return array */ protected function addInterfaceListeners($eventName, array $listeners = []) { foreach (class_implements($eventName) as $interface) { if (isset($this->listeners[$interface])) { foreach ($this->listeners[$interface] as $names) { $listeners = array_merge($listeners, (array) $names); } } } return $listeners; } /** * Register an event listener with the dispatcher. * * @param \Closure|string|array $listener * @param bool $wildcard * @return \Closure */ public function makeListener($listener, $wildcard = false) { if (is_string($listener)) { return $this->createClassListener($listener, $wildcard); } if (is_array($listener) && isset($listener[0]) && is_string($listener[0])) { return $this->createClassListener($listener, $wildcard); } return function ($event, $payload) use ($listener, $wildcard) { if ($wildcard) { return $listener($event, $payload); } return $listener(...array_values($payload)); }; } /** * Create a class based listener using the IoC container. * * @param string $listener * @param bool $wildcard * @return \Closure */ public function createClassListener($listener, $wildcard = false) { return function ($event, $payload) use ($listener, $wildcard) { if ($wildcard) { return call_user_func($this->createClassCallable($listener), $event, $payload); } $callable = $this->createClassCallable($listener); return $callable(...array_values($payload)); }; } /** * Create the class based event callable. * * @param array|string $listener * @return callable */ protected function createClassCallable($listener) { [$class, $method] = is_array($listener) ? $listener : $this->parseClassCallable($listener); if (! method_exists($class, $method)) { $method = '__invoke'; } if ($this->handlerShouldBeQueued($class)) { return $this->createQueuedHandlerCallable($class, $method); } $listener = $this->container->make($class); return $this->handlerShouldBeDispatchedAfterDatabaseTransactions($listener) ? $this->createCallbackForListenerRunningAfterCommits($listener, $method) : [$listener, $method]; } /** * Parse the class listener into class and method. * * @param string $listener * @return array */ protected function parseClassCallable($listener) { return Str::parseCallback($listener, 'handle'); } /** * Determine if the event handler class should be queued. * * @param string $class * @return bool */ protected function handlerShouldBeQueued($class) { try { return (new ReflectionClass($class))->implementsInterface( ShouldQueue::class ); } catch (Exception $e) { return false; } } /** * Create a callable for putting an event handler on the queue. * * @param string $class * @param string $method * @return \Closure */ protected function createQueuedHandlerCallable($class, $method) { return function () use ($class, $method) { $arguments = array_map(function ($a) { return is_object($a) ? clone $a : $a; }, func_get_args()); if ($this->handlerWantsToBeQueued($class, $arguments)) { $this->queueHandler($class, $method, $arguments); } }; } /** * Determine if the given event handler should be dispatched after all database transactions have committed. * * @param object|mixed $listener * @return bool */ protected function handlerShouldBeDispatchedAfterDatabaseTransactions($listener) { return ($listener->afterCommit ?? null) && $this->container->bound('db.transactions'); } /** * Create a callable for dispatching a listener after database transactions. * * @param mixed $listener * @param string $method * @return \Closure */ protected function createCallbackForListenerRunningAfterCommits($listener, $method) { return function () use ($method, $listener) { $payload = func_get_args(); $this->container->make('db.transactions')->addCallback( function () use ($listener, $method, $payload) { $listener->$method(...$payload); } ); }; } /** * Determine if the event handler wants to be queued. * * @param string $class * @param array $arguments * @return bool */ protected function handlerWantsToBeQueued($class, $arguments) { $instance = $this->container->make($class); if (method_exists($instance, 'shouldQueue')) { return $instance->shouldQueue($arguments[0]); } return true; } /** * Queue the handler class. * * @param string $class * @param string $method * @param array $arguments * @return void */ protected function queueHandler($class, $method, $arguments) { [$listener, $job] = $this->createListenerAndJob($class, $method, $arguments); $connection = $this->resolveQueue()->connection(method_exists($listener, 'viaConnection') ? $listener->viaConnection() : $listener->connection ?? null); $queue = method_exists($listener, 'viaQueue') ? $listener->viaQueue() : $listener->queue ?? null; isset($listener->delay) ? $connection->laterOn($queue, $listener->delay, $job) : $connection->pushOn($queue, $job); } /** * Create the listener and job for a queued listener. * * @param string $class * @param string $method * @param array $arguments * @return array */ protected function createListenerAndJob($class, $method, $arguments) { $listener = (new ReflectionClass($class))->newInstanceWithoutConstructor(); return [$listener, $this->propagateListenerOptions( $listener, new CallQueuedListener($class, $method, $arguments) )]; } /** * Propagate listener options to the job. * * @param mixed $listener * @param mixed $job * @return mixed */ protected function propagateListenerOptions($listener, $job) { return tap($job, function ($job) use ($listener) { $job->afterCommit = property_exists($listener, 'afterCommit') ? $listener->afterCommit : null; $job->backoff = method_exists($listener, 'backoff') ? $listener->backoff() : ($listener->backoff ?? null); $job->maxExceptions = $listener->maxExceptions ?? null; $job->retryUntil = method_exists($listener, 'retryUntil') ? $listener->retryUntil() : null; $job->shouldBeEncrypted = $listener instanceof ShouldBeEncrypted; $job->timeout = $listener->timeout ?? null; $job->tries = $listener->tries ?? null; $job->through(array_merge( method_exists($listener, 'middleware') ? $listener->middleware() : [], $listener->middleware ?? [] )); }); } /** * Remove a set of listeners from the dispatcher. * * @param string $event * @return void */ public function forget($event) { if (Str::contains($event, '*')) { unset($this->wildcards[$event]); } else { unset($this->listeners[$event]); } foreach ($this->wildcardsCache as $key => $listeners) { if (Str::is($event, $key)) { unset($this->wildcardsCache[$key]); } } } /** * Forget all of the pushed listeners. * * @return void */ public function forgetPushed() { foreach ($this->listeners as $key => $value) { if (Str::endsWith($key, '_pushed')) { $this->forget($key); } } } /** * Get the queue implementation from the resolver. * * @return \Illuminate\Contracts\Queue\Queue */ protected function resolveQueue() { return call_user_func($this->queueResolver); } /** * Set the queue resolver implementation. * * @param callable $resolver * @return $this */ public function setQueueResolver(callable $resolver) { $this->queueResolver = $resolver; return $this; } } src/Illuminate/Events/functions.php 0000644 00000000552 15052151126 0013423 0 ustar 00 dispatcher = $dispatcher; } /** * Don't fire an event. * * @param string|object $event * @param mixed $payload * @param bool $halt * @return void */ public function dispatch($event, $payload = [], $halt = false) { // } /** * Don't register an event and payload to be fired later. * * @param string $event * @param array $payload * @return void */ public function push($event, $payload = []) { // } /** * Don't dispatch an event. * * @param string|object $event * @param mixed $payload * @return array|null */ public function until($event, $payload = []) { // } /** * Register an event listener with the dispatcher. * * @param \Closure|string|array $events * @param \Closure|string|array|null $listener * @return void */ public function listen($events, $listener = null) { $this->dispatcher->listen($events, $listener); } /** * Determine if a given event has listeners. * * @param string $eventName * @return bool */ public function hasListeners($eventName) { return $this->dispatcher->hasListeners($eventName); } /** * Register an event subscriber with the dispatcher. * * @param object|string $subscriber * @return void */ public function subscribe($subscriber) { $this->dispatcher->subscribe($subscriber); } /** * Flush a set of pushed events. * * @param string $event * @return void */ public function flush($event) { $this->dispatcher->flush($event); } /** * Remove a set of listeners from the dispatcher. * * @param string $event * @return void */ public function forget($event) { $this->dispatcher->forget($event); } /** * Forget all of the queued listeners. * * @return void */ public function forgetPushed() { $this->dispatcher->forgetPushed(); } /** * Dynamically pass method calls to the underlying dispatcher. * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { return $this->forwardCallTo($this->dispatcher, $method, $parameters); } } src/Illuminate/Events/CallQueuedListener.php 0000644 00000007232 15052151126 0015147 0 ustar 00 data = $data; $this->class = $class; $this->method = $method; } /** * Handle the queued job. * * @param \Illuminate\Container\Container $container * @return void */ public function handle(Container $container) { $this->prepareData(); $handler = $this->setJobInstanceIfNecessary( $this->job, $container->make($this->class) ); $handler->{$this->method}(...array_values($this->data)); } /** * Set the job instance of the given class if necessary. * * @param \Illuminate\Contracts\Queue\Job $job * @param object $instance * @return object */ protected function setJobInstanceIfNecessary(Job $job, $instance) { if (in_array(InteractsWithQueue::class, class_uses_recursive($instance))) { $instance->setJob($job); } return $instance; } /** * Call the failed method on the job instance. * * The event instance and the exception will be passed. * * @param \Throwable $e * @return void */ public function failed($e) { $this->prepareData(); $handler = Container::getInstance()->make($this->class); $parameters = array_merge(array_values($this->data), [$e]); if (method_exists($handler, 'failed')) { $handler->failed(...$parameters); } } /** * Unserialize the data if needed. * * @return void */ protected function prepareData() { if (is_string($this->data)) { $this->data = unserialize($this->data); } } /** * Get the display name for the queued job. * * @return string */ public function displayName() { return $this->class; } /** * Prepare the instance for cloning. * * @return void */ public function __clone() { $this->data = array_map(function ($data) { return is_object($data) ? clone $data : $data; }, $this->data); } } src/Illuminate/Encryption/MissingAppKeyException.php 0000644 00000000600 15052151126 0016675 0 ustar 00 ['size' => 16, 'aead' => false], 'aes-256-cbc' => ['size' => 32, 'aead' => false], 'aes-128-gcm' => ['size' => 16, 'aead' => true], 'aes-256-gcm' => ['size' => 32, 'aead' => true], ]; /** * Create a new encrypter instance. * * @param string $key * @param string $cipher * @return void * * @throws \RuntimeException */ public function __construct($key, $cipher = 'aes-128-cbc') { $key = (string) $key; if (! static::supported($key, $cipher)) { $ciphers = implode(', ', array_keys(self::$supportedCiphers)); throw new RuntimeException("Unsupported cipher or incorrect key length. Supported ciphers are: {$ciphers}."); } $this->key = $key; $this->cipher = $cipher; } /** * Determine if the given key and cipher combination is valid. * * @param string $key * @param string $cipher * @return bool */ public static function supported($key, $cipher) { if (! isset(self::$supportedCiphers[strtolower($cipher)])) { return false; } return mb_strlen($key, '8bit') === self::$supportedCiphers[strtolower($cipher)]['size']; } /** * Create a new encryption key for the given cipher. * * @param string $cipher * @return string */ public static function generateKey($cipher) { return random_bytes(self::$supportedCiphers[strtolower($cipher)]['size'] ?? 32); } /** * Encrypt the given value. * * @param mixed $value * @param bool $serialize * @return string * * @throws \Illuminate\Contracts\Encryption\EncryptException */ public function encrypt($value, $serialize = true) { $iv = random_bytes(openssl_cipher_iv_length(strtolower($this->cipher))); $tag = ''; $value = self::$supportedCiphers[strtolower($this->cipher)]['aead'] ? \openssl_encrypt( $serialize ? serialize($value) : $value, strtolower($this->cipher), $this->key, 0, $iv, $tag ) : \openssl_encrypt( $serialize ? serialize($value) : $value, strtolower($this->cipher), $this->key, 0, $iv ); if ($value === false) { throw new EncryptException('Could not encrypt the data.'); } $iv = base64_encode($iv); $tag = base64_encode($tag); $mac = self::$supportedCiphers[strtolower($this->cipher)]['aead'] ? '' // For AEAD-algoritms, the tag / MAC is returned by openssl_encrypt... : $this->hash($iv, $value); $json = json_encode(compact('iv', 'value', 'mac', 'tag'), JSON_UNESCAPED_SLASHES); if (json_last_error() !== JSON_ERROR_NONE) { throw new EncryptException('Could not encrypt the data.'); } return base64_encode($json); } /** * Encrypt a string without serialization. * * @param string $value * @return string * * @throws \Illuminate\Contracts\Encryption\EncryptException */ public function encryptString($value) { return $this->encrypt($value, false); } /** * Decrypt the given value. * * @param string $payload * @param bool $unserialize * @return mixed * * @throws \Illuminate\Contracts\Encryption\DecryptException */ public function decrypt($payload, $unserialize = true) { $payload = $this->getJsonPayload($payload); $iv = base64_decode($payload['iv']); $tag = empty($payload['tag']) ? null : base64_decode($payload['tag']); if (self::$supportedCiphers[strtolower($this->cipher)]['aead'] && strlen($tag) !== 16) { throw new DecryptException('Could not decrypt the data.'); } // Here we will decrypt the value. If we are able to successfully decrypt it // we will then unserialize it and return it out to the caller. If we are // unable to decrypt this value we will throw out an exception message. $decrypted = \openssl_decrypt( $payload['value'], strtolower($this->cipher), $this->key, 0, $iv, $tag ?? '' ); if ($decrypted === false) { throw new DecryptException('Could not decrypt the data.'); } return $unserialize ? unserialize($decrypted) : $decrypted; } /** * Decrypt the given string without unserialization. * * @param string $payload * @return string * * @throws \Illuminate\Contracts\Encryption\DecryptException */ public function decryptString($payload) { return $this->decrypt($payload, false); } /** * Create a MAC for the given value. * * @param string $iv * @param mixed $value * @return string */ protected function hash($iv, $value) { return hash_hmac('sha256', $iv.$value, $this->key); } /** * Get the JSON array from the given payload. * * @param string $payload * @return array * * @throws \Illuminate\Contracts\Encryption\DecryptException */ protected function getJsonPayload($payload) { $payload = json_decode(base64_decode($payload), true); // If the payload is not valid JSON or does not have the proper keys set we will // assume it is invalid and bail out of the routine since we will not be able // to decrypt the given value. We'll also check the MAC for this encryption. if (! $this->validPayload($payload)) { throw new DecryptException('The payload is invalid.'); } if (! self::$supportedCiphers[strtolower($this->cipher)]['aead'] && ! $this->validMac($payload)) { throw new DecryptException('The MAC is invalid.'); } return $payload; } /** * Verify that the encryption payload is valid. * * @param mixed $payload * @return bool */ protected function validPayload($payload) { return is_array($payload) && isset($payload['iv'], $payload['value'], $payload['mac']) && strlen(base64_decode($payload['iv'], true)) === openssl_cipher_iv_length(strtolower($this->cipher)); } /** * Determine if the MAC for the given payload is valid. * * @param array $payload * @return bool */ protected function validMac(array $payload) { return hash_equals( $this->hash($payload['iv'], $payload['value']), $payload['mac'] ); } /** * Get the encryption key. * * @return string */ public function getKey() { return $this->key; } } src/Illuminate/Encryption/composer.json 0000644 00000001622 15052151126 0014311 0 ustar 00 { "name": "illuminate/encryption", "description": "The Illuminate Encryption package.", "license": "MIT", "homepage": "https://laravel.com", "support": { "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, "authors": [ { "name": "Taylor Otwell", "email": "taylor@laravel.com" } ], "require": { "php": "^7.3|^8.0", "ext-json": "*", "ext-mbstring": "*", "ext-openssl": "*", "illuminate/contracts": "^8.0", "illuminate/support": "^8.0" }, "autoload": { "psr-4": { "Illuminate\\Encryption\\": "" } }, "extra": { "branch-alias": { "dev-master": "8.x-dev" } }, "config": { "sort-packages": true }, "minimum-stability": "dev" } src/Illuminate/Encryption/EncryptionServiceProvider.php 0000644 00000005072 15052151126 0017471 0 ustar 00 registerEncrypter(); $this->registerOpisSecurityKey(); $this->registerSerializableClosureSecurityKey(); } /** * Register the encrypter. * * @return void */ protected function registerEncrypter() { $this->app->singleton('encrypter', function ($app) { $config = $app->make('config')->get('app'); return new Encrypter($this->parseKey($config), $config['cipher']); }); } /** * Configure Opis Closure signing for security. * * @return void * * @deprecated Will be removed in a future Laravel version. */ protected function registerOpisSecurityKey() { if (\PHP_VERSION_ID < 80100) { $config = $this->app->make('config')->get('app'); if (! class_exists(OpisSerializableClosure::class) || empty($config['key'])) { return; } OpisSerializableClosure::setSecretKey($this->parseKey($config)); } } /** * Configure Serializable Closure signing for security. * * @return void */ protected function registerSerializableClosureSecurityKey() { $config = $this->app->make('config')->get('app'); if (! class_exists(SerializableClosure::class) || empty($config['key'])) { return; } SerializableClosure::setSecretKey($this->parseKey($config)); } /** * Parse the encryption key. * * @param array $config * @return string */ protected function parseKey(array $config) { if (Str::startsWith($key = $this->key($config), $prefix = 'base64:')) { $key = base64_decode(Str::after($key, $prefix)); } return $key; } /** * Extract the encryption key from the given configuration. * * @param array $config * @return string * * @throws \Illuminate\Encryption\MissingAppKeyException */ protected function key(array $config) { return tap($config['key'], function ($key) { if (empty($key)) { throw new MissingAppKeyException; } }); } } src/Illuminate/Pagination/PaginationServiceProvider.php 0000644 00000001344 15052151126 0017365 0 ustar 00 loadViewsFrom(__DIR__.'/resources/views', 'pagination'); if ($this->app->runningInConsole()) { $this->publishes([ __DIR__.'/resources/views' => $this->app->resourcePath('views/vendor/pagination'), ], 'laravel-pagination'); } } /** * Register the service provider. * * @return void */ public function register() { PaginationState::resolveUsing($this->app); } } src/Illuminate/Pagination/AbstractCursorPaginator.php 0000644 00000035550 15052151126 0017054 0 ustar 00 cursorName => $cursor->encode()]; if (count($this->query) > 0) { $parameters = array_merge($this->query, $parameters); } return $this->path() .(Str::contains($this->path(), '?') ? '&' : '?') .Arr::query($parameters) .$this->buildFragment(); } /** * Get the URL for the previous page. * * @return string|null */ public function previousPageUrl() { if (is_null($previousCursor = $this->previousCursor())) { return null; } return $this->url($previousCursor); } /** * The URL for the next page, or null. * * @return string|null */ public function nextPageUrl() { if (is_null($nextCursor = $this->nextCursor())) { return null; } return $this->url($nextCursor); } /** * Get the "cursor" that points to the previous set of items. * * @return \Illuminate\Pagination\Cursor|null */ public function previousCursor() { if (is_null($this->cursor) || ($this->cursor->pointsToPreviousItems() && ! $this->hasMore)) { return null; } return $this->getCursorForItem($this->items->first(), false); } /** * Get the "cursor" that points to the next set of items. * * @return \Illuminate\Pagination\Cursor|null */ public function nextCursor() { if ((is_null($this->cursor) && ! $this->hasMore) || (! is_null($this->cursor) && $this->cursor->pointsToNextItems() && ! $this->hasMore)) { return null; } return $this->getCursorForItem($this->items->last(), true); } /** * Get a cursor instance for the given item. * * @param \ArrayAccess|\stdClass $item * @param bool $isNext * @return \Illuminate\Pagination\Cursor */ public function getCursorForItem($item, $isNext = true) { return new Cursor($this->getParametersForItem($item), $isNext); } /** * Get the cursor parameters for a given object. * * @param \ArrayAccess|\stdClass $item * @return array * * @throws \Exception */ public function getParametersForItem($item) { return collect($this->parameters) ->flip() ->map(function ($_, $parameterName) use ($item) { if ($item instanceof JsonResource) { $item = $item->resource; } if ($item instanceof Model && ! is_null($parameter = $this->getPivotParameterForItem($item, $parameterName))) { return $parameter; } elseif ($item instanceof ArrayAccess || is_array($item)) { return $this->ensureParameterIsPrimitive( $item[$parameterName] ?? $item[Str::afterLast($parameterName, '.')] ); } elseif (is_object($item)) { return $this->ensureParameterIsPrimitive( $item->{$parameterName} ?? $item->{Str::afterLast($parameterName, '.')} ); } throw new Exception('Only arrays and objects are supported when cursor paginating items.'); })->toArray(); } /** * Get the cursor parameter value from a pivot model if applicable. * * @param \ArrayAccess|\stdClass $item * @param string $parameterName * @return string|null */ protected function getPivotParameterForItem($item, $parameterName) { $table = Str::beforeLast($parameterName, '.'); foreach ($item->getRelations() as $relation) { if ($relation instanceof Pivot && $relation->getTable() === $table) { return $this->ensureParameterIsPrimitive( $relation->getAttribute(Str::afterLast($parameterName, '.')) ); } } } /** * Ensure the parameter is a primitive type. * * This can resolve issues that arise the developer uses a value object for an attribute. * * @param mixed $parameter * @return mixed */ protected function ensureParameterIsPrimitive($parameter) { return is_object($parameter) && method_exists($parameter, '__toString') ? (string) $parameter : $parameter; } /** * Get / set the URL fragment to be appended to URLs. * * @param string|null $fragment * @return $this|string|null */ public function fragment($fragment = null) { if (is_null($fragment)) { return $this->fragment; } $this->fragment = $fragment; return $this; } /** * Add a set of query string values to the paginator. * * @param array|string|null $key * @param string|null $value * @return $this */ public function appends($key, $value = null) { if (is_null($key)) { return $this; } if (is_array($key)) { return $this->appendArray($key); } return $this->addQuery($key, $value); } /** * Add an array of query string values. * * @param array $keys * @return $this */ protected function appendArray(array $keys) { foreach ($keys as $key => $value) { $this->addQuery($key, $value); } return $this; } /** * Add all current query string values to the paginator. * * @return $this */ public function withQueryString() { if (! is_null($query = Paginator::resolveQueryString())) { return $this->appends($query); } return $this; } /** * Add a query string value to the paginator. * * @param string $key * @param string $value * @return $this */ protected function addQuery($key, $value) { if ($key !== $this->cursorName) { $this->query[$key] = $value; } return $this; } /** * Build the full fragment portion of a URL. * * @return string */ protected function buildFragment() { return $this->fragment ? '#'.$this->fragment : ''; } /** * Load a set of relationships onto the mixed relationship collection. * * @param string $relation * @param array $relations * @return $this */ public function loadMorph($relation, $relations) { $this->getCollection()->loadMorph($relation, $relations); return $this; } /** * Load a set of relationship counts onto the mixed relationship collection. * * @param string $relation * @param array $relations * @return $this */ public function loadMorphCount($relation, $relations) { $this->getCollection()->loadMorphCount($relation, $relations); return $this; } /** * Get the slice of items being paginated. * * @return array */ public function items() { return $this->items->all(); } /** * Transform each item in the slice of items using a callback. * * @param callable $callback * @return $this */ public function through(callable $callback) { $this->items->transform($callback); return $this; } /** * Get the number of items shown per page. * * @return int */ public function perPage() { return $this->perPage; } /** * Get the current cursor being paginated. * * @return \Illuminate\Pagination\Cursor|null */ public function cursor() { return $this->cursor; } /** * Get the query string variable used to store the cursor. * * @return string */ public function getCursorName() { return $this->cursorName; } /** * Set the query string variable used to store the cursor. * * @param string $name * @return $this */ public function setCursorName($name) { $this->cursorName = $name; return $this; } /** * Set the base path to assign to all URLs. * * @param string $path * @return $this */ public function withPath($path) { return $this->setPath($path); } /** * Set the base path to assign to all URLs. * * @param string $path * @return $this */ public function setPath($path) { $this->path = $path; return $this; } /** * Get the base path for paginator generated URLs. * * @return string|null */ public function path() { return $this->path; } /** * Resolve the current cursor or return the default value. * * @param string $cursorName * @return \Illuminate\Pagination\Cursor|null */ public static function resolveCurrentCursor($cursorName = 'cursor', $default = null) { if (isset(static::$currentCursorResolver)) { return call_user_func(static::$currentCursorResolver, $cursorName); } return $default; } /** * Set the current cursor resolver callback. * * @param \Closure $resolver * @return void */ public static function currentCursorResolver(Closure $resolver) { static::$currentCursorResolver = $resolver; } /** * Get an instance of the view factory from the resolver. * * @return \Illuminate\Contracts\View\Factory */ public static function viewFactory() { return Paginator::viewFactory(); } /** * Get an iterator for the items. * * @return \ArrayIterator */ #[\ReturnTypeWillChange] public function getIterator() { return $this->items->getIterator(); } /** * Determine if the list of items is empty. * * @return bool */ public function isEmpty() { return $this->items->isEmpty(); } /** * Determine if the list of items is not empty. * * @return bool */ public function isNotEmpty() { return $this->items->isNotEmpty(); } /** * Get the number of items for the current page. * * @return int */ #[\ReturnTypeWillChange] public function count() { return $this->items->count(); } /** * Get the paginator's underlying collection. * * @return \Illuminate\Support\Collection */ public function getCollection() { return $this->items; } /** * Set the paginator's underlying collection. * * @param \Illuminate\Support\Collection $collection * @return $this */ public function setCollection(Collection $collection) { $this->items = $collection; return $this; } /** * Get the paginator options. * * @return array */ public function getOptions() { return $this->options; } /** * Determine if the given item exists. * * @param mixed $key * @return bool */ #[\ReturnTypeWillChange] public function offsetExists($key) { return $this->items->has($key); } /** * Get the item at the given offset. * * @param mixed $key * @return mixed */ #[\ReturnTypeWillChange] public function offsetGet($key) { return $this->items->get($key); } /** * Set the item at the given offset. * * @param mixed $key * @param mixed $value * @return void */ #[\ReturnTypeWillChange] public function offsetSet($key, $value) { $this->items->put($key, $value); } /** * Unset the item at the given key. * * @param mixed $key * @return void */ #[\ReturnTypeWillChange] public function offsetUnset($key) { $this->items->forget($key); } /** * Render the contents of the paginator to HTML. * * @return string */ public function toHtml() { return (string) $this->render(); } /** * Make dynamic calls into the collection. * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { return $this->forwardCallTo($this->getCollection(), $method, $parameters); } /** * Render the contents of the paginator when casting to a string. * * @return string */ public function __toString() { return (string) $this->render(); } } src/Illuminate/Pagination/CursorPaginationException.php 0000644 00000000310 15052151126 0017376 0 ustar 00 = 1 && filter_var($page, FILTER_VALIDATE_INT) !== false; } /** * Get the URL for the previous page. * * @return string|null */ public function previousPageUrl() { if ($this->currentPage() > 1) { return $this->url($this->currentPage() - 1); } } /** * Create a range of pagination URLs. * * @param int $start * @param int $end * @return array */ public function getUrlRange($start, $end) { return collect(range($start, $end))->mapWithKeys(function ($page) { return [$page => $this->url($page)]; })->all(); } /** * Get the URL for a given page number. * * @param int $page * @return string */ public function url($page) { if ($page <= 0) { $page = 1; } // If we have any extra query string key / value pairs that need to be added // onto the URL, we will put them in query string form and then attach it // to the URL. This allows for extra information like sortings storage. $parameters = [$this->pageName => $page]; if (count($this->query) > 0) { $parameters = array_merge($this->query, $parameters); } return $this->path() .(Str::contains($this->path(), '?') ? '&' : '?') .Arr::query($parameters) .$this->buildFragment(); } /** * Get / set the URL fragment to be appended to URLs. * * @param string|null $fragment * @return $this|string|null */ public function fragment($fragment = null) { if (is_null($fragment)) { return $this->fragment; } $this->fragment = $fragment; return $this; } /** * Add a set of query string values to the paginator. * * @param array|string|null $key * @param string|null $value * @return $this */ public function appends($key, $value = null) { if (is_null($key)) { return $this; } if (is_array($key)) { return $this->appendArray($key); } return $this->addQuery($key, $value); } /** * Add an array of query string values. * * @param array $keys * @return $this */ protected function appendArray(array $keys) { foreach ($keys as $key => $value) { $this->addQuery($key, $value); } return $this; } /** * Add all current query string values to the paginator. * * @return $this */ public function withQueryString() { if (isset(static::$queryStringResolver)) { return $this->appends(call_user_func(static::$queryStringResolver)); } return $this; } /** * Add a query string value to the paginator. * * @param string $key * @param string $value * @return $this */ protected function addQuery($key, $value) { if ($key !== $this->pageName) { $this->query[$key] = $value; } return $this; } /** * Build the full fragment portion of a URL. * * @return string */ protected function buildFragment() { return $this->fragment ? '#'.$this->fragment : ''; } /** * Load a set of relationships onto the mixed relationship collection. * * @param string $relation * @param array $relations * @return $this */ public function loadMorph($relation, $relations) { $this->getCollection()->loadMorph($relation, $relations); return $this; } /** * Load a set of relationship counts onto the mixed relationship collection. * * @param string $relation * @param array $relations * @return $this */ public function loadMorphCount($relation, $relations) { $this->getCollection()->loadMorphCount($relation, $relations); return $this; } /** * Get the slice of items being paginated. * * @return array */ public function items() { return $this->items->all(); } /** * Get the number of the first item in the slice. * * @return int */ public function firstItem() { return count($this->items) > 0 ? ($this->currentPage - 1) * $this->perPage + 1 : null; } /** * Get the number of the last item in the slice. * * @return int */ public function lastItem() { return count($this->items) > 0 ? $this->firstItem() + $this->count() - 1 : null; } /** * Transform each item in the slice of items using a callback. * * @param callable $callback * @return $this */ public function through(callable $callback) { $this->items->transform($callback); return $this; } /** * Get the number of items shown per page. * * @return int */ public function perPage() { return $this->perPage; } /** * Determine if there are enough items to split into multiple pages. * * @return bool */ public function hasPages() { return $this->currentPage() != 1 || $this->hasMorePages(); } /** * Determine if the paginator is on the first page. * * @return bool */ public function onFirstPage() { return $this->currentPage() <= 1; } /** * Get the current page. * * @return int */ public function currentPage() { return $this->currentPage; } /** * Get the query string variable used to store the page. * * @return string */ public function getPageName() { return $this->pageName; } /** * Set the query string variable used to store the page. * * @param string $name * @return $this */ public function setPageName($name) { $this->pageName = $name; return $this; } /** * Set the base path to assign to all URLs. * * @param string $path * @return $this */ public function withPath($path) { return $this->setPath($path); } /** * Set the base path to assign to all URLs. * * @param string $path * @return $this */ public function setPath($path) { $this->path = $path; return $this; } /** * Set the number of links to display on each side of current page link. * * @param int $count * @return $this */ public function onEachSide($count) { $this->onEachSide = $count; return $this; } /** * Get the base path for paginator generated URLs. * * @return string|null */ public function path() { return $this->path; } /** * Resolve the current request path or return the default value. * * @param string $default * @return string */ public static function resolveCurrentPath($default = '/') { if (isset(static::$currentPathResolver)) { return call_user_func(static::$currentPathResolver); } return $default; } /** * Set the current request path resolver callback. * * @param \Closure $resolver * @return void */ public static function currentPathResolver(Closure $resolver) { static::$currentPathResolver = $resolver; } /** * Resolve the current page or return the default value. * * @param string $pageName * @param int $default * @return int */ public static function resolveCurrentPage($pageName = 'page', $default = 1) { if (isset(static::$currentPageResolver)) { return (int) call_user_func(static::$currentPageResolver, $pageName); } return $default; } /** * Set the current page resolver callback. * * @param \Closure $resolver * @return void */ public static function currentPageResolver(Closure $resolver) { static::$currentPageResolver = $resolver; } /** * Resolve the query string or return the default value. * * @param string|array|null $default * @return string */ public static function resolveQueryString($default = null) { if (isset(static::$queryStringResolver)) { return (static::$queryStringResolver)(); } return $default; } /** * Set with query string resolver callback. * * @param \Closure $resolver * @return void */ public static function queryStringResolver(Closure $resolver) { static::$queryStringResolver = $resolver; } /** * Get an instance of the view factory from the resolver. * * @return \Illuminate\Contracts\View\Factory */ public static function viewFactory() { return call_user_func(static::$viewFactoryResolver); } /** * Set the view factory resolver callback. * * @param \Closure $resolver * @return void */ public static function viewFactoryResolver(Closure $resolver) { static::$viewFactoryResolver = $resolver; } /** * Set the default pagination view. * * @param string $view * @return void */ public static function defaultView($view) { static::$defaultView = $view; } /** * Set the default "simple" pagination view. * * @param string $view * @return void */ public static function defaultSimpleView($view) { static::$defaultSimpleView = $view; } /** * Indicate that Tailwind styling should be used for generated links. * * @return void */ public static function useTailwind() { static::defaultView('pagination::tailwind'); static::defaultSimpleView('pagination::simple-tailwind'); } /** * Indicate that Bootstrap 4 styling should be used for generated links. * * @return void */ public static function useBootstrap() { static::defaultView('pagination::bootstrap-4'); static::defaultSimpleView('pagination::simple-bootstrap-4'); } /** * Indicate that Bootstrap 3 styling should be used for generated links. * * @return void */ public static function useBootstrapThree() { static::defaultView('pagination::default'); static::defaultSimpleView('pagination::simple-default'); } /** * Get an iterator for the items. * * @return \ArrayIterator */ #[\ReturnTypeWillChange] public function getIterator() { return $this->items->getIterator(); } /** * Determine if the list of items is empty. * * @return bool */ public function isEmpty() { return $this->items->isEmpty(); } /** * Determine if the list of items is not empty. * * @return bool */ public function isNotEmpty() { return $this->items->isNotEmpty(); } /** * Get the number of items for the current page. * * @return int */ #[\ReturnTypeWillChange] public function count() { return $this->items->count(); } /** * Get the paginator's underlying collection. * * @return \Illuminate\Support\Collection */ public function getCollection() { return $this->items; } /** * Set the paginator's underlying collection. * * @param \Illuminate\Support\Collection $collection * @return $this */ public function setCollection(Collection $collection) { $this->items = $collection; return $this; } /** * Get the paginator options. * * @return array */ public function getOptions() { return $this->options; } /** * Determine if the given item exists. * * @param mixed $key * @return bool */ #[\ReturnTypeWillChange] public function offsetExists($key) { return $this->items->has($key); } /** * Get the item at the given offset. * * @param mixed $key * @return mixed */ #[\ReturnTypeWillChange] public function offsetGet($key) { return $this->items->get($key); } /** * Set the item at the given offset. * * @param mixed $key * @param mixed $value * @return void */ #[\ReturnTypeWillChange] public function offsetSet($key, $value) { $this->items->put($key, $value); } /** * Unset the item at the given key. * * @param mixed $key * @return void */ #[\ReturnTypeWillChange] public function offsetUnset($key) { $this->items->forget($key); } /** * Render the contents of the paginator to HTML. * * @return string */ public function toHtml() { return (string) $this->render(); } /** * Make dynamic calls into the collection. * * @param string $method * @param array $parameters * @return mixed */ public function __call($method, $parameters) { return $this->forwardCallTo($this->getCollection(), $method, $parameters); } /** * Render the contents of the paginator when casting to a string. * * @return string */ public function __toString() { return (string) $this->render(); } } src/Illuminate/Pagination/Paginator.php 0000644 00000010454 15052151126 0014166 0 ustar 00 options = $options; foreach ($options as $key => $value) { $this->{$key} = $value; } $this->perPage = $perPage; $this->currentPage = $this->setCurrentPage($currentPage); $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path; $this->setItems($items); } /** * Get the current page for the request. * * @param int $currentPage * @return int */ protected function setCurrentPage($currentPage) { $currentPage = $currentPage ?: static::resolveCurrentPage(); return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1; } /** * Set the items for the paginator. * * @param mixed $items * @return void */ protected function setItems($items) { $this->items = $items instanceof Collection ? $items : Collection::make($items); $this->hasMore = $this->items->count() > $this->perPage; $this->items = $this->items->slice(0, $this->perPage); } /** * Get the URL for the next page. * * @return string|null */ public function nextPageUrl() { if ($this->hasMorePages()) { return $this->url($this->currentPage() + 1); } } /** * Render the paginator using the given view. * * @param string|null $view * @param array $data * @return string */ public function links($view = null, $data = []) { return $this->render($view, $data); } /** * Render the paginator using the given view. * * @param string|null $view * @param array $data * @return \Illuminate\Contracts\Support\Htmlable */ public function render($view = null, $data = []) { return static::viewFactory()->make($view ?: static::$defaultSimpleView, array_merge($data, [ 'paginator' => $this, ])); } /** * Manually indicate that the paginator does have more pages. * * @param bool $hasMore * @return $this */ public function hasMorePagesWhen($hasMore = true) { $this->hasMore = $hasMore; return $this; } /** * Determine if there are more items in the data source. * * @return bool */ public function hasMorePages() { return $this->hasMore; } /** * Get the instance as an array. * * @return array */ public function toArray() { return [ 'current_page' => $this->currentPage(), 'data' => $this->items->toArray(), 'first_page_url' => $this->url(1), 'from' => $this->firstItem(), 'next_page_url' => $this->nextPageUrl(), 'path' => $this->path(), 'per_page' => $this->perPage(), 'prev_page_url' => $this->previousPageUrl(), 'to' => $this->lastItem(), ]; } /** * Convert the object into something JSON serializable. * * @return array */ #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->toArray(); } /** * Convert the object to its JSON representation. * * @param int $options * @return string */ public function toJson($options = 0) { return json_encode($this->jsonSerialize(), $options); } } src/Illuminate/Pagination/UrlWindow.php 0000644 00000013135 15052151126 0014173 0 ustar 00 paginator = $paginator; } /** * Create a new URL window instance. * * @param \Illuminate\Contracts\Pagination\LengthAwarePaginator $paginator * @return array */ public static function make(PaginatorContract $paginator) { return (new static($paginator))->get(); } /** * Get the window of URLs to be shown. * * @return array */ public function get() { $onEachSide = $this->paginator->onEachSide; if ($this->paginator->lastPage() < ($onEachSide * 2) + 8) { return $this->getSmallSlider(); } return $this->getUrlSlider($onEachSide); } /** * Get the slider of URLs there are not enough pages to slide. * * @return array */ protected function getSmallSlider() { return [ 'first' => $this->paginator->getUrlRange(1, $this->lastPage()), 'slider' => null, 'last' => null, ]; } /** * Create a URL slider links. * * @param int $onEachSide * @return array */ protected function getUrlSlider($onEachSide) { $window = $onEachSide + 4; if (! $this->hasPages()) { return ['first' => null, 'slider' => null, 'last' => null]; } // If the current page is very close to the beginning of the page range, we will // just render the beginning of the page range, followed by the last 2 of the // links in this list, since we will not have room to create a full slider. if ($this->currentPage() <= $window) { return $this->getSliderTooCloseToBeginning($window, $onEachSide); } // If the current page is close to the ending of the page range we will just get // this first couple pages, followed by a larger window of these ending pages // since we're too close to the end of the list to create a full on slider. elseif ($this->currentPage() > ($this->lastPage() - $window)) { return $this->getSliderTooCloseToEnding($window, $onEachSide); } // If we have enough room on both sides of the current page to build a slider we // will surround it with both the beginning and ending caps, with this window // of pages in the middle providing a Google style sliding paginator setup. return $this->getFullSlider($onEachSide); } /** * Get the slider of URLs when too close to beginning of window. * * @param int $window * @param int $onEachSide * @return array */ protected function getSliderTooCloseToBeginning($window, $onEachSide) { return [ 'first' => $this->paginator->getUrlRange(1, $window + $onEachSide), 'slider' => null, 'last' => $this->getFinish(), ]; } /** * Get the slider of URLs when too close to ending of window. * * @param int $window * @param int $onEachSide * @return array */ protected function getSliderTooCloseToEnding($window, $onEachSide) { $last = $this->paginator->getUrlRange( $this->lastPage() - ($window + ($onEachSide - 1)), $this->lastPage() ); return [ 'first' => $this->getStart(), 'slider' => null, 'last' => $last, ]; } /** * Get the slider of URLs when a full slider can be made. * * @param int $onEachSide * @return array */ protected function getFullSlider($onEachSide) { return [ 'first' => $this->getStart(), 'slider' => $this->getAdjacentUrlRange($onEachSide), 'last' => $this->getFinish(), ]; } /** * Get the page range for the current page window. * * @param int $onEachSide * @return array */ public function getAdjacentUrlRange($onEachSide) { return $this->paginator->getUrlRange( $this->currentPage() - $onEachSide, $this->currentPage() + $onEachSide ); } /** * Get the starting URLs of a pagination slider. * * @return array */ public function getStart() { return $this->paginator->getUrlRange(1, 2); } /** * Get the ending URLs of a pagination slider. * * @return array */ public function getFinish() { return $this->paginator->getUrlRange( $this->lastPage() - 1, $this->lastPage() ); } /** * Determine if the underlying paginator being presented has pages to show. * * @return bool */ public function hasPages() { return $this->paginator->lastPage() > 1; } /** * Get the current page from the paginator. * * @return int */ protected function currentPage() { return $this->paginator->currentPage(); } /** * Get the last page from the paginator. * * @return int */ protected function lastPage() { return $this->paginator->lastPage(); } } src/Illuminate/Pagination/CursorPaginator.php 0000644 00000010240 15052151126 0015355 0 ustar 00 options = $options; foreach ($options as $key => $value) { $this->{$key} = $value; } $this->perPage = $perPage; $this->cursor = $cursor; $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path; $this->setItems($items); } /** * Set the items for the paginator. * * @param mixed $items * @return void */ protected function setItems($items) { $this->items = $items instanceof Collection ? $items : Collection::make($items); $this->hasMore = $this->items->count() > $this->perPage; $this->items = $this->items->slice(0, $this->perPage); if (! is_null($this->cursor) && $this->cursor->pointsToPreviousItems()) { $this->items = $this->items->reverse()->values(); } } /** * Render the paginator using the given view. * * @param string|null $view * @param array $data * @return \Illuminate\Contracts\Support\Htmlable */ public function links($view = null, $data = []) { return $this->render($view, $data); } /** * Render the paginator using the given view. * * @param string|null $view * @param array $data * @return \Illuminate\Contracts\Support\Htmlable */ public function render($view = null, $data = []) { return static::viewFactory()->make($view ?: Paginator::$defaultSimpleView, array_merge($data, [ 'paginator' => $this, ])); } /** * Determine if there are more items in the data source. * * @return bool */ public function hasMorePages() { return (is_null($this->cursor) && $this->hasMore) || (! is_null($this->cursor) && $this->cursor->pointsToNextItems() && $this->hasMore) || (! is_null($this->cursor) && $this->cursor->pointsToPreviousItems()); } /** * Determine if there are enough items to split into multiple pages. * * @return bool */ public function hasPages() { return ! $this->onFirstPage() || $this->hasMorePages(); } /** * Determine if the paginator is on the first page. * * @return bool */ public function onFirstPage() { return is_null($this->cursor) || ($this->cursor->pointsToPreviousItems() && ! $this->hasMore); } /** * Get the instance as an array. * * @return array */ public function toArray() { return [ 'data' => $this->items->toArray(), 'path' => $this->path(), 'per_page' => $this->perPage(), 'next_page_url' => $this->nextPageUrl(), 'prev_page_url' => $this->previousPageUrl(), ]; } /** * Convert the object into something JSON serializable. * * @return array */ #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->toArray(); } /** * Convert the object to its JSON representation. * * @param int $options * @return string */ public function toJson($options = 0) { return json_encode($this->jsonSerialize(), $options); } } src/Illuminate/Pagination/composer.json 0000644 00000001603 15052151126 0014247 0 ustar 00 { "name": "illuminate/pagination", "description": "The Illuminate Pagination package.", "license": "MIT", "homepage": "https://laravel.com", "support": { "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, "authors": [ { "name": "Taylor Otwell", "email": "taylor@laravel.com" } ], "require": { "php": "^7.3|^8.0", "ext-json": "*", "illuminate/collections": "^8.0", "illuminate/contracts": "^8.0", "illuminate/support": "^8.0" }, "autoload": { "psr-4": { "Illuminate\\Pagination\\": "" } }, "extra": { "branch-alias": { "dev-master": "8.x-dev" } }, "config": { "sort-packages": true }, "minimum-stability": "dev" } src/Illuminate/Pagination/Cursor.php 0000644 00000006271 15052151126 0013521 0 ustar 00 parameters = $parameters; $this->pointsToNextItems = $pointsToNextItems; } /** * Get the given parameter from the cursor. * * @param string $parameterName * @return string|null * * @throws \UnexpectedValueException */ public function parameter(string $parameterName) { if (! array_key_exists($parameterName, $this->parameters)) { throw new UnexpectedValueException("Unable to find parameter [{$parameterName}] in pagination item."); } return $this->parameters[$parameterName]; } /** * Get the given parameters from the cursor. * * @param array $parameterNames * @return array */ public function parameters(array $parameterNames) { return collect($parameterNames)->map(function ($parameterName) { return $this->parameter($parameterName); })->toArray(); } /** * Determine whether the cursor points to the next set of items. * * @return bool */ public function pointsToNextItems() { return $this->pointsToNextItems; } /** * Determine whether the cursor points to the previous set of items. * * @return bool */ public function pointsToPreviousItems() { return ! $this->pointsToNextItems; } /** * Get the array representation of the cursor. * * @return array */ public function toArray() { return array_merge($this->parameters, [ '_pointsToNextItems' => $this->pointsToNextItems, ]); } /** * Get the encoded string representation of the cursor to construct a URL. * * @return string */ public function encode() { return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode(json_encode($this->toArray()))); } /** * Get a cursor instance from the encoded string representation. * * @param string|null $encodedString * @return static|null */ public static function fromEncoded($encodedString) { if (is_null($encodedString) || ! is_string($encodedString)) { return null; } $parameters = json_decode(base64_decode(str_replace(['-', '_'], ['+', '/'], $encodedString)), true); if (json_last_error() !== JSON_ERROR_NONE) { return null; } $pointsToNextItems = $parameters['_pointsToNextItems']; unset($parameters['_pointsToNextItems']); return new static($parameters, $pointsToNextItems); } } src/Illuminate/Pagination/resources/views/simple-default.blade.php 0000644 00000001405 15052151126 0021366 0 ustar 00 @if ($paginator->hasPages()) @endif src/Illuminate/Pagination/resources/views/semantic-ui.blade.php 0000644 00000003222 15052151126 0020670 0 ustar 00 @if ($paginator->hasPages()) @endif src/Illuminate/Pagination/resources/views/tailwind.blade.php 0000644 00000017232 15052151126 0020273 0 ustar 00 @if ($paginator->hasPages()) @endif src/Illuminate/Pagination/resources/views/simple-bootstrap-4.blade.php 0000644 00000002035 15052151126 0022120 0 ustar 00 @if ($paginator->hasPages()) @endif src/Illuminate/Pagination/resources/views/bootstrap-4.blade.php 0000644 00000004044 15052151126 0020633 0 ustar 00 @if ($paginator->hasPages()) @endif src/Illuminate/Pagination/resources/views/simple-tailwind.blade.php 0000644 00000003243 15052151126 0021557 0 ustar 00 @if ($paginator->hasPages()) @endif src/Illuminate/Pagination/resources/views/default.blade.php 0000644 00000003510 15052151126 0020076 0 ustar 00 @if ($paginator->hasPages()) @endif src/Illuminate/Pagination/LengthAwarePaginator.php 0000644 00000014067 15052151126 0016314 0 ustar 00 options = $options; foreach ($options as $key => $value) { $this->{$key} = $value; } $this->total = $total; $this->perPage = $perPage; $this->lastPage = max((int) ceil($total / $perPage), 1); $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path; $this->currentPage = $this->setCurrentPage($currentPage, $this->pageName); $this->items = $items instanceof Collection ? $items : Collection::make($items); } /** * Get the current page for the request. * * @param int $currentPage * @param string $pageName * @return int */ protected function setCurrentPage($currentPage, $pageName) { $currentPage = $currentPage ?: static::resolveCurrentPage($pageName); return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1; } /** * Render the paginator using the given view. * * @param string|null $view * @param array $data * @return \Illuminate\Contracts\Support\Htmlable */ public function links($view = null, $data = []) { return $this->render($view, $data); } /** * Render the paginator using the given view. * * @param string|null $view * @param array $data * @return \Illuminate\Contracts\Support\Htmlable */ public function render($view = null, $data = []) { return static::viewFactory()->make($view ?: static::$defaultView, array_merge($data, [ 'paginator' => $this, 'elements' => $this->elements(), ])); } /** * Get the paginator links as a collection (for JSON responses). * * @return \Illuminate\Support\Collection */ public function linkCollection() { return collect($this->elements())->flatMap(function ($item) { if (! is_array($item)) { return [['url' => null, 'label' => '...', 'active' => false]]; } return collect($item)->map(function ($url, $page) { return [ 'url' => $url, 'label' => (string) $page, 'active' => $this->currentPage() === $page, ]; }); })->prepend([ 'url' => $this->previousPageUrl(), 'label' => function_exists('__') ? __('pagination.previous') : 'Previous', 'active' => false, ])->push([ 'url' => $this->nextPageUrl(), 'label' => function_exists('__') ? __('pagination.next') : 'Next', 'active' => false, ]); } /** * Get the array of elements to pass to the view. * * @return array */ protected function elements() { $window = UrlWindow::make($this); return array_filter([ $window['first'], is_array($window['slider']) ? '...' : null, $window['slider'], is_array($window['last']) ? '...' : null, $window['last'], ]); } /** * Get the total number of items being paginated. * * @return int */ public function total() { return $this->total; } /** * Determine if there are more items in the data source. * * @return bool */ public function hasMorePages() { return $this->currentPage() < $this->lastPage(); } /** * Get the URL for the next page. * * @return string|null */ public function nextPageUrl() { if ($this->hasMorePages()) { return $this->url($this->currentPage() + 1); } } /** * Get the last page. * * @return int */ public function lastPage() { return $this->lastPage; } /** * Get the instance as an array. * * @return array */ public function toArray() { return [ 'current_page' => $this->currentPage(), 'data' => $this->items->toArray(), 'first_page_url' => $this->url(1), 'from' => $this->firstItem(), 'last_page' => $this->lastPage(), 'last_page_url' => $this->url($this->lastPage()), 'links' => $this->linkCollection()->toArray(), 'next_page_url' => $this->nextPageUrl(), 'path' => $this->path(), 'per_page' => $this->perPage(), 'prev_page_url' => $this->previousPageUrl(), 'to' => $this->lastItem(), 'total' => $this->total(), ]; } /** * Convert the object into something JSON serializable. * * @return array */ #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->toArray(); } /** * Convert the object to its JSON representation. * * @param int $options * @return string */ public function toJson($options = 0) { return json_encode($this->jsonSerialize(), $options); } } src/Illuminate/Pagination/PaginationState.php 0000644 00000002225 15052151126 0015331 0 ustar 00 url(); }); Paginator::currentPageResolver(function ($pageName = 'page') use ($app) { $page = $app['request']->input($pageName); if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) { return (int) $page; } return 1; }); Paginator::queryStringResolver(function () use ($app) { return $app['request']->query(); }); CursorPaginator::currentCursorResolver(function ($cursorName = 'cursor') use ($app) { return Cursor::fromEncoded($app['request']->input($cursorName)); }); } } src/Illuminate/Container/RewindableGenerator.php 0000644 00000002171 15052151126 0016013 0 ustar 00 count = $count; $this->generator = $generator; } /** * Get an iterator from the generator. * * @return mixed */ #[\ReturnTypeWillChange] public function getIterator() { return ($this->generator)(); } /** * Get the total number of tagged services. * * @return int */ #[\ReturnTypeWillChange] public function count() { if (is_callable($count = $this->count)) { $this->count = $count(); } return $this->count; } } src/Illuminate/Container/LICENSE.md 0000644 00000002063 15052151126 0012763 0 ustar 00 The MIT License (MIT) Copyright (c) Taylor Otwell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. src/Illuminate/Container/Util.php 0000644 00000003144 15052151126 0013006 0 ustar 00 getType(); if (! $type instanceof ReflectionNamedType || $type->isBuiltin()) { return null; } $name = $type->getName(); if (! is_null($class = $parameter->getDeclaringClass())) { if ($name === 'self') { return $class->getName(); } if ($name === 'parent' && $parent = $class->getParentClass()) { return $parent->getName(); } } return $name; } } src/Illuminate/Container/EntryNotFoundException.php 0000644 00000000306 15052151126 0016523 0 ustar 00 getAlias($c); } return new ContextualBindingBuilder($this, $aliases); } /** * Determine if the given abstract type has been bound. * * @param string $abstract * @return bool */ public function bound($abstract) { return isset($this->bindings[$abstract]) || isset($this->instances[$abstract]) || $this->isAlias($abstract); } /** * {@inheritdoc} * * @return bool */ public function has($id) { return $this->bound($id); } /** * Determine if the given abstract type has been resolved. * * @param string $abstract * @return bool */ public function resolved($abstract) { if ($this->isAlias($abstract)) { $abstract = $this->getAlias($abstract); } return isset($this->resolved[$abstract]) || isset($this->instances[$abstract]); } /** * Determine if a given type is shared. * * @param string $abstract * @return bool */ public function isShared($abstract) { return isset($this->instances[$abstract]) || (isset($this->bindings[$abstract]['shared']) && $this->bindings[$abstract]['shared'] === true); } /** * Determine if a given string is an alias. * * @param string $name * @return bool */ public function isAlias($name) { return isset($this->aliases[$name]); } /** * Register a binding with the container. * * @param string $abstract * @param \Closure|string|null $concrete * @param bool $shared * @return void * * @throws \TypeError */ public function bind($abstract, $concrete = null, $shared = false) { $this->dropStaleInstances($abstract); // If no concrete type was given, we will simply set the concrete type to the // abstract type. After that, the concrete type to be registered as shared // without being forced to state their classes in both of the parameters. if (is_null($concrete)) { $concrete = $abstract; } // If the factory is not a Closure, it means it is just a class name which is // bound into this container to the abstract type and we will just wrap it // up inside its own Closure to give us more convenience when extending. if (! $concrete instanceof Closure) { if (! is_string($concrete)) { throw new TypeError(self::class.'::bind(): Argument #2 ($concrete) must be of type Closure|string|null'); } $concrete = $this->getClosure($abstract, $concrete); } $this->bindings[$abstract] = compact('concrete', 'shared'); // If the abstract type was already resolved in this container we'll fire the // rebound listener so that any objects which have already gotten resolved // can have their copy of the object updated via the listener callbacks. if ($this->resolved($abstract)) { $this->rebound($abstract); } } /** * Get the Closure to be used when building a type. * * @param string $abstract * @param string $concrete * @return \Closure */ protected function getClosure($abstract, $concrete) { return function ($container, $parameters = []) use ($abstract, $concrete) { if ($abstract == $concrete) { return $container->build($concrete); } return $container->resolve( $concrete, $parameters, $raiseEvents = false ); }; } /** * Determine if the container has a method binding. * * @param string $method * @return bool */ public function hasMethodBinding($method) { return isset($this->methodBindings[$method]); } /** * Bind a callback to resolve with Container::call. * * @param array|string $method * @param \Closure $callback * @return void */ public function bindMethod($method, $callback) { $this->methodBindings[$this->parseBindMethod($method)] = $callback; } /** * Get the method to be bound in class@method format. * * @param array|string $method * @return string */ protected function parseBindMethod($method) { if (is_array($method)) { return $method[0].'@'.$method[1]; } return $method; } /** * Get the method binding for the given method. * * @param string $method * @param mixed $instance * @return mixed */ public function callMethodBinding($method, $instance) { return call_user_func($this->methodBindings[$method], $instance, $this); } /** * Add a contextual binding to the container. * * @param string $concrete * @param string $abstract * @param \Closure|string $implementation * @return void */ public function addContextualBinding($concrete, $abstract, $implementation) { $this->contextual[$concrete][$this->getAlias($abstract)] = $implementation; } /** * Register a binding if it hasn't already been registered. * * @param string $abstract * @param \Closure|string|null $concrete * @param bool $shared * @return void */ public function bindIf($abstract, $concrete = null, $shared = false) { if (! $this->bound($abstract)) { $this->bind($abstract, $concrete, $shared); } } /** * Register a shared binding in the container. * * @param string $abstract * @param \Closure|string|null $concrete * @return void */ public function singleton($abstract, $concrete = null) { $this->bind($abstract, $concrete, true); } /** * Register a shared binding if it hasn't already been registered. * * @param string $abstract * @param \Closure|string|null $concrete * @return void */ public function singletonIf($abstract, $concrete = null) { if (! $this->bound($abstract)) { $this->singleton($abstract, $concrete); } } /** * Register a scoped binding in the container. * * @param string $abstract * @param \Closure|string|null $concrete * @return void */ public function scoped($abstract, $concrete = null) { $this->scopedInstances[] = $abstract; $this->singleton($abstract, $concrete); } /** * Register a scoped binding if it hasn't already been registered. * * @param string $abstract * @param \Closure|string|null $concrete * @return void */ public function scopedIf($abstract, $concrete = null) { if (! $this->bound($abstract)) { $this->scopedInstances[] = $abstract; $this->singleton($abstract, $concrete); } } /** * "Extend" an abstract type in the container. * * @param string $abstract * @param \Closure $closure * @return void * * @throws \InvalidArgumentException */ public function extend($abstract, Closure $closure) { $abstract = $this->getAlias($abstract); if (isset($this->instances[$abstract])) { $this->instances[$abstract] = $closure($this->instances[$abstract], $this); $this->rebound($abstract); } else { $this->extenders[$abstract][] = $closure; if ($this->resolved($abstract)) { $this->rebound($abstract); } } } /** * Register an existing instance as shared in the container. * * @param string $abstract * @param mixed $instance * @return mixed */ public function instance($abstract, $instance) { $this->removeAbstractAlias($abstract); $isBound = $this->bound($abstract); unset($this->aliases[$abstract]); // We'll check to determine if this type has been bound before, and if it has // we will fire the rebound callbacks registered with the container and it // can be updated with consuming classes that have gotten resolved here. $this->instances[$abstract] = $instance; if ($isBound) { $this->rebound($abstract); } return $instance; } /** * Remove an alias from the contextual binding alias cache. * * @param string $searched * @return void */ protected function removeAbstractAlias($searched) { if (! isset($this->aliases[$searched])) { return; } foreach ($this->abstractAliases as $abstract => $aliases) { foreach ($aliases as $index => $alias) { if ($alias == $searched) { unset($this->abstractAliases[$abstract][$index]); } } } } /** * Assign a set of tags to a given binding. * * @param array|string $abstracts * @param array|mixed ...$tags * @return void */ public function tag($abstracts, $tags) { $tags = is_array($tags) ? $tags : array_slice(func_get_args(), 1); foreach ($tags as $tag) { if (! isset($this->tags[$tag])) { $this->tags[$tag] = []; } foreach ((array) $abstracts as $abstract) { $this->tags[$tag][] = $abstract; } } } /** * Resolve all of the bindings for a given tag. * * @param string $tag * @return iterable */ public function tagged($tag) { if (! isset($this->tags[$tag])) { return []; } return new RewindableGenerator(function () use ($tag) { foreach ($this->tags[$tag] as $abstract) { yield $this->make($abstract); } }, count($this->tags[$tag])); } /** * Alias a type to a different name. * * @param string $abstract * @param string $alias * @return void * * @throws \LogicException */ public function alias($abstract, $alias) { if ($alias === $abstract) { throw new LogicException("[{$abstract}] is aliased to itself."); } $this->aliases[$alias] = $abstract; $this->abstractAliases[$abstract][] = $alias; } /** * Bind a new callback to an abstract's rebind event. * * @param string $abstract * @param \Closure $callback * @return mixed */ public function rebinding($abstract, Closure $callback) { $this->reboundCallbacks[$abstract = $this->getAlias($abstract)][] = $callback; if ($this->bound($abstract)) { return $this->make($abstract); } } /** * Refresh an instance on the given target and method. * * @param string $abstract * @param mixed $target * @param string $method * @return mixed */ public function refresh($abstract, $target, $method) { return $this->rebinding($abstract, function ($app, $instance) use ($target, $method) { $target->{$method}($instance); }); } /** * Fire the "rebound" callbacks for the given abstract type. * * @param string $abstract * @return void */ protected function rebound($abstract) { $instance = $this->make($abstract); foreach ($this->getReboundCallbacks($abstract) as $callback) { call_user_func($callback, $this, $instance); } } /** * Get the rebound callbacks for a given type. * * @param string $abstract * @return array */ protected function getReboundCallbacks($abstract) { return $this->reboundCallbacks[$abstract] ?? []; } /** * Wrap the given closure such that its dependencies will be injected when executed. * * @param \Closure $callback * @param array $parameters * @return \Closure */ public function wrap(Closure $callback, array $parameters = []) { return function () use ($callback, $parameters) { return $this->call($callback, $parameters); }; } /** * Call the given Closure / class@method and inject its dependencies. * * @param callable|string $callback * @param array
|
{{ Illuminate\Mail\Markdown::parse($slot) }} |
|
|
{{ Illuminate\Mail\Markdown::parse($slot) }} |