first commit

This commit is contained in:
2026-02-08 21:16:11 +01:00
commit e17b7026fd
8881 changed files with 1160453 additions and 0 deletions

View File

@@ -0,0 +1,413 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
use _JchOptimizeVendor\Carbon\CarbonImmutable;
use _JchOptimizeVendor\Illuminate\Contracts\Queue\Factory as QueueFactory;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Arrayable;
use _JchOptimizeVendor\Illuminate\Queue\CallQueuedClosure;
use _JchOptimizeVendor\Illuminate\Support\Arr;
use _JchOptimizeVendor\Illuminate\Support\Collection;
class Batch implements Arrayable, \JsonSerializable
{
/**
* The batch ID.
*
* @var string
*/
public $id;
/**
* The batch name.
*
* @var string
*/
public $name;
/**
* The total number of jobs that belong to the batch.
*
* @var int
*/
public $totalJobs;
/**
* The total number of jobs that are still pending.
*
* @var int
*/
public $pendingJobs;
/**
* The total number of jobs that have failed.
*
* @var int
*/
public $failedJobs;
/**
* The IDs of the jobs that have failed.
*
* @var array
*/
public $failedJobIds;
/**
* The batch options.
*
* @var array
*/
public $options;
/**
* The date indicating when the batch was created.
*
* @var \Carbon\CarbonImmutable
*/
public $createdAt;
/**
* The date indicating when the batch was cancelled.
*
* @var null|\Carbon\CarbonImmutable
*/
public $cancelledAt;
/**
* The date indicating when the batch was finished.
*
* @var null|\Carbon\CarbonImmutable
*/
public $finishedAt;
/**
* The queue factory implementation.
*
* @var \Illuminate\Contracts\Queue\Factory
*/
protected $queue;
/**
* The repository implementation.
*
* @var \Illuminate\Bus\BatchRepository
*/
protected $repository;
/**
* Create a new batch instance.
*
* @param \Illuminate\Contracts\Queue\Factory $queue
* @param \Illuminate\Bus\BatchRepository $repository
* @param \Carbon\CarbonImmutable $createdAt
* @param null|\Carbon\CarbonImmutable $cancelledAt
* @param null|\Carbon\CarbonImmutable $finishedAt
*/
public function __construct(QueueFactory $queue, BatchRepository $repository, string $id, string $name, int $totalJobs, int $pendingJobs, int $failedJobs, array $failedJobIds, array $options, CarbonImmutable $createdAt, ?CarbonImmutable $cancelledAt = null, ?CarbonImmutable $finishedAt = null)
{
$this->queue = $queue;
$this->repository = $repository;
$this->id = $id;
$this->name = $name;
$this->totalJobs = $totalJobs;
$this->pendingJobs = $pendingJobs;
$this->failedJobs = $failedJobs;
$this->failedJobIds = $failedJobIds;
$this->options = $options;
$this->createdAt = $createdAt;
$this->cancelledAt = $cancelledAt;
$this->finishedAt = $finishedAt;
}
/**
* Dynamically access the batch's "options" via properties.
*
* @param string $key
*
* @return mixed
*/
public function __get($key)
{
return $this->options[$key] ?? null;
}
/**
* Get a fresh instance of the batch represented by this ID.
*
* @return self
*/
public function fresh()
{
return $this->repository->find($this->id);
}
/**
* Add additional jobs to the batch.
*
* @param array|\Illuminate\Support\Enumerable $jobs
*
* @return self
*/
public function add($jobs)
{
$count = 0;
$jobs = Collection::wrap($jobs)->map(function ($job) use (&$count) {
$job = $job instanceof \Closure ? CallQueuedClosure::create($job) : $job;
if (\is_array($job)) {
$count += \count($job);
return with($this->prepareBatchedChain($job), function ($chain) {
return $chain->first()->allOnQueue($this->options['queue'] ?? null)->allOnConnection($this->options['connection'] ?? null)->chain($chain->slice(1)->values()->all());
});
} else {
$job->withBatchId($this->id);
++$count;
}
return $job;
});
$this->repository->transaction(function () use ($jobs, $count) {
$this->repository->incrementTotalJobs($this->id, $count);
$this->queue->connection($this->options['connection'] ?? null)->bulk($jobs->all(), $data = '', $this->options['queue'] ?? null);
});
return $this->fresh();
}
/**
* Get the total number of jobs that have been processed by the batch thus far.
*
* @return int
*/
public function processedJobs()
{
return $this->totalJobs - $this->pendingJobs;
}
/**
* Get the percentage of jobs that have been processed (between 0-100).
*
* @return int
*/
public function progress()
{
return $this->totalJobs > 0 ? \round($this->processedJobs() / $this->totalJobs * 100) : 0;
}
/**
* Record that a job within the batch finished successfully, executing any callbacks if necessary.
*/
public function recordSuccessfulJob(string $jobId)
{
$counts = $this->decrementPendingJobs($jobId);
if (0 === $counts->pendingJobs) {
$this->repository->markAsFinished($this->id);
}
if (0 === $counts->pendingJobs && $this->hasThenCallbacks()) {
$batch = $this->fresh();
collect($this->options['then'])->each(function ($handler) use ($batch) {
$this->invokeHandlerCallback($handler, $batch);
});
}
if ($counts->allJobsHaveRanExactlyOnce() && $this->hasFinallyCallbacks()) {
$batch = $this->fresh();
collect($this->options['finally'])->each(function ($handler) use ($batch) {
$this->invokeHandlerCallback($handler, $batch);
});
}
}
/**
* Decrement the pending jobs for the batch.
*
* @return \Illuminate\Bus\UpdatedBatchJobCounts
*/
public function decrementPendingJobs(string $jobId)
{
return $this->repository->decrementPendingJobs($this->id, $jobId);
}
/**
* Determine if the batch has finished executing.
*
* @return bool
*/
public function finished()
{
return !\is_null($this->finishedAt);
}
/**
* Determine if the batch has "success" callbacks.
*
* @return bool
*/
public function hasThenCallbacks()
{
return isset($this->options['then']) && !empty($this->options['then']);
}
/**
* Determine if the batch allows jobs to fail without cancelling the batch.
*
* @return bool
*/
public function allowsFailures()
{
return \true === Arr::get($this->options, 'allowFailures', \false);
}
/**
* Determine if the batch has job failures.
*
* @return bool
*/
public function hasFailures()
{
return $this->failedJobs > 0;
}
/**
* Record that a job within the batch failed to finish successfully, executing any callbacks if necessary.
*
* @param \Throwable $e
*/
public function recordFailedJob(string $jobId, $e)
{
$counts = $this->incrementFailedJobs($jobId);
if (1 === $counts->failedJobs && !$this->allowsFailures()) {
$this->cancel();
}
if (1 === $counts->failedJobs && $this->hasCatchCallbacks()) {
$batch = $this->fresh();
collect($this->options['catch'])->each(function ($handler) use ($batch, $e) {
$this->invokeHandlerCallback($handler, $batch, $e);
});
}
if ($counts->allJobsHaveRanExactlyOnce() && $this->hasFinallyCallbacks()) {
$batch = $this->fresh();
collect($this->options['finally'])->each(function ($handler) use ($batch, $e) {
$this->invokeHandlerCallback($handler, $batch, $e);
});
}
}
/**
* Increment the failed jobs for the batch.
*
* @return \Illuminate\Bus\UpdatedBatchJobCounts
*/
public function incrementFailedJobs(string $jobId)
{
return $this->repository->incrementFailedJobs($this->id, $jobId);
}
/**
* Determine if the batch has "catch" callbacks.
*
* @return bool
*/
public function hasCatchCallbacks()
{
return isset($this->options['catch']) && !empty($this->options['catch']);
}
/**
* Determine if the batch has "finally" callbacks.
*
* @return bool
*/
public function hasFinallyCallbacks()
{
return isset($this->options['finally']) && !empty($this->options['finally']);
}
/**
* Cancel the batch.
*/
public function cancel()
{
$this->repository->cancel($this->id);
}
/**
* Determine if the batch has been cancelled.
*
* @return bool
*/
public function canceled()
{
return $this->cancelled();
}
/**
* Determine if the batch has been cancelled.
*
* @return bool
*/
public function cancelled()
{
return !\is_null($this->cancelledAt);
}
/**
* Delete the batch from storage.
*/
public function delete()
{
$this->repository->delete($this->id);
}
/**
* Convert the batch to an array.
*
* @return array
*/
public function toArray()
{
return ['id' => $this->id, 'name' => $this->name, 'totalJobs' => $this->totalJobs, 'pendingJobs' => $this->pendingJobs, 'processedJobs' => $this->processedJobs(), 'progress' => $this->progress(), 'failedJobs' => $this->failedJobs, 'options' => $this->options, 'createdAt' => $this->createdAt, 'cancelledAt' => $this->cancelledAt, 'finishedAt' => $this->finishedAt];
}
/**
* Get the JSON serializable representation of the object.
*
* @return array
*/
#[\ReturnTypeWillChange]
public function jsonSerialize()
{
return $this->toArray();
}
/**
* Prepare a chain that exists within the jobs being added.
*
* @return \Illuminate\Support\Collection
*/
protected function prepareBatchedChain(array $chain)
{
return collect($chain)->map(function ($job) {
$job = $job instanceof \Closure ? CallQueuedClosure::create($job) : $job;
return $job->withBatchId($this->id);
});
}
/**
* Invoke a batch callback handler.
*
* @param callable $handler
* @param \Illuminate\Bus\Batch $batch
*/
protected function invokeHandlerCallback($handler, Batch $batch, \Throwable $e = null)
{
try {
return $handler($batch, $e);
} catch (\Throwable $e) {
if (\function_exists('_JchOptimizeVendor\\report')) {
report($e);
}
}
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
use _JchOptimizeVendor\Carbon\CarbonImmutable;
use _JchOptimizeVendor\Illuminate\Contracts\Queue\Factory as QueueFactory;
class BatchFactory
{
/**
* The queue factory implementation.
*
* @var \Illuminate\Contracts\Queue\Factory
*/
protected $queue;
/**
* Create a new batch factory instance.
*
* @param \Illuminate\Contracts\Queue\Factory $queue
*/
public function __construct(QueueFactory $queue)
{
$this->queue = $queue;
}
/**
* Create a new batch instance.
*
* @param \Illuminate\Bus\BatchRepository $repository
* @param \Carbon\CarbonImmutable $createdAt
* @param null|\Carbon\CarbonImmutable $cancelledAt
* @param null|\Carbon\CarbonImmutable $finishedAt
*
* @return \Illuminate\Bus\Batch
*/
public function make(BatchRepository $repository, string $id, string $name, int $totalJobs, int $pendingJobs, int $failedJobs, array $failedJobIds, array $options, CarbonImmutable $createdAt, ?CarbonImmutable $cancelledAt, ?CarbonImmutable $finishedAt)
{
return new Batch($this->queue, $repository, $id, $name, $totalJobs, $pendingJobs, $failedJobs, $failedJobIds, $options, $createdAt, $cancelledAt, $finishedAt);
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
use Closure;
interface BatchRepository
{
/**
* Retrieve a list of batches.
*
* @param int $limit
* @param mixed $before
*
* @return \Illuminate\Bus\Batch[]
*/
public function get($limit, $before);
/**
* Retrieve information about an existing batch.
*
* @return null|\Illuminate\Bus\Batch
*/
public function find(string $batchId);
/**
* Store a new pending batch.
*
* @param \Illuminate\Bus\PendingBatch $batch
*
* @return \Illuminate\Bus\Batch
*/
public function store(PendingBatch $batch);
/**
* Increment the total number of jobs within the batch.
*/
public function incrementTotalJobs(string $batchId, int $amount);
/**
* Decrement the total number of pending jobs for the batch.
*
* @return \Illuminate\Bus\UpdatedBatchJobCounts
*/
public function decrementPendingJobs(string $batchId, string $jobId);
/**
* Increment the total number of failed jobs for the batch.
*
* @return \Illuminate\Bus\UpdatedBatchJobCounts
*/
public function incrementFailedJobs(string $batchId, string $jobId);
/**
* Mark the batch that has the given ID as finished.
*/
public function markAsFinished(string $batchId);
/**
* Cancel the batch that has the given ID.
*/
public function cancel(string $batchId);
/**
* Delete the batch that has the given ID.
*/
public function delete(string $batchId);
/**
* Execute the given Closure within a storage specific transaction.
*
* @return mixed
*/
public function transaction(\Closure $callback);
}

View File

@@ -0,0 +1,51 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
use _JchOptimizeVendor\Illuminate\Container\Container;
trait Batchable
{
/**
* The batch ID (if applicable).
*
* @var string
*/
public $batchId;
/**
* Get the batch instance for the job, if applicable.
*
* @return null|\Illuminate\Bus\Batch
*/
public function batch()
{
if ($this->batchId) {
return Container::getInstance()->make(BatchRepository::class)->find($this->batchId);
}
}
/**
* Determine if the batch is still active and processing.
*
* @return bool
*/
public function batching()
{
$batch = $this->batch();
return $batch && !$batch->cancelled();
}
/**
* Set the batch ID on the job.
*
* @return $this
*/
public function withBatchId(string $batchId)
{
$this->batchId = $batchId;
return $this;
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
use _JchOptimizeVendor\Illuminate\Contracts\Bus\Dispatcher as DispatcherContract;
use _JchOptimizeVendor\Illuminate\Contracts\Bus\QueueingDispatcher as QueueingDispatcherContract;
use _JchOptimizeVendor\Illuminate\Contracts\Queue\Factory as QueueFactoryContract;
use _JchOptimizeVendor\Illuminate\Contracts\Support\DeferrableProvider;
use _JchOptimizeVendor\Illuminate\Support\ServiceProvider;
class BusServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register the service provider.
*/
public function register()
{
$this->app->singleton(Dispatcher::class, function ($app) {
return new Dispatcher($app, function ($connection = null) use ($app) {
return $app[QueueFactoryContract::class]->connection($connection);
});
});
$this->registerBatchServices();
$this->app->alias(Dispatcher::class, DispatcherContract::class);
$this->app->alias(Dispatcher::class, QueueingDispatcherContract::class);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [Dispatcher::class, DispatcherContract::class, QueueingDispatcherContract::class, BatchRepository::class];
}
/**
* Register the batch handling services.
*/
protected function registerBatchServices()
{
$this->app->singleton(BatchRepository::class, DatabaseBatchRepository::class);
$this->app->singleton(DatabaseBatchRepository::class, function ($app) {
return new DatabaseBatchRepository($app->make(BatchFactory::class), $app->make('db')->connection($app->config->get('queue.batching.database')), $app->config->get('queue.batching.table', 'job_batches'));
});
}
}

View File

@@ -0,0 +1,256 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
use _JchOptimizeVendor\Carbon\CarbonImmutable;
use _JchOptimizeVendor\Illuminate\Database\Connection;
use _JchOptimizeVendor\Illuminate\Database\PostgresConnection;
use _JchOptimizeVendor\Illuminate\Database\Query\Expression;
use _JchOptimizeVendor\Illuminate\Support\Str;
use Closure;
class DatabaseBatchRepository implements PrunableBatchRepository
{
/**
* The batch factory instance.
*
* @var \Illuminate\Bus\BatchFactory
*/
protected $factory;
/**
* The database connection instance.
*
* @var \Illuminate\Database\Connection
*/
protected $connection;
/**
* The database table to use to store batch information.
*
* @var string
*/
protected $table;
/**
* Create a new batch repository instance.
*
* @param \Illuminate\Bus\BatchFactory $factory
* @param \Illuminate\Database\Connection $connection
*/
public function __construct(BatchFactory $factory, Connection $connection, string $table)
{
$this->factory = $factory;
$this->connection = $connection;
$this->table = $table;
}
/**
* Retrieve a list of batches.
*
* @param int $limit
* @param mixed $before
*
* @return \Illuminate\Bus\Batch[]
*/
public function get($limit = 50, $before = null)
{
return $this->connection->table($this->table)->orderByDesc('id')->take($limit)->when($before, function ($q) use ($before) {
return $q->where('id', '<', $before);
})->get()->map(function ($batch) {
return $this->toBatch($batch);
})->all();
}
/**
* Retrieve information about an existing batch.
*
* @return null|\Illuminate\Bus\Batch
*/
public function find(string $batchId)
{
$batch = $this->connection->table($this->table)->where('id', $batchId)->first();
if ($batch) {
return $this->toBatch($batch);
}
}
/**
* Store a new pending batch.
*
* @param \Illuminate\Bus\PendingBatch $batch
*
* @return \Illuminate\Bus\Batch
*/
public function store(PendingBatch $batch)
{
$id = (string) Str::orderedUuid();
$this->connection->table($this->table)->insert(['id' => $id, 'name' => $batch->name, 'total_jobs' => 0, 'pending_jobs' => 0, 'failed_jobs' => 0, 'failed_job_ids' => '[]', 'options' => $this->serialize($batch->options), 'created_at' => \time(), 'cancelled_at' => null, 'finished_at' => null]);
return $this->find($id);
}
/**
* Increment the total number of jobs within the batch.
*/
public function incrementTotalJobs(string $batchId, int $amount)
{
$this->connection->table($this->table)->where('id', $batchId)->update(['total_jobs' => new Expression('total_jobs + '.$amount), 'pending_jobs' => new Expression('pending_jobs + '.$amount), 'finished_at' => null]);
}
/**
* Decrement the total number of pending jobs for the batch.
*
* @return \Illuminate\Bus\UpdatedBatchJobCounts
*/
public function decrementPendingJobs(string $batchId, string $jobId)
{
$values = $this->updateAtomicValues($batchId, function ($batch) use ($jobId) {
return ['pending_jobs' => $batch->pending_jobs - 1, 'failed_jobs' => $batch->failed_jobs, 'failed_job_ids' => \json_encode(\array_values(\array_diff(\json_decode($batch->failed_job_ids, \true), [$jobId])))];
});
return new UpdatedBatchJobCounts($values['pending_jobs'], $values['failed_jobs']);
}
/**
* Increment the total number of failed jobs for the batch.
*
* @return \Illuminate\Bus\UpdatedBatchJobCounts
*/
public function incrementFailedJobs(string $batchId, string $jobId)
{
$values = $this->updateAtomicValues($batchId, function ($batch) use ($jobId) {
return ['pending_jobs' => $batch->pending_jobs, 'failed_jobs' => $batch->failed_jobs + 1, 'failed_job_ids' => \json_encode(\array_values(\array_unique(\array_merge(\json_decode($batch->failed_job_ids, \true), [$jobId]))))];
});
return new UpdatedBatchJobCounts($values['pending_jobs'], $values['failed_jobs']);
}
/**
* Mark the batch that has the given ID as finished.
*/
public function markAsFinished(string $batchId)
{
$this->connection->table($this->table)->where('id', $batchId)->update(['finished_at' => \time()]);
}
/**
* Cancel the batch that has the given ID.
*/
public function cancel(string $batchId)
{
$this->connection->table($this->table)->where('id', $batchId)->update(['cancelled_at' => \time(), 'finished_at' => \time()]);
}
/**
* Delete the batch that has the given ID.
*/
public function delete(string $batchId)
{
$this->connection->table($this->table)->where('id', $batchId)->delete();
}
/**
* Prune all of the entries older than the given date.
*
* @return int
*/
public function prune(\DateTimeInterface $before)
{
$query = $this->connection->table($this->table)->whereNotNull('finished_at')->where('finished_at', '<', $before->getTimestamp());
$totalDeleted = 0;
do {
$deleted = $query->take(1000)->delete();
$totalDeleted += $deleted;
} while (0 !== $deleted);
return $totalDeleted;
}
/**
* Prune all of the unfinished entries older than the given date.
*
* @return int
*/
public function pruneUnfinished(\DateTimeInterface $before)
{
$query = $this->connection->table($this->table)->whereNull('finished_at')->where('created_at', '<', $before->getTimestamp());
$totalDeleted = 0;
do {
$deleted = $query->take(1000)->delete();
$totalDeleted += $deleted;
} while (0 !== $deleted);
return $totalDeleted;
}
/**
* Execute the given Closure within a storage specific transaction.
*
* @return mixed
*/
public function transaction(\Closure $callback)
{
return $this->connection->transaction(function () use ($callback) {
return $callback();
});
}
/**
* Update an atomic value within the batch.
*
* @return null|int
*/
protected function updateAtomicValues(string $batchId, \Closure $callback)
{
return $this->connection->transaction(function () use ($batchId, $callback) {
$batch = $this->connection->table($this->table)->where('id', $batchId)->lockForUpdate()->first();
return \is_null($batch) ? [] : tap($callback($batch), function ($values) use ($batchId) {
$this->connection->table($this->table)->where('id', $batchId)->update($values);
});
});
}
/**
* Serialize the given value.
*
* @param mixed $value
*
* @return string
*/
protected function serialize($value)
{
$serialized = \serialize($value);
return $this->connection instanceof PostgresConnection ? \base64_encode($serialized) : $serialized;
}
/**
* Unserialize the given value.
*
* @param string $serialized
*
* @return mixed
*/
protected function unserialize($serialized)
{
if ($this->connection instanceof PostgresConnection && !Str::contains($serialized, [':', ';'])) {
$serialized = \base64_decode($serialized);
}
return \unserialize($serialized);
}
/**
* Convert the given raw batch to a Batch object.
*
* @param object $batch
*
* @return \Illuminate\Bus\Batch
*/
protected function toBatch($batch)
{
return $this->factory->make($this, $batch->id, $batch->name, (int) $batch->total_jobs, (int) $batch->pending_jobs, (int) $batch->failed_jobs, \json_decode($batch->failed_job_ids, \true), $this->unserialize($batch->options), CarbonImmutable::createFromTimestamp($batch->created_at), $batch->cancelled_at ? CarbonImmutable::createFromTimestamp($batch->cancelled_at) : $batch->cancelled_at, $batch->finished_at ? CarbonImmutable::createFromTimestamp($batch->finished_at) : $batch->finished_at);
}
}

View File

@@ -0,0 +1,284 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
use _JchOptimizeVendor\Illuminate\Contracts\Bus\QueueingDispatcher;
use _JchOptimizeVendor\Illuminate\Contracts\Container\Container;
use _JchOptimizeVendor\Illuminate\Contracts\Queue\Queue;
use _JchOptimizeVendor\Illuminate\Contracts\Queue\ShouldQueue;
use _JchOptimizeVendor\Illuminate\Foundation\Bus\PendingChain;
use _JchOptimizeVendor\Illuminate\Pipeline\Pipeline;
use _JchOptimizeVendor\Illuminate\Queue\InteractsWithQueue;
use _JchOptimizeVendor\Illuminate\Queue\Jobs\SyncJob;
use _JchOptimizeVendor\Illuminate\Support\Collection;
class Dispatcher implements QueueingDispatcher
{
/**
* The container implementation.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* The pipeline instance for the bus.
*
* @var \Illuminate\Pipeline\Pipeline
*/
protected $pipeline;
/**
* The pipes to send commands through before dispatching.
*
* @var array
*/
protected $pipes = [];
/**
* The command to handler mapping for non-self-handling events.
*
* @var array
*/
protected $handlers = [];
/**
* The queue resolver callback.
*
* @var null|\Closure
*/
protected $queueResolver;
/**
* Create a new command dispatcher instance.
*
* @param \Illuminate\Contracts\Container\Container $container
*/
public function __construct(Container $container, \Closure $queueResolver = null)
{
$this->container = $container;
$this->queueResolver = $queueResolver;
$this->pipeline = new Pipeline($container);
}
/**
* Dispatch a command to its appropriate handler.
*
* @param mixed $command
*
* @return mixed
*/
public function dispatch($command)
{
return $this->queueResolver && $this->commandShouldBeQueued($command) ? $this->dispatchToQueue($command) : $this->dispatchNow($command);
}
/**
* Dispatch a command to its appropriate handler in the current process.
*
* Queueable jobs will be dispatched to the "sync" queue.
*
* @param mixed $command
* @param mixed $handler
*
* @return mixed
*/
public function dispatchSync($command, $handler = null)
{
if ($this->queueResolver && $this->commandShouldBeQueued($command) && \method_exists($command, 'onConnection')) {
return $this->dispatchToQueue($command->onConnection('sync'));
}
return $this->dispatchNow($command, $handler);
}
/**
* Dispatch a command to its appropriate handler in the current process without using the synchronous queue.
*
* @param mixed $command
* @param mixed $handler
*
* @return mixed
*/
public function dispatchNow($command, $handler = null)
{
$uses = class_uses_recursive($command);
if (\in_array(InteractsWithQueue::class, $uses) && \in_array(Queueable::class, $uses) && !$command->job) {
$command->setJob(new SyncJob($this->container, \json_encode([]), 'sync', 'sync'));
}
if ($handler || ($handler = $this->getCommandHandler($command))) {
$callback = function ($command) use ($handler) {
$method = \method_exists($handler, 'handle') ? 'handle' : '__invoke';
return $handler->{$method}($command);
};
} else {
$callback = function ($command) {
$method = \method_exists($command, 'handle') ? 'handle' : '__invoke';
return $this->container->call([$command, $method]);
};
}
return $this->pipeline->send($command)->through($this->pipes)->then($callback);
}
/**
* Attempt to find the batch with the given ID.
*
* @return null|\Illuminate\Bus\Batch
*/
public function findBatch(string $batchId)
{
return $this->container->make(BatchRepository::class)->find($batchId);
}
/**
* Create a new batch of queueable jobs.
*
* @param array|\Illuminate\Support\Collection|mixed $jobs
*
* @return \Illuminate\Bus\PendingBatch
*/
public function batch($jobs)
{
return new PendingBatch($this->container, Collection::wrap($jobs));
}
/**
* Create a new chain of queueable jobs.
*
* @param array|\Illuminate\Support\Collection $jobs
*
* @return \Illuminate\Foundation\Bus\PendingChain
*/
public function chain($jobs)
{
$jobs = Collection::wrap($jobs);
return new PendingChain($jobs->shift(), $jobs->toArray());
}
/**
* Determine if the given command has a handler.
*
* @param mixed $command
*
* @return bool
*/
public function hasCommandHandler($command)
{
return \array_key_exists(\get_class($command), $this->handlers);
}
/**
* Retrieve the handler for a command.
*
* @param mixed $command
*
* @return bool|mixed
*/
public function getCommandHandler($command)
{
if ($this->hasCommandHandler($command)) {
return $this->container->make($this->handlers[\get_class($command)]);
}
return \false;
}
/**
* Dispatch a command to its appropriate handler behind a queue.
*
* @param mixed $command
*
* @return mixed
*
* @throws \RuntimeException
*/
public function dispatchToQueue($command)
{
$connection = $command->connection ?? null;
$queue = \call_user_func($this->queueResolver, $connection);
if (!$queue instanceof Queue) {
throw new \RuntimeException('Queue resolver did not return a Queue implementation.');
}
if (\method_exists($command, 'queue')) {
return $command->queue($queue, $command);
}
return $this->pushCommandToQueue($queue, $command);
}
/**
* Dispatch a command to its appropriate handler after the current process.
*
* @param mixed $command
* @param mixed $handler
*/
public function dispatchAfterResponse($command, $handler = null)
{
$this->container->terminating(function () use ($command, $handler) {
$this->dispatchNow($command, $handler);
});
}
/**
* Set the pipes through which commands should be piped before dispatching.
*
* @return $this
*/
public function pipeThrough(array $pipes)
{
$this->pipes = $pipes;
return $this;
}
/**
* Map a command to a handler.
*
* @return $this
*/
public function map(array $map)
{
$this->handlers = \array_merge($this->handlers, $map);
return $this;
}
/**
* Determine if the given command should be queued.
*
* @param mixed $command
*
* @return bool
*/
protected function commandShouldBeQueued($command)
{
return $command instanceof ShouldQueue;
}
/**
* Push the command onto the given queue instance.
*
* @param \Illuminate\Contracts\Queue\Queue $queue
* @param mixed $command
*
* @return mixed
*/
protected function pushCommandToQueue($queue, $command)
{
if (isset($command->queue, $command->delay)) {
return $queue->laterOn($command->queue, $command->delay, $command);
}
if (isset($command->queue)) {
return $queue->pushOn($command->queue, $command);
}
if (isset($command->delay)) {
return $queue->later($command->delay, $command);
}
return $queue->push($command);
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus\Events;
use _JchOptimizeVendor\Illuminate\Bus\Batch;
class BatchDispatched
{
/**
* The batch instance.
*
* @var \Illuminate\Bus\Batch
*/
public $batch;
/**
* Create a new event instance.
*
* @param \Illuminate\Bus\Batch $batch
*/
public function __construct(Batch $batch)
{
$this->batch = $batch;
}
}

View File

@@ -0,0 +1,261 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
use _JchOptimizeVendor\Illuminate\Bus\Events\BatchDispatched;
use _JchOptimizeVendor\Illuminate\Contracts\Container\Container;
use _JchOptimizeVendor\Illuminate\Contracts\Events\Dispatcher as EventDispatcher;
use _JchOptimizeVendor\Illuminate\Queue\SerializableClosureFactory;
use _JchOptimizeVendor\Illuminate\Support\Arr;
use _JchOptimizeVendor\Illuminate\Support\Collection;
class PendingBatch
{
/**
* The batch name.
*
* @var string
*/
public $name = '';
/**
* The jobs that belong to the batch.
*
* @var \Illuminate\Support\Collection
*/
public $jobs;
/**
* The batch options.
*
* @var array
*/
public $options = [];
/**
* The IoC container instance.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* Create a new pending batch instance.
*
* @param \Illuminate\Contracts\Container\Container $container
* @param \Illuminate\Support\Collection $jobs
*/
public function __construct(Container $container, Collection $jobs)
{
$this->container = $container;
$this->jobs = $jobs;
}
/**
* Add jobs to the batch.
*
* @param iterable $jobs
*
* @return $this
*/
public function add($jobs)
{
foreach ($jobs as $job) {
$this->jobs->push($job);
}
return $this;
}
/**
* Add a callback to be executed after all jobs in the batch have executed successfully.
*
* @param callable $callback
*
* @return $this
*/
public function then($callback)
{
$this->options['then'][] = $callback instanceof \Closure ? SerializableClosureFactory::make($callback) : $callback;
return $this;
}
/**
* Get the "then" callbacks that have been registered with the pending batch.
*
* @return array
*/
public function thenCallbacks()
{
return $this->options['then'] ?? [];
}
/**
* Add a callback to be executed after the first failing job in the batch.
*
* @param callable $callback
*
* @return $this
*/
public function catch($callback)
{
$this->options['catch'][] = $callback instanceof \Closure ? SerializableClosureFactory::make($callback) : $callback;
return $this;
}
/**
* Get the "catch" callbacks that have been registered with the pending batch.
*
* @return array
*/
public function catchCallbacks()
{
return $this->options['catch'] ?? [];
}
/**
* Add a callback to be executed after the batch has finished executing.
*
* @param callable $callback
*
* @return $this
*/
public function finally($callback)
{
$this->options['finally'][] = $callback instanceof \Closure ? SerializableClosureFactory::make($callback) : $callback;
return $this;
}
/**
* Get the "finally" callbacks that have been registered with the pending batch.
*
* @return array
*/
public function finallyCallbacks()
{
return $this->options['finally'] ?? [];
}
/**
* Indicate that the batch should not be cancelled when a job within the batch fails.
*
* @param bool $allowFailures
*
* @return $this
*/
public function allowFailures($allowFailures = \true)
{
$this->options['allowFailures'] = $allowFailures;
return $this;
}
/**
* Determine if the pending batch allows jobs to fail without cancelling the batch.
*
* @return bool
*/
public function allowsFailures()
{
return \true === Arr::get($this->options, 'allowFailures', \false);
}
/**
* Set the name for the batch.
*
* @return $this
*/
public function name(string $name)
{
$this->name = $name;
return $this;
}
/**
* Specify the queue connection that the batched jobs should run on.
*
* @return $this
*/
public function onConnection(string $connection)
{
$this->options['connection'] = $connection;
return $this;
}
/**
* Get the connection used by the pending batch.
*
* @return null|string
*/
public function connection()
{
return $this->options['connection'] ?? null;
}
/**
* Specify the queue that the batched jobs should run on.
*
* @return $this
*/
public function onQueue(string $queue)
{
$this->options['queue'] = $queue;
return $this;
}
/**
* Get the queue used by the pending batch.
*
* @return null|string
*/
public function queue()
{
return $this->options['queue'] ?? null;
}
/**
* Add additional data into the batch's options array.
*
* @param mixed $value
*
* @return $this
*/
public function withOption(string $key, $value)
{
$this->options[$key] = $value;
return $this;
}
/**
* Dispatch the batch.
*
* @return \Illuminate\Bus\Batch
*
* @throws \Throwable
*/
public function dispatch()
{
$repository = $this->container->make(BatchRepository::class);
try {
$batch = $repository->store($this);
$batch = $batch->add($this->jobs);
} catch (\Throwable $e) {
if (isset($batch)) {
$repository->delete($batch->id);
}
throw $e;
}
$this->container->make(EventDispatcher::class)->dispatch(new BatchDispatched($batch));
return $batch;
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
interface PrunableBatchRepository extends BatchRepository
{
/**
* Prune all of the entries older than the given date.
*
* @return int
*/
public function prune(\DateTimeInterface $before);
}

View File

@@ -0,0 +1,248 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
use _JchOptimizeVendor\Illuminate\Queue\CallQueuedClosure;
use _JchOptimizeVendor\Illuminate\Support\Arr;
trait Queueable
{
/**
* The name of the connection the job should be sent to.
*
* @var null|string
*/
public $connection;
/**
* The name of the queue the job should be sent to.
*
* @var null|string
*/
public $queue;
/**
* The name of the connection the chain should be sent to.
*
* @var null|string
*/
public $chainConnection;
/**
* The name of the queue the chain should be sent to.
*
* @var null|string
*/
public $chainQueue;
/**
* The callbacks to be executed on chain failure.
*
* @var null|array
*/
public $chainCatchCallbacks;
/**
* The number of seconds before the job should be made available.
*
* @var null|\DateInterval|\DateTimeInterface|int
*/
public $delay;
/**
* Indicates whether the job should be dispatched after all database transactions have committed.
*
* @var null|bool
*/
public $afterCommit;
/**
* The middleware the job should be dispatched through.
*
* @var array
*/
public $middleware = [];
/**
* The jobs that should run if this job is successful.
*
* @var array
*/
public $chained = [];
/**
* Set the desired connection for the job.
*
* @param null|string $connection
*
* @return $this
*/
public function onConnection($connection)
{
$this->connection = $connection;
return $this;
}
/**
* Set the desired queue for the job.
*
* @param null|string $queue
*
* @return $this
*/
public function onQueue($queue)
{
$this->queue = $queue;
return $this;
}
/**
* Set the desired connection for the chain.
*
* @param null|string $connection
*
* @return $this
*/
public function allOnConnection($connection)
{
$this->chainConnection = $connection;
$this->connection = $connection;
return $this;
}
/**
* Set the desired queue for the chain.
*
* @param null|string $queue
*
* @return $this
*/
public function allOnQueue($queue)
{
$this->chainQueue = $queue;
$this->queue = $queue;
return $this;
}
/**
* Set the desired delay for the job.
*
* @param null|\DateInterval|\DateTimeInterface|int $delay
*
* @return $this
*/
public function delay($delay)
{
$this->delay = $delay;
return $this;
}
/**
* Indicate that the job should be dispatched after all database transactions have committed.
*
* @return $this
*/
public function afterCommit()
{
$this->afterCommit = \true;
return $this;
}
/**
* Indicate that the job should not wait until database transactions have been committed before dispatching.
*
* @return $this
*/
public function beforeCommit()
{
$this->afterCommit = \false;
return $this;
}
/**
* Specify the middleware the job should be dispatched through.
*
* @param array|object $middleware
*
* @return $this
*/
public function through($middleware)
{
$this->middleware = Arr::wrap($middleware);
return $this;
}
/**
* Set the jobs that should run if this job is successful.
*
* @param array $chain
*
* @return $this
*/
public function chain($chain)
{
$this->chained = collect($chain)->map(function ($job) {
return $this->serializeJob($job);
})->all();
return $this;
}
/**
* Dispatch the next job on the chain.
*/
public function dispatchNextJobInChain()
{
if (!empty($this->chained)) {
dispatch(tap(\unserialize(\array_shift($this->chained)), function ($next) {
$next->chained = $this->chained;
$next->onConnection($next->connection ?: $this->chainConnection);
$next->onQueue($next->queue ?: $this->chainQueue);
$next->chainConnection = $this->chainConnection;
$next->chainQueue = $this->chainQueue;
$next->chainCatchCallbacks = $this->chainCatchCallbacks;
}));
}
}
/**
* Invoke all of the chain's failed job callbacks.
*
* @param \Throwable $e
*/
public function invokeChainCatchCallbacks($e)
{
collect($this->chainCatchCallbacks)->each(function ($callback) use ($e) {
$callback($e);
});
}
/**
* Serialize a job for queuing.
*
* @param mixed $job
*
* @return string
*
* @throws \RuntimeException
*/
protected function serializeJob($job)
{
if ($job instanceof \Closure) {
if (!\class_exists(CallQueuedClosure::class)) {
throw new \RuntimeException('To enable support for closure jobs, please install the illuminate/queue package.');
}
$job = CallQueuedClosure::create($job);
}
return \serialize($job);
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
use _JchOptimizeVendor\Illuminate\Contracts\Cache\Repository as Cache;
class UniqueLock
{
/**
* The cache repository implementation.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $cache;
/**
* Create a new unique lock manager instance.
*
* @param \Illuminate\Contracts\Cache\Repository $cache
*/
public function __construct(Cache $cache)
{
$this->cache = $cache;
}
/**
* Attempt to acquire a lock for the given job.
*
* @param mixed $job
*
* @return bool
*/
public function acquire($job)
{
$uniqueId = \method_exists($job, 'uniqueId') ? $job->uniqueId() : $job->uniqueId ?? '';
$cache = \method_exists($job, 'uniqueVia') ? $job->uniqueVia() : $this->cache;
return (bool) $cache->lock($key = 'laravel_unique_job:'.\get_class($job).$uniqueId, $job->uniqueFor ?? 0)->get();
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Bus;
class UpdatedBatchJobCounts
{
/**
* The number of pending jobs remaining for the batch.
*
* @var int
*/
public $pendingJobs;
/**
* The number of failed jobs that belong to the batch.
*
* @var int
*/
public $failedJobs;
/**
* Create a new batch job counts object.
*/
public function __construct(int $pendingJobs = 0, int $failedJobs = 0)
{
$this->pendingJobs = $pendingJobs;
$this->failedJobs = $failedJobs;
}
/**
* Determine if all jobs have run exactly once.
*
* @return bool
*/
public function allJobsHaveRanExactlyOnce()
{
return 0 === $this->pendingJobs - $this->failedJobs;
}
}

View File

@@ -0,0 +1,709 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Illuminate\Support\Traits\Macroable;
use function _JchOptimizeVendor\data_get;
use function _JchOptimizeVendor\value;
class Arr
{
use Macroable;
/**
* Determine whether the given value is array accessible.
*
* @param mixed $value
*
* @return bool
*/
public static function accessible($value)
{
return \is_array($value) || $value instanceof \ArrayAccess;
}
/**
* Add an element to an array using "dot" notation if it doesn't exist.
*
* @param array $array
* @param string $key
* @param mixed $value
*
* @return array
*/
public static function add($array, $key, $value)
{
if (\is_null(static::get($array, $key))) {
static::set($array, $key, $value);
}
return $array;
}
/**
* Collapse an array of arrays into a single array.
*
* @param iterable $array
*
* @return array
*/
public static function collapse($array)
{
$results = [];
foreach ($array as $values) {
if ($values instanceof Collection) {
$values = $values->all();
} elseif (!\is_array($values)) {
continue;
}
$results[] = $values;
}
return \array_merge([], ...$results);
}
/**
* Cross join the given arrays, returning all possible permutations.
*
* @param iterable ...$arrays
*
* @return array
*/
public static function crossJoin(...$arrays)
{
$results = [[]];
foreach ($arrays as $index => $array) {
$append = [];
foreach ($results as $product) {
foreach ($array as $item) {
$product[$index] = $item;
$append[] = $product;
}
}
$results = $append;
}
return $results;
}
/**
* Divide an array into two arrays. One with keys and the other with values.
*
* @param array $array
*
* @return array
*/
public static function divide($array)
{
return [\array_keys($array), \array_values($array)];
}
/**
* Flatten a multi-dimensional associative array with dots.
*
* @param iterable $array
* @param string $prepend
*
* @return array
*/
public static function dot($array, $prepend = '')
{
$results = [];
foreach ($array as $key => $value) {
if (\is_array($value) && !empty($value)) {
$results = \array_merge($results, static::dot($value, $prepend.$key.'.'));
} else {
$results[$prepend.$key] = $value;
}
}
return $results;
}
/**
* Convert a flatten "dot" notation array into an expanded array.
*
* @param iterable $array
*
* @return array
*/
public static function undot($array)
{
$results = [];
foreach ($array as $key => $value) {
static::set($results, $key, $value);
}
return $results;
}
/**
* Get all of the given array except for a specified array of keys.
*
* @param array $array
* @param array|string $keys
*
* @return array
*/
public static function except($array, $keys)
{
static::forget($array, $keys);
return $array;
}
/**
* Determine if the given key exists in the provided array.
*
* @param array|\ArrayAccess $array
* @param int|string $key
*
* @return bool
*/
public static function exists($array, $key)
{
if ($array instanceof Enumerable) {
return $array->has($key);
}
if ($array instanceof \ArrayAccess) {
return $array->offsetExists($key);
}
return \array_key_exists($key, $array);
}
/**
* Return the first element in an array passing a given truth test.
*
* @param iterable $array
* @param mixed $default
*
* @return mixed
*/
public static function first($array, callable $callback = null, $default = null)
{
if (\is_null($callback)) {
if (empty($array)) {
return value($default);
}
foreach ($array as $item) {
return $item;
}
}
foreach ($array as $key => $value) {
if ($callback($value, $key)) {
return $value;
}
}
return value($default);
}
/**
* Return the last element in an array passing a given truth test.
*
* @param array $array
* @param mixed $default
*
* @return mixed
*/
public static function last($array, callable $callback = null, $default = null)
{
if (\is_null($callback)) {
return empty($array) ? value($default) : \end($array);
}
return static::first(\array_reverse($array, \true), $callback, $default);
}
/**
* Flatten a multi-dimensional array into a single level.
*
* @param iterable $array
* @param int $depth
*
* @return array
*/
public static function flatten($array, $depth = \INF)
{
$result = [];
foreach ($array as $item) {
$item = $item instanceof Collection ? $item->all() : $item;
if (!\is_array($item)) {
$result[] = $item;
} else {
$values = 1 === $depth ? \array_values($item) : static::flatten($item, $depth - 1);
foreach ($values as $value) {
$result[] = $value;
}
}
}
return $result;
}
/**
* Remove one or many array items from a given array using "dot" notation.
*
* @param array $array
* @param array|string $keys
*/
public static function forget(&$array, $keys)
{
$original = &$array;
$keys = (array) $keys;
if (0 === \count($keys)) {
return;
}
foreach ($keys as $key) {
// if the exact key exists in the top-level, remove it
if (static::exists($array, $key)) {
unset($array[$key]);
continue;
}
$parts = \explode('.', $key);
// clean up before each pass
$array = &$original;
while (\count($parts) > 1) {
$part = \array_shift($parts);
if (isset($array[$part]) && \is_array($array[$part])) {
$array = &$array[$part];
} else {
continue 2;
}
}
unset($array[\array_shift($parts)]);
}
}
/**
* Get an item from an array using "dot" notation.
*
* @param array|\ArrayAccess $array
* @param null|int|string $key
* @param mixed $default
*
* @return mixed
*/
public static function get($array, $key, $default = null)
{
if (!static::accessible($array)) {
return value($default);
}
if (\is_null($key)) {
return $array;
}
if (static::exists($array, $key)) {
return $array[$key];
}
if (\false === \strpos($key, '.')) {
return $array[$key] ?? value($default);
}
foreach (\explode('.', $key) as $segment) {
if (static::accessible($array) && static::exists($array, $segment)) {
$array = $array[$segment];
} else {
return value($default);
}
}
return $array;
}
/**
* Check if an item or items exist in an array using "dot" notation.
*
* @param array|\ArrayAccess $array
* @param array|string $keys
*
* @return bool
*/
public static function has($array, $keys)
{
$keys = (array) $keys;
if (!$array || [] === $keys) {
return \false;
}
foreach ($keys as $key) {
$subKeyArray = $array;
if (static::exists($array, $key)) {
continue;
}
foreach (\explode('.', $key) as $segment) {
if (static::accessible($subKeyArray) && static::exists($subKeyArray, $segment)) {
$subKeyArray = $subKeyArray[$segment];
} else {
return \false;
}
}
}
return \true;
}
/**
* Determine if any of the keys exist in an array using "dot" notation.
*
* @param array|\ArrayAccess $array
* @param array|string $keys
*
* @return bool
*/
public static function hasAny($array, $keys)
{
if (\is_null($keys)) {
return \false;
}
$keys = (array) $keys;
if (!$array) {
return \false;
}
if ([] === $keys) {
return \false;
}
foreach ($keys as $key) {
if (static::has($array, $key)) {
return \true;
}
}
return \false;
}
/**
* Determines if an array is associative.
*
* An array is "associative" if it doesn't have sequential numerical keys beginning with zero.
*
* @return bool
*/
public static function isAssoc(array $array)
{
$keys = \array_keys($array);
return \array_keys($keys) !== $keys;
}
/**
* Determines if an array is a list.
*
* An array is a "list" if all array keys are sequential integers starting from 0 with no gaps in between.
*
* @param array $array
*
* @return bool
*/
public static function isList($array)
{
return !self::isAssoc($array);
}
/**
* Get a subset of the items from the given array.
*
* @param array $array
* @param array|string $keys
*
* @return array
*/
public static function only($array, $keys)
{
return \array_intersect_key($array, \array_flip((array) $keys));
}
/**
* Pluck an array of values from an array.
*
* @param iterable $array
* @param null|array|int|string $value
* @param null|array|string $key
*
* @return array
*/
public static function pluck($array, $value, $key = null)
{
$results = [];
[$value, $key] = static::explodePluckParameters($value, $key);
foreach ($array as $item) {
$itemValue = data_get($item, $value);
// If the key is "null", we will just append the value to the array and keep
// looping. Otherwise we will key the array using the value of the key we
// received from the developer. Then we'll return the final array form.
if (\is_null($key)) {
$results[] = $itemValue;
} else {
$itemKey = data_get($item, $key);
if (\is_object($itemKey) && \method_exists($itemKey, '__toString')) {
$itemKey = (string) $itemKey;
}
$results[$itemKey] = $itemValue;
}
}
return $results;
}
/**
* Push an item onto the beginning of an array.
*
* @param array $array
* @param mixed $value
* @param mixed $key
*
* @return array
*/
public static function prepend($array, $value, $key = null)
{
if (2 == \func_num_args()) {
\array_unshift($array, $value);
} else {
$array = [$key => $value] + $array;
}
return $array;
}
/**
* Get a value from the array, and remove it.
*
* @param array $array
* @param int|string $key
* @param mixed $default
*
* @return mixed
*/
public static function pull(&$array, $key, $default = null)
{
$value = static::get($array, $key, $default);
static::forget($array, $key);
return $value;
}
/**
* Convert the array into a query string.
*
* @param array $array
*
* @return string
*/
public static function query($array)
{
return \http_build_query($array, '', '&', \PHP_QUERY_RFC3986);
}
/**
* Get one or a specified number of random values from an array.
*
* @param array $array
* @param null|int $number
* @param bool|false $preserveKeys
*
* @return mixed
*
* @throws \InvalidArgumentException
*/
public static function random($array, $number = null, $preserveKeys = \false)
{
$requested = \is_null($number) ? 1 : $number;
$count = \count($array);
if ($requested > $count) {
throw new \InvalidArgumentException("You requested {$requested} items, but there are only {$count} items available.");
}
if (\is_null($number)) {
return $array[\array_rand($array)];
}
if (0 === (int) $number) {
return [];
}
$keys = \array_rand($array, $number);
$results = [];
if ($preserveKeys) {
foreach ((array) $keys as $key) {
$results[$key] = $array[$key];
}
} else {
foreach ((array) $keys as $key) {
$results[] = $array[$key];
}
}
return $results;
}
/**
* Set an array item to a given value using "dot" notation.
*
* If no key is given to the method, the entire array will be replaced.
*
* @param array $array
* @param null|string $key
* @param mixed $value
*
* @return array
*/
public static function set(&$array, $key, $value)
{
if (\is_null($key)) {
return $array = $value;
}
$keys = \explode('.', $key);
foreach ($keys as $i => $key) {
if (1 === \count($keys)) {
break;
}
unset($keys[$i]);
// If the key doesn't exist at this depth, we will just create an empty array
// to hold the next value, allowing us to create the arrays to hold final
// values at the correct depth. Then we'll keep digging into the array.
if (!isset($array[$key]) || !\is_array($array[$key])) {
$array[$key] = [];
}
$array = &$array[$key];
}
$array[\array_shift($keys)] = $value;
return $array;
}
/**
* Shuffle the given array and return the result.
*
* @param array $array
* @param null|int $seed
*
* @return array
*/
public static function shuffle($array, $seed = null)
{
if (\is_null($seed)) {
\shuffle($array);
} else {
\mt_srand($seed);
\shuffle($array);
\mt_srand();
}
return $array;
}
/**
* Sort the array using the given callback or "dot" notation.
*
* @param array $array
* @param null|array|callable|string $callback
*
* @return array
*/
public static function sort($array, $callback = null)
{
return Collection::make($array)->sortBy($callback)->all();
}
/**
* Recursively sort an array by keys and values.
*
* @param array $array
* @param int $options
* @param bool $descending
*
* @return array
*/
public static function sortRecursive($array, $options = \SORT_REGULAR, $descending = \false)
{
foreach ($array as &$value) {
if (\is_array($value)) {
$value = static::sortRecursive($value, $options, $descending);
}
}
if (static::isAssoc($array)) {
$descending ? \krsort($array, $options) : \ksort($array, $options);
} else {
$descending ? \rsort($array, $options) : \sort($array, $options);
}
return $array;
}
/**
* Conditionally compile classes from an array into a CSS class list.
*
* @param array $array
*
* @return string
*/
public static function toCssClasses($array)
{
$classList = static::wrap($array);
$classes = [];
foreach ($classList as $class => $constraint) {
if (\is_numeric($class)) {
$classes[] = $constraint;
} elseif ($constraint) {
$classes[] = $class;
}
}
return \implode(' ', $classes);
}
/**
* Filter the array using the given callback.
*
* @param array $array
*
* @return array
*/
public static function where($array, callable $callback)
{
return \array_filter($array, $callback, \ARRAY_FILTER_USE_BOTH);
}
/**
* Filter items where the value is not null.
*
* @param array $array
*
* @return array
*/
public static function whereNotNull($array)
{
return static::where($array, function ($value) {
return !\is_null($value);
});
}
/**
* If the given value is not an array and not null, wrap it in one.
*
* @param mixed $value
*
* @return array
*/
public static function wrap($value)
{
if (\is_null($value)) {
return [];
}
return \is_array($value) ? $value : [$value];
}
/**
* Explode the "value" and "key" arguments passed to "pluck".
*
* @param array|string $value
* @param null|array|string $key
*
* @return array
*/
protected static function explodePluckParameters($value, $key)
{
$value = \is_string($value) ? \explode('.', $value) : $value;
$key = \is_null($key) || \is_array($key) ? $key : \explode('.', $key);
return [$value, $key];
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,64 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
/**
* @mixin \Illuminate\Support\Enumerable
*/
class HigherOrderCollectionProxy
{
/**
* The collection being operated on.
*
* @var \Illuminate\Support\Enumerable
*/
protected $collection;
/**
* The method being proxied.
*
* @var string
*/
protected $method;
/**
* Create a new proxy instance.
*
* @param \Illuminate\Support\Enumerable $collection
* @param string $method
*/
public function __construct(Enumerable $collection, $method)
{
$this->method = $method;
$this->collection = $collection;
}
/**
* Proxy accessing an attribute onto the collection items.
*
* @param string $key
*
* @return mixed
*/
public function __get($key)
{
return $this->collection->{$this->method}(function ($value) use ($key) {
return \is_array($value) ? $value[$key] : $value->{$key};
});
}
/**
* Proxy a method call onto the collection items.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->collection->{$this->method}(function ($value) use ($method, $parameters) {
return $value->{$method}(...$parameters);
});
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
/**
* @mixin \Illuminate\Support\Enumerable
*/
class HigherOrderWhenProxy
{
/**
* The collection being operated on.
*
* @var \Illuminate\Support\Enumerable
*/
protected $collection;
/**
* The condition for proxying.
*
* @var bool
*/
protected $condition;
/**
* Create a new proxy instance.
*
* @param \Illuminate\Support\Enumerable $collection
* @param bool $condition
*/
public function __construct(Enumerable $collection, $condition)
{
$this->condition = $condition;
$this->collection = $collection;
}
/**
* Proxy accessing an attribute onto the collection.
*
* @param string $key
*
* @return mixed
*/
public function __get($key)
{
return $this->condition ? $this->collection->{$key} : $this->collection;
}
/**
* Proxy a method call onto the collection.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->condition ? $this->collection->{$method}(...$parameters) : $this->collection;
}
}

View File

@@ -0,0 +1,7 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
class ItemNotFoundException extends \RuntimeException
{
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
class MultipleItemsFoundException extends \RuntimeException
{
}

View File

@@ -0,0 +1,177 @@
<?php
namespace _JchOptimizeVendor;
use _JchOptimizeVendor\Illuminate\Support\Arr;
use _JchOptimizeVendor\Illuminate\Support\Collection;
if (!\function_exists('_JchOptimizeVendor\\collect')) {
/**
* Create a collection from the given value.
*
* @param mixed $value
*
* @return \Illuminate\Support\Collection
*/
function collect($value = null)
{
return new Collection($value);
}
}
if (!\function_exists('_JchOptimizeVendor\\data_fill')) {
/**
* Fill in data where it's missing.
*
* @param mixed $target
* @param array|string $key
* @param mixed $value
*
* @return mixed
*/
function data_fill(&$target, $key, $value)
{
return data_set($target, $key, $value, \false);
}
}
if (!\function_exists('_JchOptimizeVendor\\data_get')) {
/**
* Get an item from an array or object using "dot" notation.
*
* @param mixed $target
* @param null|array|int|string $key
* @param mixed $default
*
* @return mixed
*/
function data_get($target, $key, $default = null)
{
if (\is_null($key)) {
return $target;
}
$key = \is_array($key) ? $key : \explode('.', $key);
foreach ($key as $i => $segment) {
unset($key[$i]);
if (\is_null($segment)) {
return $target;
}
if ('*' === $segment) {
if ($target instanceof Collection) {
$target = $target->all();
} elseif (!\is_array($target)) {
return value($default);
}
$result = [];
foreach ($target as $item) {
$result[] = data_get($item, $key);
}
return \in_array('*', $key) ? Arr::collapse($result) : $result;
}
if (Arr::accessible($target) && Arr::exists($target, $segment)) {
$target = $target[$segment];
} elseif (\is_object($target) && isset($target->{$segment})) {
$target = $target->{$segment};
} else {
return value($default);
}
}
return $target;
}
}
if (!\function_exists('_JchOptimizeVendor\\data_set')) {
/**
* Set an item on an array or object using dot notation.
*
* @param mixed $target
* @param array|string $key
* @param mixed $value
* @param bool $overwrite
*
* @return mixed
*/
function data_set(&$target, $key, $value, $overwrite = \true)
{
$segments = \is_array($key) ? $key : \explode('.', $key);
if (($segment = \array_shift($segments)) === '*') {
if (!Arr::accessible($target)) {
$target = [];
}
if ($segments) {
foreach ($target as &$inner) {
data_set($inner, $segments, $value, $overwrite);
}
} elseif ($overwrite) {
foreach ($target as &$inner) {
$inner = $value;
}
}
} elseif (Arr::accessible($target)) {
if ($segments) {
if (!Arr::exists($target, $segment)) {
$target[$segment] = [];
}
data_set($target[$segment], $segments, $value, $overwrite);
} elseif ($overwrite || !Arr::exists($target, $segment)) {
$target[$segment] = $value;
}
} elseif (\is_object($target)) {
if ($segments) {
if (!isset($target->{$segment})) {
$target->{$segment} = [];
}
data_set($target->{$segment}, $segments, $value, $overwrite);
} elseif ($overwrite || !isset($target->{$segment})) {
$target->{$segment} = $value;
}
} else {
$target = [];
if ($segments) {
data_set($target[$segment], $segments, $value, $overwrite);
} elseif ($overwrite) {
$target[$segment] = $value;
}
}
return $target;
}
}
if (!\function_exists('_JchOptimizeVendor\\head')) {
/**
* Get the first element of an array. Useful for method chaining.
*
* @param array $array
*
* @return mixed
*/
function head($array)
{
return \reset($array);
}
}
if (!\function_exists('_JchOptimizeVendor\\last')) {
/**
* Get the last element from an array.
*
* @param array $array
*
* @return mixed
*/
function last($array)
{
return \end($array);
}
}
if (!\function_exists('_JchOptimizeVendor\\value')) {
/**
* Return the default value of the given value.
*
* @param mixed $value
*
* @return mixed
*/
function value($value, ...$args)
{
return $value instanceof \Closure ? $value(...$args) : $value;
}
}

View File

@@ -0,0 +1,186 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Container;
use _JchOptimizeVendor\Illuminate\Contracts\Container\BindingResolutionException;
use Closure;
class BoundMethod
{
/**
* Call the given Closure / class@method and inject its dependencies.
*
* @param \Illuminate\Container\Container $container
* @param callable|string $callback
* @param null|string $defaultMethod
*
* @return mixed
*
* @throws \ReflectionException
* @throws \InvalidArgumentException
*/
public static function call($container, $callback, array $parameters = [], $defaultMethod = null)
{
if (\is_string($callback) && !$defaultMethod && \method_exists($callback, '__invoke')) {
$defaultMethod = '__invoke';
}
if (static::isCallableWithAtSign($callback) || $defaultMethod) {
return static::callClass($container, $callback, $parameters, $defaultMethod);
}
return static::callBoundMethod($container, $callback, function () use ($container, $callback, $parameters) {
return $callback(...\array_values(static::getMethodDependencies($container, $callback, $parameters)));
});
}
/**
* Call a string reference to a class using Class@method syntax.
*
* @param \Illuminate\Container\Container $container
* @param string $target
* @param null|string $defaultMethod
*
* @return mixed
*
* @throws \InvalidArgumentException
*/
protected static function callClass($container, $target, array $parameters = [], $defaultMethod = null)
{
$segments = \explode('@', $target);
// We will assume an @ sign is used to delimit the class name from the method
// name. We will split on this @ sign and then build a callable array that
// we can pass right back into the "call" method for dependency binding.
$method = 2 === \count($segments) ? $segments[1] : $defaultMethod;
if (\is_null($method)) {
throw new \InvalidArgumentException('Method not provided.');
}
return static::call($container, [$container->make($segments[0]), $method], $parameters);
}
/**
* Call a method that has been bound to the container.
*
* @param \Illuminate\Container\Container $container
* @param callable $callback
* @param mixed $default
*
* @return mixed
*/
protected static function callBoundMethod($container, $callback, $default)
{
if (!\is_array($callback)) {
return Util::unwrapIfClosure($default);
}
// Here we need to turn the array callable into a Class@method string we can use to
// examine the container and see if there are any method bindings for this given
// method. If there are, we can call this method binding callback immediately.
$method = static::normalizeMethod($callback);
if ($container->hasMethodBinding($method)) {
return $container->callMethodBinding($method, $callback[0]);
}
return Util::unwrapIfClosure($default);
}
/**
* Normalize the given callback into a Class@method string.
*
* @param callable $callback
*
* @return string
*/
protected static function normalizeMethod($callback)
{
$class = \is_string($callback[0]) ? $callback[0] : \get_class($callback[0]);
return "{$class}@{$callback[1]}";
}
/**
* Get all dependencies for a given method.
*
* @param \Illuminate\Container\Container $container
* @param callable|string $callback
*
* @return array
*
* @throws \ReflectionException
*/
protected static function getMethodDependencies($container, $callback, array $parameters = [])
{
$dependencies = [];
foreach (static::getCallReflector($callback)->getParameters() as $parameter) {
static::addDependencyForCallParameter($container, $parameter, $parameters, $dependencies);
}
return \array_merge($dependencies, \array_values($parameters));
}
/**
* Get the proper reflection instance for the given callback.
*
* @param callable|string $callback
*
* @return \ReflectionFunctionAbstract
*
* @throws \ReflectionException
*/
protected static function getCallReflector($callback)
{
if (\is_string($callback) && \false !== \strpos($callback, '::')) {
$callback = \explode('::', $callback);
} elseif (\is_object($callback) && !$callback instanceof \Closure) {
$callback = [$callback, '__invoke'];
}
return \is_array($callback) ? new \ReflectionMethod($callback[0], $callback[1]) : new \ReflectionFunction($callback);
}
/**
* Get the dependency for the given call parameter.
*
* @param \Illuminate\Container\Container $container
* @param \ReflectionParameter $parameter
* @param array $dependencies
*
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
protected static function addDependencyForCallParameter($container, $parameter, array &$parameters, &$dependencies)
{
if (\array_key_exists($paramName = $parameter->getName(), $parameters)) {
$dependencies[] = $parameters[$paramName];
unset($parameters[$paramName]);
} elseif (!\is_null($className = Util::getParameterClassName($parameter))) {
if (\array_key_exists($className, $parameters)) {
$dependencies[] = $parameters[$className];
unset($parameters[$className]);
} else {
if ($parameter->isVariadic()) {
$variadicDependencies = $container->make($className);
$dependencies = \array_merge($dependencies, \is_array($variadicDependencies) ? $variadicDependencies : [$variadicDependencies]);
} else {
$dependencies[] = $container->make($className);
}
}
} elseif ($parameter->isDefaultValueAvailable()) {
$dependencies[] = $parameter->getDefaultValue();
} elseif (!$parameter->isOptional() && !\array_key_exists($paramName, $parameters)) {
$message = "Unable to resolve dependency [{$parameter}] in class {$parameter->getDeclaringClass()->getName()}";
throw new BindingResolutionException($message);
}
}
/**
* Determine if the given string is in Class@method syntax.
*
* @param mixed $callback
*
* @return bool
*/
protected static function isCallableWithAtSign($callback)
{
return \is_string($callback) && \false !== \strpos($callback, '@');
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,95 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Container;
use _JchOptimizeVendor\Illuminate\Contracts\Container\Container;
use _JchOptimizeVendor\Illuminate\Contracts\Container\ContextualBindingBuilder as ContextualBindingBuilderContract;
class ContextualBindingBuilder implements ContextualBindingBuilderContract
{
/**
* The underlying container instance.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* The concrete instance.
*
* @var array|string
*/
protected $concrete;
/**
* The abstract target.
*
* @var string
*/
protected $needs;
/**
* Create a new contextual binding builder.
*
* @param \Illuminate\Contracts\Container\Container $container
* @param array|string $concrete
*/
public function __construct(Container $container, $concrete)
{
$this->concrete = $concrete;
$this->container = $container;
}
/**
* Define the abstract target that depends on the context.
*
* @param string $abstract
*
* @return $this
*/
public function needs($abstract)
{
$this->needs = $abstract;
return $this;
}
/**
* Define the implementation for the contextual binding.
*
* @param array|\Closure|string $implementation
*/
public function give($implementation)
{
foreach (Util::arrayWrap($this->concrete) as $concrete) {
$this->container->addContextualBinding($concrete, $this->needs, $implementation);
}
}
/**
* Define tagged services to be used as the implementation for the contextual binding.
*
* @param string $tag
*/
public function giveTagged($tag)
{
$this->give(function ($container) use ($tag) {
$taggedServices = $container->tagged($tag);
return \is_array($taggedServices) ? $taggedServices : \iterator_to_array($taggedServices);
});
}
/**
* Specify the configuration item to bind as a primitive.
*
* @param string $key
* @param ?string $default
*/
public function giveConfig($key, $default = null)
{
$this->give(function ($container) use ($key, $default) {
return $container->get('config')->get($key, $default);
});
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Container;
use _JchOptimizeVendor\Psr\Container\NotFoundExceptionInterface;
class EntryNotFoundException extends \Exception implements NotFoundExceptionInterface
{
}

View File

@@ -0,0 +1,57 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Container;
class RewindableGenerator implements \Countable, \IteratorAggregate
{
/**
* The generator callback.
*
* @var callable
*/
protected $generator;
/**
* The number of tagged services.
*
* @var callable|int
*/
protected $count;
/**
* Create a new generator instance.
*
* @param callable|int $count
*/
public function __construct(callable $generator, $count)
{
$this->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;
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Container;
/**
* @internal
*/
class Util
{
/**
* If the given value is not an array and not null, wrap it in one.
*
* From Arr::wrap() in Illuminate\Support.
*
* @param mixed $value
*
* @return array
*/
public static function arrayWrap($value)
{
if (\is_null($value)) {
return [];
}
return \is_array($value) ? $value : [$value];
}
/**
* Return the default value of the given value.
*
* From global value() helper in Illuminate\Support.
*
* @param mixed $value
*
* @return mixed
*/
public static function unwrapIfClosure($value)
{
return $value instanceof \Closure ? $value() : $value;
}
/**
* Get the class name of the given parameter's type, if possible.
*
* From Reflector::getParameterClassName() in Illuminate\Support.
*
* @param \ReflectionParameter $parameter
*
* @return null|string
*/
public static function getParameterClassName($parameter)
{
$type = $parameter->getType();
if (!$type instanceof \ReflectionNamedType || $type->isBuiltin()) {
return null;
}
$name = $type->getName();
if (!\is_null($class = $parameter->getDeclaringClass())) {
if ('self' === $name) {
return $class->getName();
}
if ('parent' === $name && ($parent = $class->getParentClass())) {
return $parent->getName();
}
}
return $name;
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Container;
use _JchOptimizeVendor\Psr\Container\ContainerExceptionInterface;
class BindingResolutionException extends \Exception implements ContainerExceptionInterface
{
}

View File

@@ -0,0 +1,9 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Container;
use _JchOptimizeVendor\Psr\Container\ContainerExceptionInterface;
class CircularDependencyException extends \Exception implements ContainerExceptionInterface
{
}

View File

@@ -0,0 +1,174 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Container;
use _JchOptimizeVendor\Psr\Container\ContainerInterface;
use Closure;
interface Container extends ContainerInterface
{
/**
* Determine if the given abstract type has been bound.
*
* @param string $abstract
*
* @return bool
*/
public function bound($abstract);
/**
* Alias a type to a different name.
*
* @param string $abstract
* @param string $alias
*
* @throws \LogicException
*/
public function alias($abstract, $alias);
/**
* Assign a set of tags to a given binding.
*
* @param array|string $abstracts
* @param array|mixed ...$tags
*/
public function tag($abstracts, $tags);
/**
* Resolve all of the bindings for a given tag.
*
* @param string $tag
*
* @return iterable
*/
public function tagged($tag);
/**
* Register a binding with the container.
*
* @param string $abstract
* @param null|\Closure|string $concrete
* @param bool $shared
*/
public function bind($abstract, $concrete = null, $shared = \false);
/**
* Register a binding if it hasn't already been registered.
*
* @param string $abstract
* @param null|\Closure|string $concrete
* @param bool $shared
*/
public function bindIf($abstract, $concrete = null, $shared = \false);
/**
* Register a shared binding in the container.
*
* @param string $abstract
* @param null|\Closure|string $concrete
*/
public function singleton($abstract, $concrete = null);
/**
* Register a shared binding if it hasn't already been registered.
*
* @param string $abstract
* @param null|\Closure|string $concrete
*/
public function singletonIf($abstract, $concrete = null);
/**
* "Extend" an abstract type in the container.
*
* @param string $abstract
*
* @throws \InvalidArgumentException
*/
public function extend($abstract, \Closure $closure);
/**
* Register an existing instance as shared in the container.
*
* @param string $abstract
* @param mixed $instance
*
* @return mixed
*/
public function instance($abstract, $instance);
/**
* Add a contextual binding to the container.
*
* @param string $concrete
* @param string $abstract
* @param \Closure|string $implementation
*/
public function addContextualBinding($concrete, $abstract, $implementation);
/**
* Define a contextual binding.
*
* @param array|string $concrete
*
* @return \Illuminate\Contracts\Container\ContextualBindingBuilder
*/
public function when($concrete);
/**
* Get a closure to resolve the given type from the container.
*
* @param string $abstract
*
* @return \Closure
*/
public function factory($abstract);
/**
* Flush the container of all bindings and resolved instances.
*/
public function flush();
/**
* Resolve the given type from the container.
*
* @param string $abstract
*
* @return mixed
*
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function make($abstract, array $parameters = []);
/**
* Call the given Closure / class@method and inject its dependencies.
*
* @param callable|string $callback
* @param null|string $defaultMethod
*
* @return mixed
*/
public function call($callback, array $parameters = [], $defaultMethod = null);
/**
* Determine if the given abstract type has been resolved.
*
* @param string $abstract
*
* @return bool
*/
public function resolved($abstract);
/**
* Register a new resolving callback.
*
* @param \Closure|string $abstract
*/
public function resolving($abstract, \Closure $callback = null);
/**
* Register a new after resolving callback.
*
* @param \Closure|string $abstract
*/
public function afterResolving($abstract, \Closure $callback = null);
}

View File

@@ -0,0 +1,29 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Container;
interface ContextualBindingBuilder
{
/**
* Define the abstract target that depends on the context.
*
* @param string $abstract
*
* @return $this
*/
public function needs($abstract);
/**
* Define the implementation for the contextual binding.
*
* @param array|\Closure|string $implementation
*/
public function give($implementation);
/**
* Define tagged services to be used as the implementation for the contextual binding.
*
* @param string $tag
*/
public function giveTagged($tag);
}

View File

@@ -0,0 +1,78 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Events;
interface Dispatcher
{
/**
* Register an event listener with the dispatcher.
*
* @param array|\Closure|string $events
* @param null|array|\Closure|string $listener
*/
public function listen($events, $listener = null);
/**
* Determine if a given event has listeners.
*
* @param string $eventName
*
* @return bool
*/
public function hasListeners($eventName);
/**
* Register an event subscriber with the dispatcher.
*
* @param object|string $subscriber
*/
public function subscribe($subscriber);
/**
* Dispatch an event until the first non-null response is returned.
*
* @param object|string $event
* @param mixed $payload
*
* @return null|array
*/
public function until($event, $payload = []);
/**
* Dispatch an event and call the listeners.
*
* @param object|string $event
* @param mixed $payload
* @param bool $halt
*
* @return null|array
*/
public function dispatch($event, $payload = [], $halt = \false);
/**
* Register an event and payload to be fired later.
*
* @param string $event
* @param array $payload
*/
public function push($event, $payload = []);
/**
* Flush a set of pushed events.
*
* @param string $event
*/
public function flush($event);
/**
* Remove a set of listeners from the dispatcher.
*
* @param string $event
*/
public function forget($event);
/**
* Forget all of the queued listeners.
*/
public function forgetPushed();
}

View File

@@ -0,0 +1,13 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Support;
interface Arrayable
{
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray();
}

View File

@@ -0,0 +1,15 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Support;
interface CanBeEscapedWhenCastToString
{
/**
* Indicate that the object's string representation should be escaped when __toString is invoked.
*
* @param bool $escape
*
* @return $this
*/
public function escapeWhenCastingToString($escape = \true);
}

View File

@@ -0,0 +1,13 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Support;
interface DeferrableProvider
{
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides();
}

View File

@@ -0,0 +1,13 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Support;
interface DeferringDisplayableValue
{
/**
* Resolve the displayable value that the class is deferring.
*
* @return \Illuminate\Contracts\Support\Htmlable|string
*/
public function resolveDisplayableValue();
}

View File

@@ -0,0 +1,13 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Support;
interface Htmlable
{
/**
* Get content as a string of HTML.
*
* @return string
*/
public function toHtml();
}

View File

@@ -0,0 +1,15 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Support;
interface Jsonable
{
/**
* Convert the object to its JSON representation.
*
* @param int $options
*
* @return string
*/
public function toJson($options = 0);
}

View File

@@ -0,0 +1,109 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Support;
use Countable;
interface MessageBag extends Arrayable, Countable
{
/**
* Get the keys present in the message bag.
*
* @return array
*/
public function keys();
/**
* Add a message to the bag.
*
* @param string $key
* @param string $message
*
* @return $this
*/
public function add($key, $message);
/**
* Merge a new array of messages into the bag.
*
* @param array|\Illuminate\Contracts\Support\MessageProvider $messages
*
* @return $this
*/
public function merge($messages);
/**
* Determine if messages exist for a given key.
*
* @param array|string $key
*
* @return bool
*/
public function has($key);
/**
* Get the first message from the bag for a given key.
*
* @param null|string $key
* @param null|string $format
*
* @return string
*/
public function first($key = null, $format = null);
/**
* Get all of the messages from the bag for a given key.
*
* @param string $key
* @param null|string $format
*
* @return array
*/
public function get($key, $format = null);
/**
* Get all of the messages for every key in the bag.
*
* @param null|string $format
*
* @return array
*/
public function all($format = null);
/**
* Get the raw messages in the container.
*
* @return array
*/
public function getMessages();
/**
* Get the default message format.
*
* @return string
*/
public function getFormat();
/**
* Set the default message format.
*
* @param string $format
*
* @return $this
*/
public function setFormat($format = ':message');
/**
* Determine if the message bag has any messages.
*
* @return bool
*/
public function isEmpty();
/**
* Determine if the message bag has any messages.
*
* @return bool
*/
public function isNotEmpty();
}

View File

@@ -0,0 +1,13 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Support;
interface MessageProvider
{
/**
* Get the messages for the instance.
*
* @return \Illuminate\Contracts\Support\MessageBag
*/
public function getMessageBag();
}

View File

@@ -0,0 +1,13 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Support;
interface Renderable
{
/**
* Get the evaluated contents of the object.
*
* @return string
*/
public function render();
}

View File

@@ -0,0 +1,15 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Support;
interface Responsable
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request);
}

View File

@@ -0,0 +1,10 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\Support;
use ArrayAccess;
use IteratorAggregate;
interface ValidatedData extends Arrayable, ArrayAccess, IteratorAggregate
{
}

View File

@@ -0,0 +1,15 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\View;
interface Engine
{
/**
* Get the evaluated contents of the view.
*
* @param string $path
*
* @return string
*/
public function get($path, array $data = []);
}

View File

@@ -0,0 +1,87 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\View;
interface Factory
{
/**
* Determine if a given view exists.
*
* @param string $view
*
* @return bool
*/
public function exists($view);
/**
* Get the evaluated view contents for the given path.
*
* @param string $path
* @param array|\Illuminate\Contracts\Support\Arrayable $data
* @param array $mergeData
*
* @return \Illuminate\Contracts\View\View
*/
public function file($path, $data = [], $mergeData = []);
/**
* Get the evaluated view contents for the given view.
*
* @param string $view
* @param array|\Illuminate\Contracts\Support\Arrayable $data
* @param array $mergeData
*
* @return \Illuminate\Contracts\View\View
*/
public function make($view, $data = [], $mergeData = []);
/**
* Add a piece of shared data to the environment.
*
* @param array|string $key
* @param mixed $value
*
* @return mixed
*/
public function share($key, $value = null);
/**
* Register a view composer event.
*
* @param array|string $views
* @param \Closure|string $callback
*
* @return array
*/
public function composer($views, $callback);
/**
* Register a view creator event.
*
* @param array|string $views
* @param \Closure|string $callback
*
* @return array
*/
public function creator($views, $callback);
/**
* Add a new namespace to the loader.
*
* @param string $namespace
* @param array|string $hints
*
* @return $this
*/
public function addNamespace($namespace, $hints);
/**
* Replace the namespace hints for the given namespace.
*
* @param string $namespace
* @param array|string $hints
*
* @return $this
*/
public function replaceNamespace($namespace, $hints);
}

View File

@@ -0,0 +1,32 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Contracts\View;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Renderable;
interface View extends Renderable
{
/**
* Get the name of the view.
*
* @return string
*/
public function name();
/**
* Add a piece of data to the view.
*
* @param array|string $key
* @param mixed $value
*
* @return $this
*/
public function with($key, $value = null);
/**
* Get the array of view data.
*
* @return array
*/
public function getData();
}

View File

@@ -0,0 +1,168 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Events;
use _JchOptimizeVendor\Illuminate\Bus\Queueable;
use _JchOptimizeVendor\Illuminate\Container\Container;
use _JchOptimizeVendor\Illuminate\Contracts\Queue\Job;
use _JchOptimizeVendor\Illuminate\Contracts\Queue\ShouldQueue;
use _JchOptimizeVendor\Illuminate\Queue\InteractsWithQueue;
class CallQueuedListener implements ShouldQueue
{
use InteractsWithQueue;
use Queueable;
/**
* The listener class name.
*
* @var string
*/
public $class;
/**
* The listener method.
*
* @var string
*/
public $method;
/**
* The data to be passed to the listener.
*
* @var array
*/
public $data;
/**
* The number of times the job may be attempted.
*
* @var int
*/
public $tries;
/**
* The maximum number of exceptions allowed, regardless of attempts.
*
* @var int
*/
public $maxExceptions;
/**
* The number of seconds to wait before retrying a job that encountered an uncaught exception.
*
* @var int
*/
public $backoff;
/**
* The timestamp indicating when the job should timeout.
*
* @var int
*/
public $retryUntil;
/**
* The number of seconds the job can run before timing out.
*
* @var int
*/
public $timeout;
/**
* Indicates if the job should be encrypted.
*
* @var bool
*/
public $shouldBeEncrypted = \false;
/**
* Create a new job instance.
*
* @param string $class
* @param string $method
* @param array $data
*/
public function __construct($class, $method, $data)
{
$this->data = $data;
$this->class = $class;
$this->method = $method;
}
/**
* Prepare the instance for cloning.
*/
public function __clone()
{
$this->data = \array_map(function ($data) {
return \is_object($data) ? clone $data : $data;
}, $this->data);
}
/**
* Handle the queued job.
*
* @param \Illuminate\Container\Container $container
*/
public function handle(Container $container)
{
$this->prepareData();
$handler = $this->setJobInstanceIfNecessary($this->job, $container->make($this->class));
$handler->{$this->method}(...\array_values($this->data));
}
/**
* Call the failed method on the job instance.
*
* The event instance and the exception will be passed.
*
* @param \Throwable $e
*/
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);
}
}
/**
* Get the display name for the queued job.
*
* @return string
*/
public function displayName()
{
return $this->class;
}
/**
* 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;
}
/**
* Unserialize the data if needed.
*/
protected function prepareData()
{
if (\is_string($this->data)) {
$this->data = \unserialize($this->data);
}
}
}

View File

@@ -0,0 +1,624 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Events;
use _JchOptimizeVendor\Illuminate\Container\Container;
use _JchOptimizeVendor\Illuminate\Contracts\Broadcasting\Factory as BroadcastFactory;
use _JchOptimizeVendor\Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use _JchOptimizeVendor\Illuminate\Contracts\Container\Container as ContainerContract;
use _JchOptimizeVendor\Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use _JchOptimizeVendor\Illuminate\Contracts\Queue\ShouldBeEncrypted;
use _JchOptimizeVendor\Illuminate\Contracts\Queue\ShouldQueue;
use _JchOptimizeVendor\Illuminate\Support\Arr;
use _JchOptimizeVendor\Illuminate\Support\Str;
use _JchOptimizeVendor\Illuminate\Support\Traits\Macroable;
use _JchOptimizeVendor\Illuminate\Support\Traits\ReflectsClosures;
use function _JchOptimizeVendor\tap;
class Dispatcher implements DispatcherContract
{
use Macroable;
use ReflectsClosures;
/**
* The IoC container instance.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* The registered event listeners.
*
* @var array
*/
protected $listeners = [];
/**
* The wildcard listeners.
*
* @var array
*/
protected $wildcards = [];
/**
* The cached wildcard listeners.
*
* @var array
*/
protected $wildcardsCache = [];
/**
* The queue resolver instance.
*
* @var callable
*/
protected $queueResolver;
/**
* Create a new event dispatcher instance.
*
* @param null|\Illuminate\Contracts\Container\Container $container
*/
public function __construct(ContainerContract $container = null)
{
$this->container = $container ?: new Container();
}
/**
* Register an event listener with the dispatcher.
*
* @param array|\Closure|string $events
* @param null|array|\Closure|string $listener
*/
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);
}
}
}
/**
* 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
*/
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
*/
public function flush($event)
{
$this->dispatch($event.'_pushed');
}
/**
* Register an event subscriber with the dispatcher.
*
* @param object|string $subscriber
*/
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);
}
}
}
}
/**
* Fire an event until the first non-null response is returned.
*
* @param object|string $event
* @param mixed $payload
*
* @return null|array
*/
public function until($event, $payload = [])
{
return $this->dispatch($event, $payload, \true);
}
/**
* Fire an event and call the listeners.
*
* @param object|string $event
* @param mixed $payload
* @param bool $halt
*
* @return null|array
*/
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 (\false === $response) {
break;
}
$responses[] = $response;
}
return $halt ? null : $responses;
}
/**
* 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;
}
/**
* Register an event listener with the dispatcher.
*
* @param array|\Closure|string $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));
};
}
/**
* Remove a set of listeners from the dispatcher.
*
* @param string $event
*/
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.
*/
public function forgetPushed()
{
foreach ($this->listeners as $key => $value) {
if (Str::endsWith($key, '_pushed')) {
$this->forget($key);
}
}
}
/**
* Set the queue resolver implementation.
*
* @return $this
*/
public function setQueueResolver(callable $resolver)
{
$this->queueResolver = $resolver;
return $this;
}
/**
* Setup a wildcard listener callback.
*
* @param string $event
* @param \Closure|string $listener
*/
protected function setupWildcardListen($event, $listener)
{
$this->wildcards[$event][] = $this->makeListener($listener, \true);
$this->wildcardsCache = [];
}
/**
* 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;
}
/**
* 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.
*
* @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
*/
protected function broadcastEvent($event)
{
$this->container->make(BroadcastFactory::class)->queue($event);
}
/**
* 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
*
* @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;
}
/**
* 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 mixed|object $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
*/
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 ?? []));
});
}
/**
* Get the queue implementation from the resolver.
*
* @return \Illuminate\Contracts\Queue\Queue
*/
protected function resolveQueue()
{
return \call_user_func($this->queueResolver);
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Events;
use _JchOptimizeVendor\Illuminate\Contracts\Queue\Factory as QueueFactoryContract;
use _JchOptimizeVendor\Illuminate\Support\ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*/
public function register()
{
$this->app->singleton('events', function ($app) {
return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
return $app->make(QueueFactoryContract::class);
});
});
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Events;
class InvokeQueuedClosure
{
/**
* Handle the event.
*
* @param \Laravel\SerializableClosure\SerializableClosure $closure
*/
public function handle($closure, array $arguments)
{
\call_user_func($closure->getClosure(), ...$arguments);
}
/**
* Handle a job failure.
*
* @param \Laravel\SerializableClosure\SerializableClosure $closure
* @param \Throwable $exception
*/
public function failed($closure, array $arguments, array $catchCallbacks, $exception)
{
$arguments[] = $exception;
collect($catchCallbacks)->each->__invoke(...$arguments);
}
}

View File

@@ -0,0 +1,135 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Events;
use _JchOptimizeVendor\Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use _JchOptimizeVendor\Illuminate\Support\Traits\ForwardsCalls;
class NullDispatcher implements DispatcherContract
{
use ForwardsCalls;
/**
* The underlying event dispatcher instance.
*
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $dispatcher;
/**
* Create a new event dispatcher instance that does not fire.
*
* @param \Illuminate\Contracts\Events\Dispatcher $dispatcher
*/
public function __construct(DispatcherContract $dispatcher)
{
$this->dispatcher = $dispatcher;
}
/**
* 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);
}
/**
* Don't fire an event.
*
* @param object|string $event
* @param mixed $payload
* @param bool $halt
*/
public function dispatch($event, $payload = [], $halt = \false)
{
}
/**
* Don't register an event and payload to be fired later.
*
* @param string $event
* @param array $payload
*/
public function push($event, $payload = [])
{
}
/**
* Don't dispatch an event.
*
* @param object|string $event
* @param mixed $payload
*
* @return null|array
*/
public function until($event, $payload = [])
{
}
/**
* Register an event listener with the dispatcher.
*
* @param array|\Closure|string $events
* @param null|array|\Closure|string $listener
*/
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
*/
public function subscribe($subscriber)
{
$this->dispatcher->subscribe($subscriber);
}
/**
* Flush a set of pushed events.
*
* @param string $event
*/
public function flush($event)
{
$this->dispatcher->flush($event);
}
/**
* Remove a set of listeners from the dispatcher.
*
* @param string $event
*/
public function forget($event)
{
$this->dispatcher->forget($event);
}
/**
* Forget all of the queued listeners.
*/
public function forgetPushed()
{
$this->dispatcher->forgetPushed();
}
}

View File

@@ -0,0 +1,120 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Events;
use _JchOptimizeVendor\Illuminate\Queue\SerializableClosureFactory;
use Closure;
class QueuedClosure
{
/**
* The underlying Closure.
*
* @var \Closure
*/
public $closure;
/**
* The name of the connection the job should be sent to.
*
* @var null|string
*/
public $connection;
/**
* The name of the queue the job should be sent to.
*
* @var null|string
*/
public $queue;
/**
* The number of seconds before the job should be made available.
*
* @var null|\DateInterval|\DateTimeInterface|int
*/
public $delay;
/**
* All of the "catch" callbacks for the queued closure.
*
* @var array
*/
public $catchCallbacks = [];
/**
* Create a new queued closure event listener resolver.
*/
public function __construct(\Closure $closure)
{
$this->closure = $closure;
}
/**
* Set the desired connection for the job.
*
* @param null|string $connection
*
* @return $this
*/
public function onConnection($connection)
{
$this->connection = $connection;
return $this;
}
/**
* Set the desired queue for the job.
*
* @param null|string $queue
*
* @return $this
*/
public function onQueue($queue)
{
$this->queue = $queue;
return $this;
}
/**
* Set the desired delay for the job.
*
* @param null|\DateInterval|\DateTimeInterface|int $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.
*
* @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);
};
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Events;
use Closure;
if (!\function_exists('_JchOptimizeVendor\\Illuminate\\Events\\queueable')) {
/**
* Create a new queued Closure event listener.
*
* @return \Illuminate\Events\QueuedClosure
*/
function queueable(\Closure $closure)
{
return new QueuedClosure($closure);
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Filesystem;
use _JchOptimizeVendor\Illuminate\Contracts\Cache\Repository;
use _JchOptimizeVendor\League\Flysystem\Cached\Storage\AbstractCache;
class Cache extends AbstractCache
{
/**
* The cache repository implementation.
*
* @var \Illuminate\Contracts\Cache\Repository
*/
protected $repository;
/**
* The cache key.
*
* @var string
*/
protected $key;
/**
* The cache expiration time in seconds.
*
* @var null|int
*/
protected $expire;
/**
* Create a new cache instance.
*
* @param \Illuminate\Contracts\Cache\Repository $repository
* @param string $key
* @param null|int $expire
*/
public function __construct(Repository $repository, $key = 'flysystem', $expire = null)
{
$this->key = $key;
$this->expire = $expire;
$this->repository = $repository;
}
/**
* Load the cache.
*/
public function load()
{
$contents = $this->repository->get($this->key);
if (!\is_null($contents)) {
$this->setFromStorage($contents);
}
}
/**
* Persist the cache.
*/
public function save()
{
$contents = $this->getForStorage();
$this->repository->put($this->key, $contents, $this->expire);
}
}

View File

@@ -0,0 +1,718 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Filesystem;
use _JchOptimizeVendor\Illuminate\Contracts\Filesystem\FileNotFoundException;
use _JchOptimizeVendor\Illuminate\Support\LazyCollection;
use _JchOptimizeVendor\Illuminate\Support\Traits\Macroable;
use _JchOptimizeVendor\Symfony\Component\Filesystem\Filesystem as SymfonyFilesystem;
use _JchOptimizeVendor\Symfony\Component\Finder\Finder;
use _JchOptimizeVendor\Symfony\Component\Mime\MimeTypes;
class Filesystem
{
use Macroable;
/**
* Determine if a file or directory exists.
*
* @param string $path
*
* @return bool
*/
public function exists($path)
{
return \file_exists($path);
}
/**
* Determine if a file or directory is missing.
*
* @param string $path
*
* @return bool
*/
public function missing($path)
{
return !$this->exists($path);
}
/**
* Get the contents of a file.
*
* @param string $path
* @param bool $lock
*
* @return string
*
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get($path, $lock = \false)
{
if ($this->isFile($path)) {
return $lock ? $this->sharedGet($path) : \file_get_contents($path);
}
throw new FileNotFoundException("File does not exist at path {$path}.");
}
/**
* Get contents of a file with shared access.
*
* @param string $path
*
* @return string
*/
public function sharedGet($path)
{
$contents = '';
$handle = \fopen($path, 'rb');
if ($handle) {
try {
if (\flock($handle, \LOCK_SH)) {
\clearstatcache(\true, $path);
$contents = \fread($handle, $this->size($path) ?: 1);
\flock($handle, \LOCK_UN);
}
} finally {
\fclose($handle);
}
}
return $contents;
}
/**
* Get the returned value of a file.
*
* @param string $path
*
* @return mixed
*
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function getRequire($path, array $data = [])
{
if ($this->isFile($path)) {
$__path = $path;
$__data = $data;
return (static function () use ($__path, $__data) {
\extract($__data, \EXTR_SKIP);
return require $__path;
})();
}
throw new FileNotFoundException("File does not exist at path {$path}.");
}
/**
* Require the given file once.
*
* @param string $path
*
* @return mixed
*
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function requireOnce($path, array $data = [])
{
if ($this->isFile($path)) {
$__path = $path;
$__data = $data;
return (static function () use ($__path, $__data) {
\extract($__data, \EXTR_SKIP);
return require_once $__path;
})();
}
throw new FileNotFoundException("File does not exist at path {$path}.");
}
/**
* Get the contents of a file one line at a time.
*
* @param string $path
*
* @return \Illuminate\Support\LazyCollection
*
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function lines($path)
{
if (!$this->isFile($path)) {
throw new FileNotFoundException("File does not exist at path {$path}.");
}
return LazyCollection::make(function () use ($path) {
$file = new \SplFileObject($path);
$file->setFlags(\SplFileObject::DROP_NEW_LINE);
while (!$file->eof()) {
yield $file->fgets();
}
});
}
/**
* Get the MD5 hash of the file at the given path.
*
* @param string $path
*
* @return string
*/
public function hash($path)
{
return \md5_file($path);
}
/**
* Write the contents of a file.
*
* @param string $path
* @param string $contents
* @param bool $lock
*
* @return bool|int
*/
public function put($path, $contents, $lock = \false)
{
return \file_put_contents($path, $contents, $lock ? \LOCK_EX : 0);
}
/**
* Write the contents of a file, replacing it atomically if it already exists.
*
* @param string $path
* @param string $content
*/
public function replace($path, $content)
{
// If the path already exists and is a symlink, get the real path...
\clearstatcache(\true, $path);
$path = \realpath($path) ?: $path;
$tempPath = \tempnam(\dirname($path), \basename($path));
// Fix permissions of tempPath because `tempnam()` creates it with permissions set to 0600...
\chmod($tempPath, 0777 - \umask());
\file_put_contents($tempPath, $content);
\rename($tempPath, $path);
}
/**
* Replace a given string within a given file.
*
* @param array|string $search
* @param array|string $replace
* @param string $path
*/
public function replaceInFile($search, $replace, $path)
{
\file_put_contents($path, \str_replace($search, $replace, \file_get_contents($path)));
}
/**
* Prepend to a file.
*
* @param string $path
* @param string $data
*
* @return int
*/
public function prepend($path, $data)
{
if ($this->exists($path)) {
return $this->put($path, $data.$this->get($path));
}
return $this->put($path, $data);
}
/**
* Append to a file.
*
* @param string $path
* @param string $data
*
* @return int
*/
public function append($path, $data)
{
return \file_put_contents($path, $data, \FILE_APPEND);
}
/**
* Get or set UNIX mode of a file or directory.
*
* @param string $path
* @param null|int $mode
*
* @return mixed
*/
public function chmod($path, $mode = null)
{
if ($mode) {
return \chmod($path, $mode);
}
return \substr(\sprintf('%o', \fileperms($path)), -4);
}
/**
* Delete the file at a given path.
*
* @param array|string $paths
*
* @return bool
*/
public function delete($paths)
{
$paths = \is_array($paths) ? $paths : \func_get_args();
$success = \true;
foreach ($paths as $path) {
try {
if (@\unlink($path)) {
\clearstatcache(\false, $path);
} else {
$success = \false;
}
} catch (\ErrorException $e) {
$success = \false;
}
}
return $success;
}
/**
* Move a file to a new location.
*
* @param string $path
* @param string $target
*
* @return bool
*/
public function move($path, $target)
{
return \rename($path, $target);
}
/**
* Copy a file to a new location.
*
* @param string $path
* @param string $target
*
* @return bool
*/
public function copy($path, $target)
{
return \copy($path, $target);
}
/**
* Create a symlink to the target file or directory. On Windows, a hard link is created if the target is a file.
*
* @param string $target
* @param string $link
*/
public function link($target, $link)
{
if (!windows_os()) {
return \symlink($target, $link);
}
$mode = $this->isDirectory($target) ? 'J' : 'H';
\exec("mklink /{$mode} ".\escapeshellarg($link).' '.\escapeshellarg($target));
}
/**
* Create a relative symlink to the target file or directory.
*
* @param string $target
* @param string $link
*
* @throws \RuntimeException
*/
public function relativeLink($target, $link)
{
if (!\class_exists(SymfonyFilesystem::class)) {
throw new \RuntimeException('To enable support for relative links, please install the symfony/filesystem package.');
}
$relativeTarget = (new SymfonyFilesystem())->makePathRelative($target, \dirname($link));
$this->link($relativeTarget, $link);
}
/**
* Extract the file name from a file path.
*
* @param string $path
*
* @return string
*/
public function name($path)
{
return \pathinfo($path, \PATHINFO_FILENAME);
}
/**
* Extract the trailing name component from a file path.
*
* @param string $path
*
* @return string
*/
public function basename($path)
{
return \pathinfo($path, \PATHINFO_BASENAME);
}
/**
* Extract the parent directory from a file path.
*
* @param string $path
*
* @return string
*/
public function dirname($path)
{
return \pathinfo($path, \PATHINFO_DIRNAME);
}
/**
* Extract the file extension from a file path.
*
* @param string $path
*
* @return string
*/
public function extension($path)
{
return \pathinfo($path, \PATHINFO_EXTENSION);
}
/**
* Guess the file extension from the mime-type of a given file.
*
* @param string $path
*
* @return null|string
*
* @throws \RuntimeException
*/
public function guessExtension($path)
{
if (!\class_exists(MimeTypes::class)) {
throw new \RuntimeException('To enable support for guessing extensions, please install the symfony/mime package.');
}
return (new MimeTypes())->getExtensions($this->mimeType($path))[0] ?? null;
}
/**
* Get the file type of a given file.
*
* @param string $path
*
* @return string
*/
public function type($path)
{
return \filetype($path);
}
/**
* Get the mime-type of a given file.
*
* @param string $path
*
* @return false|string
*/
public function mimeType($path)
{
return \finfo_file(\finfo_open(\FILEINFO_MIME_TYPE), $path);
}
/**
* Get the file size of a given file.
*
* @param string $path
*
* @return int
*/
public function size($path)
{
return \filesize($path);
}
/**
* Get the file's last modification time.
*
* @param string $path
*
* @return int
*/
public function lastModified($path)
{
return \filemtime($path);
}
/**
* Determine if the given path is a directory.
*
* @param string $directory
*
* @return bool
*/
public function isDirectory($directory)
{
return \is_dir($directory);
}
/**
* Determine if the given path is readable.
*
* @param string $path
*
* @return bool
*/
public function isReadable($path)
{
return \is_readable($path);
}
/**
* Determine if the given path is writable.
*
* @param string $path
*
* @return bool
*/
public function isWritable($path)
{
return \is_writable($path);
}
/**
* Determine if the given path is a file.
*
* @param string $file
*
* @return bool
*/
public function isFile($file)
{
return \is_file($file);
}
/**
* Find path names matching a given pattern.
*
* @param string $pattern
* @param int $flags
*
* @return array
*/
public function glob($pattern, $flags = 0)
{
return \glob($pattern, $flags);
}
/**
* Get an array of all files in a directory.
*
* @param string $directory
* @param bool $hidden
*
* @return \Symfony\Component\Finder\SplFileInfo[]
*/
public function files($directory, $hidden = \false)
{
return \iterator_to_array(Finder::create()->files()->ignoreDotFiles(!$hidden)->in($directory)->depth(0)->sortByName(), \false);
}
/**
* Get all of the files from the given directory (recursive).
*
* @param string $directory
* @param bool $hidden
*
* @return \Symfony\Component\Finder\SplFileInfo[]
*/
public function allFiles($directory, $hidden = \false)
{
return \iterator_to_array(Finder::create()->files()->ignoreDotFiles(!$hidden)->in($directory)->sortByName(), \false);
}
/**
* Get all of the directories within a given directory.
*
* @param string $directory
*
* @return array
*/
public function directories($directory)
{
$directories = [];
foreach (Finder::create()->in($directory)->directories()->depth(0)->sortByName() as $dir) {
$directories[] = $dir->getPathname();
}
return $directories;
}
/**
* Ensure a directory exists.
*
* @param string $path
* @param int $mode
* @param bool $recursive
*/
public function ensureDirectoryExists($path, $mode = 0755, $recursive = \true)
{
if (!$this->isDirectory($path)) {
$this->makeDirectory($path, $mode, $recursive);
}
}
/**
* Create a directory.
*
* @param string $path
* @param int $mode
* @param bool $recursive
* @param bool $force
*
* @return bool
*/
public function makeDirectory($path, $mode = 0755, $recursive = \false, $force = \false)
{
if ($force) {
return @\mkdir($path, $mode, $recursive);
}
return \mkdir($path, $mode, $recursive);
}
/**
* Move a directory.
*
* @param string $from
* @param string $to
* @param bool $overwrite
*
* @return bool
*/
public function moveDirectory($from, $to, $overwrite = \false)
{
if ($overwrite && $this->isDirectory($to) && !$this->deleteDirectory($to)) {
return \false;
}
return \true === @\rename($from, $to);
}
/**
* Copy a directory from one location to another.
*
* @param string $directory
* @param string $destination
* @param null|int $options
*
* @return bool
*/
public function copyDirectory($directory, $destination, $options = null)
{
if (!$this->isDirectory($directory)) {
return \false;
}
$options = $options ?: \FilesystemIterator::SKIP_DOTS;
// If the destination directory does not actually exist, we will go ahead and
// create it recursively, which just gets the destination prepared to copy
// the files over. Once we make the directory we'll proceed the copying.
$this->ensureDirectoryExists($destination, 0777);
$items = new \FilesystemIterator($directory, $options);
foreach ($items as $item) {
// As we spin through items, we will check to see if the current file is actually
// a directory or a file. When it is actually a directory we will need to call
// back into this function recursively to keep copying these nested folders.
$target = $destination.'/'.$item->getBasename();
if ($item->isDir()) {
$path = $item->getPathname();
if (!$this->copyDirectory($path, $target, $options)) {
return \false;
}
} else {
if (!$this->copy($item->getPathname(), $target)) {
return \false;
}
}
}
return \true;
}
/**
* Recursively delete a directory.
*
* The directory itself may be optionally preserved.
*
* @param string $directory
* @param bool $preserve
*
* @return bool
*/
public function deleteDirectory($directory, $preserve = \false)
{
if (!$this->isDirectory($directory)) {
return \false;
}
$items = new \FilesystemIterator($directory);
foreach ($items as $item) {
// If the item is a directory, we can just recurse into the function and
// delete that sub-directory otherwise we'll just delete the file and
// keep iterating through each file until the directory is cleaned.
if ($item->isDir() && !$item->isLink()) {
$this->deleteDirectory($item->getPathname());
} else {
$this->delete($item->getPathname());
}
}
if (!$preserve) {
@\rmdir($directory);
}
return \true;
}
/**
* Remove all of the directories within a given directory.
*
* @param string $directory
*
* @return bool
*/
public function deleteDirectories($directory)
{
$allDirectories = $this->directories($directory);
if (!empty($allDirectories)) {
foreach ($allDirectories as $directoryName) {
$this->deleteDirectory($directoryName);
}
return \true;
}
return \false;
}
/**
* Empty the specified directory of all files and folders.
*
* @param string $directory
*
* @return bool
*/
public function cleanDirectory($directory)
{
return $this->deleteDirectory($directory, \true);
}
}

View File

@@ -0,0 +1,787 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Filesystem;
use _JchOptimizeVendor\Illuminate\Contracts\Filesystem\Cloud as CloudFilesystemContract;
use _JchOptimizeVendor\Illuminate\Contracts\Filesystem\FileExistsException as ContractFileExistsException;
use _JchOptimizeVendor\Illuminate\Contracts\Filesystem\FileNotFoundException as ContractFileNotFoundException;
use _JchOptimizeVendor\Illuminate\Contracts\Filesystem\Filesystem as FilesystemContract;
use _JchOptimizeVendor\Illuminate\Http\File;
use _JchOptimizeVendor\Illuminate\Http\UploadedFile;
use _JchOptimizeVendor\Illuminate\Support\Arr;
use _JchOptimizeVendor\Illuminate\Support\Collection;
use _JchOptimizeVendor\Illuminate\Support\Str;
use _JchOptimizeVendor\Illuminate\Support\Traits\Macroable;
use _JchOptimizeVendor\League\Flysystem\Adapter\Ftp;
use _JchOptimizeVendor\League\Flysystem\Adapter\Local as LocalAdapter;
use _JchOptimizeVendor\League\Flysystem\AdapterInterface;
use _JchOptimizeVendor\League\Flysystem\AwsS3v3\AwsS3Adapter;
use _JchOptimizeVendor\League\Flysystem\Cached\CachedAdapter;
use _JchOptimizeVendor\League\Flysystem\FileExistsException;
use _JchOptimizeVendor\League\Flysystem\FileNotFoundException;
use _JchOptimizeVendor\League\Flysystem\FilesystemInterface;
use _JchOptimizeVendor\League\Flysystem\Sftp\SftpAdapter as Sftp;
use _JchOptimizeVendor\PHPUnit\Framework\Assert as PHPUnit;
use _JchOptimizeVendor\Psr\Http\Message\StreamInterface;
use _JchOptimizeVendor\Psr\Http\Message\UriInterface;
use _JchOptimizeVendor\Symfony\Component\HttpFoundation\StreamedResponse;
/**
* @mixin \League\Flysystem\FilesystemInterface
*/
class FilesystemAdapter implements CloudFilesystemContract
{
use Macroable {
__call as macroCall;
}
/**
* The Flysystem filesystem implementation.
*
* @var \League\Flysystem\FilesystemInterface
*/
protected $driver;
/**
* The temporary URL builder callback.
*
* @var null|\Closure
*/
protected $temporaryUrlCallback;
/**
* Create a new filesystem adapter instance.
*
* @param \League\Flysystem\FilesystemInterface $driver
*/
public function __construct(FilesystemInterface $driver)
{
$this->driver = $driver;
}
/**
* Pass dynamic methods call onto Flysystem.
*
* @param string $method
*
* @return mixed
*
* @throws \BadMethodCallException
*/
public function __call($method, array $parameters)
{
if (static::hasMacro($method)) {
return $this->macroCall($method, $parameters);
}
return $this->driver->{$method}(...$parameters);
}
/**
* Assert that the given file exists.
*
* @param array|string $path
* @param null|string $content
*
* @return $this
*/
public function assertExists($path, $content = null)
{
\clearstatcache();
$paths = Arr::wrap($path);
foreach ($paths as $path) {
PHPUnit::assertTrue($this->exists($path), "Unable to find a file at path [{$path}].");
if (!\is_null($content)) {
$actual = $this->get($path);
PHPUnit::assertSame($content, $actual, "File [{$path}] was found, but content [{$actual}] does not match [{$content}].");
}
}
return $this;
}
/**
* Assert that the given file does not exist.
*
* @param array|string $path
*
* @return $this
*/
public function assertMissing($path)
{
\clearstatcache();
$paths = Arr::wrap($path);
foreach ($paths as $path) {
PHPUnit::assertFalse($this->exists($path), "Found unexpected file at path [{$path}].");
}
return $this;
}
/**
* Determine if a file exists.
*
* @param string $path
*
* @return bool
*/
public function exists($path)
{
return $this->driver->has($path);
}
/**
* Determine if a file or directory is missing.
*
* @param string $path
*
* @return bool
*/
public function missing($path)
{
return !$this->exists($path);
}
/**
* Get the full path for the file at the given "short" path.
*
* @param string $path
*
* @return string
*/
public function path($path)
{
$adapter = $this->driver->getAdapter();
if ($adapter instanceof CachedAdapter) {
$adapter = $adapter->getAdapter();
}
return $adapter->getPathPrefix().$path;
}
/**
* Get the contents of a file.
*
* @param string $path
*
* @return string
*
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get($path)
{
try {
return $this->driver->read($path);
} catch (FileNotFoundException $e) {
throw new ContractFileNotFoundException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* Create a streamed response for a given file.
*
* @param string $path
* @param null|string $name
* @param null|array $headers
* @param null|string $disposition
*
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function response($path, $name = null, array $headers = [], $disposition = 'inline')
{
$response = new StreamedResponse();
$filename = $name ?? \basename($path);
$disposition = $response->headers->makeDisposition($disposition, $filename, $this->fallbackName($filename));
$response->headers->replace($headers + ['Content-Type' => $this->mimeType($path), 'Content-Length' => $this->size($path), 'Content-Disposition' => $disposition]);
$response->setCallback(function () use ($path) {
$stream = $this->readStream($path);
\fpassthru($stream);
\fclose($stream);
});
return $response;
}
/**
* Create a streamed download response for a given file.
*
* @param string $path
* @param null|string $name
* @param null|array $headers
*
* @return \Symfony\Component\HttpFoundation\StreamedResponse
*/
public function download($path, $name = null, array $headers = [])
{
return $this->response($path, $name, $headers, 'attachment');
}
/**
* Write the contents of a file.
*
* @param string $path
* @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile|\Psr\Http\Message\StreamInterface|resource|string $contents
* @param mixed $options
*
* @return bool
*/
public function put($path, $contents, $options = [])
{
$options = \is_string($options) ? ['visibility' => $options] : (array) $options;
// If the given contents is actually a file or uploaded file instance than we will
// automatically store the file using a stream. This provides a convenient path
// for the developer to store streams without managing them manually in code.
if ($contents instanceof File || $contents instanceof UploadedFile) {
return $this->putFile($path, $contents, $options);
}
if ($contents instanceof StreamInterface) {
return $this->driver->putStream($path, $contents->detach(), $options);
}
return \is_resource($contents) ? $this->driver->putStream($path, $contents, $options) : $this->driver->put($path, $contents, $options);
}
/**
* Store the uploaded file on the disk.
*
* @param string $path
* @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string $file
* @param mixed $options
*
* @return false|string
*/
public function putFile($path, $file, $options = [])
{
$file = \is_string($file) ? new File($file) : $file;
return $this->putFileAs($path, $file, $file->hashName(), $options);
}
/**
* Store the uploaded file on the disk with a given name.
*
* @param string $path
* @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string $file
* @param string $name
* @param mixed $options
*
* @return false|string
*/
public function putFileAs($path, $file, $name, $options = [])
{
$stream = \fopen(\is_string($file) ? $file : $file->getRealPath(), 'r');
// Next, we will format the path of the file and store the file using a stream since
// they provide better performance than alternatives. Once we write the file this
// stream will get closed automatically by us so the developer doesn't have to.
$result = $this->put($path = \trim($path.'/'.$name, '/'), $stream, $options);
if (\is_resource($stream)) {
\fclose($stream);
}
return $result ? $path : \false;
}
/**
* Get the visibility for the given path.
*
* @param string $path
*
* @return string
*/
public function getVisibility($path)
{
if (AdapterInterface::VISIBILITY_PUBLIC == $this->driver->getVisibility($path)) {
return FilesystemContract::VISIBILITY_PUBLIC;
}
return FilesystemContract::VISIBILITY_PRIVATE;
}
/**
* Set the visibility for the given path.
*
* @param string $path
* @param string $visibility
*
* @return bool
*/
public function setVisibility($path, $visibility)
{
return $this->driver->setVisibility($path, $this->parseVisibility($visibility));
}
/**
* Prepend to a file.
*
* @param string $path
* @param string $data
* @param string $separator
*
* @return bool
*/
public function prepend($path, $data, $separator = \PHP_EOL)
{
if ($this->exists($path)) {
return $this->put($path, $data.$separator.$this->get($path));
}
return $this->put($path, $data);
}
/**
* Append to a file.
*
* @param string $path
* @param string $data
* @param string $separator
*
* @return bool
*/
public function append($path, $data, $separator = \PHP_EOL)
{
if ($this->exists($path)) {
return $this->put($path, $this->get($path).$separator.$data);
}
return $this->put($path, $data);
}
/**
* Delete the file at a given path.
*
* @param array|string $paths
*
* @return bool
*/
public function delete($paths)
{
$paths = \is_array($paths) ? $paths : \func_get_args();
$success = \true;
foreach ($paths as $path) {
try {
if (!$this->driver->delete($path)) {
$success = \false;
}
} catch (FileNotFoundException $e) {
$success = \false;
}
}
return $success;
}
/**
* Copy a file to a new location.
*
* @param string $from
* @param string $to
*
* @return bool
*/
public function copy($from, $to)
{
return $this->driver->copy($from, $to);
}
/**
* Move a file to a new location.
*
* @param string $from
* @param string $to
*
* @return bool
*/
public function move($from, $to)
{
return $this->driver->rename($from, $to);
}
/**
* Get the file size of a given file.
*
* @param string $path
*
* @return int
*/
public function size($path)
{
return $this->driver->getSize($path);
}
/**
* Get the mime-type of a given file.
*
* @param string $path
*
* @return false|string
*/
public function mimeType($path)
{
return $this->driver->getMimetype($path);
}
/**
* Get the file's last modification time.
*
* @param string $path
*
* @return int
*/
public function lastModified($path)
{
return $this->driver->getTimestamp($path);
}
/**
* Get the URL for the file at the given path.
*
* @param string $path
*
* @return string
*
* @throws \RuntimeException
*/
public function url($path)
{
$adapter = $this->driver->getAdapter();
if ($adapter instanceof CachedAdapter) {
$adapter = $adapter->getAdapter();
}
if (\method_exists($adapter, 'getUrl')) {
return $adapter->getUrl($path);
}
if (\method_exists($this->driver, 'getUrl')) {
return $this->driver->getUrl($path);
}
if ($adapter instanceof AwsS3Adapter) {
return $this->getAwsUrl($adapter, $path);
}
if ($adapter instanceof Ftp || $adapter instanceof Sftp) {
return $this->getFtpUrl($path);
}
if ($adapter instanceof LocalAdapter) {
return $this->getLocalUrl($path);
}
throw new \RuntimeException('This driver does not support retrieving URLs.');
}
public function readStream($path)
{
try {
return $this->driver->readStream($path) ?: null;
} catch (FileNotFoundException $e) {
throw new ContractFileNotFoundException($e->getMessage(), $e->getCode(), $e);
}
}
public function writeStream($path, $resource, array $options = [])
{
try {
return $this->driver->writeStream($path, $resource, $options);
} catch (FileExistsException $e) {
throw new ContractFileExistsException($e->getMessage(), $e->getCode(), $e);
}
}
/**
* Get a temporary URL for the file at the given path.
*
* @param string $path
* @param \DateTimeInterface $expiration
*
* @return string
*
* @throws \RuntimeException
*/
public function temporaryUrl($path, $expiration, array $options = [])
{
$adapter = $this->driver->getAdapter();
if ($adapter instanceof CachedAdapter) {
$adapter = $adapter->getAdapter();
}
if (\method_exists($adapter, 'getTemporaryUrl')) {
return $adapter->getTemporaryUrl($path, $expiration, $options);
}
if ($this->temporaryUrlCallback) {
return $this->temporaryUrlCallback->bindTo($this, static::class)($path, $expiration, $options);
}
if ($adapter instanceof AwsS3Adapter) {
return $this->getAwsTemporaryUrl($adapter, $path, $expiration, $options);
}
throw new \RuntimeException('This driver does not support creating temporary URLs.');
}
/**
* Get a temporary URL for the file at the given path.
*
* @param \League\Flysystem\AwsS3v3\AwsS3Adapter $adapter
* @param string $path
* @param \DateTimeInterface $expiration
* @param array $options
*
* @return string
*/
public function getAwsTemporaryUrl($adapter, $path, $expiration, $options)
{
$client = $adapter->getClient();
$command = $client->getCommand('GetObject', \array_merge(['Bucket' => $adapter->getBucket(), 'Key' => $adapter->getPathPrefix().$path], $options));
$uri = $client->createPresignedRequest($command, $expiration)->getUri();
// If an explicit base URL has been set on the disk configuration then we will use
// it as the base URL instead of the default path. This allows the developer to
// have full control over the base path for this filesystem's generated URLs.
if (!\is_null($url = $this->driver->getConfig()->get('temporary_url'))) {
$uri = $this->replaceBaseUrl($uri, $url);
}
return (string) $uri;
}
/**
* Get an array of all files in a directory.
*
* @param null|string $directory
* @param bool $recursive
*
* @return array
*/
public function files($directory = null, $recursive = \false)
{
$contents = $this->driver->listContents($directory ?? '', $recursive);
return $this->filterContentsByType($contents, 'file');
}
/**
* Get all of the files from the given directory (recursive).
*
* @param null|string $directory
*
* @return array
*/
public function allFiles($directory = null)
{
return $this->files($directory, \true);
}
/**
* Get all of the directories within a given directory.
*
* @param null|string $directory
* @param bool $recursive
*
* @return array
*/
public function directories($directory = null, $recursive = \false)
{
$contents = $this->driver->listContents($directory ?? '', $recursive);
return $this->filterContentsByType($contents, 'dir');
}
/**
* Get all (recursive) of the directories within a given directory.
*
* @param null|string $directory
*
* @return array
*/
public function allDirectories($directory = null)
{
return $this->directories($directory, \true);
}
/**
* Create a directory.
*
* @param string $path
*
* @return bool
*/
public function makeDirectory($path)
{
return $this->driver->createDir($path);
}
/**
* Recursively delete a directory.
*
* @param string $directory
*
* @return bool
*/
public function deleteDirectory($directory)
{
return $this->driver->deleteDir($directory);
}
/**
* Flush the Flysystem cache.
*/
public function flushCache()
{
$adapter = $this->driver->getAdapter();
if ($adapter instanceof CachedAdapter) {
$adapter->getCache()->flush();
}
}
/**
* Get the Flysystem driver.
*
* @return \League\Flysystem\FilesystemInterface
*/
public function getDriver()
{
return $this->driver;
}
/**
* Define a custom temporary URL builder callback.
*/
public function buildTemporaryUrlsUsing(\Closure $callback)
{
$this->temporaryUrlCallback = $callback;
}
/**
* Convert the string to ASCII characters that are equivalent to the given name.
*
* @param string $name
*
* @return string
*/
protected function fallbackName($name)
{
return \str_replace('%', '', Str::ascii($name));
}
/**
* Get the URL for the file at the given path.
*
* @param \League\Flysystem\AwsS3v3\AwsS3Adapter $adapter
* @param string $path
*
* @return string
*/
protected function getAwsUrl($adapter, $path)
{
// If an explicit base URL has been set on the disk configuration then we will use
// it as the base URL instead of the default path. This allows the developer to
// have full control over the base path for this filesystem's generated URLs.
if (!\is_null($url = $this->driver->getConfig()->get('url'))) {
return $this->concatPathToUrl($url, $adapter->getPathPrefix().$path);
}
return $adapter->getClient()->getObjectUrl($adapter->getBucket(), $adapter->getPathPrefix().$path);
}
/**
* Get the URL for the file at the given path.
*
* @param string $path
*
* @return string
*/
protected function getFtpUrl($path)
{
$config = $this->driver->getConfig();
return $config->has('url') ? $this->concatPathToUrl($config->get('url'), $path) : $path;
}
/**
* Get the URL for the file at the given path.
*
* @param string $path
*
* @return string
*/
protected function getLocalUrl($path)
{
$config = $this->driver->getConfig();
// If an explicit base URL has been set on the disk configuration then we will use
// it as the base URL instead of the default path. This allows the developer to
// have full control over the base path for this filesystem's generated URLs.
if ($config->has('url')) {
return $this->concatPathToUrl($config->get('url'), $path);
}
$path = '/storage/'.$path;
// If the path contains "storage/public", it probably means the developer is using
// the default disk to generate the path instead of the "public" disk like they
// are really supposed to use. We will remove the public from this path here.
if (Str::contains($path, '/storage/public/')) {
return Str::replaceFirst('/public/', '/', $path);
}
return $path;
}
/**
* Concatenate a path to a URL.
*
* @param string $url
* @param string $path
*
* @return string
*/
protected function concatPathToUrl($url, $path)
{
return \rtrim($url, '/').'/'.\ltrim($path, '/');
}
/**
* Replace the scheme, host and port of the given UriInterface with values from the given URL.
*
* @param \Psr\Http\Message\UriInterface $uri
* @param string $url
*
* @return \Psr\Http\Message\UriInterface
*/
protected function replaceBaseUrl($uri, $url)
{
$parsed = \parse_url($url);
return $uri->withScheme($parsed['scheme'])->withHost($parsed['host'])->withPort($parsed['port'] ?? null);
}
/**
* Filter directory contents by type.
*
* @param array $contents
* @param string $type
*
* @return array
*/
protected function filterContentsByType($contents, $type)
{
return Collection::make($contents)->where('type', $type)->pluck('path')->values()->all();
}
/**
* Parse the given visibility value.
*
* @param null|string $visibility
*
* @return null|string
*
* @throws \InvalidArgumentException
*/
protected function parseVisibility($visibility)
{
if (\is_null($visibility)) {
return;
}
switch ($visibility) {
case FilesystemContract::VISIBILITY_PUBLIC:
return AdapterInterface::VISIBILITY_PUBLIC;
case FilesystemContract::VISIBILITY_PRIVATE:
return AdapterInterface::VISIBILITY_PRIVATE;
}
throw new \InvalidArgumentException("Unknown visibility: {$visibility}.");
}
}

View File

@@ -0,0 +1,385 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Filesystem;
use _JchOptimizeVendor\Aws\S3\S3Client;
use _JchOptimizeVendor\Illuminate\Contracts\Filesystem\Factory as FactoryContract;
use _JchOptimizeVendor\Illuminate\Support\Arr;
use _JchOptimizeVendor\League\Flysystem\Adapter\Ftp as FtpAdapter;
use _JchOptimizeVendor\League\Flysystem\Adapter\Local as LocalAdapter;
use _JchOptimizeVendor\League\Flysystem\AdapterInterface;
use _JchOptimizeVendor\League\Flysystem\AwsS3v3\AwsS3Adapter as S3Adapter;
use _JchOptimizeVendor\League\Flysystem\Cached\CachedAdapter;
use _JchOptimizeVendor\League\Flysystem\Cached\Storage\Memory as MemoryStore;
use _JchOptimizeVendor\League\Flysystem\Filesystem as Flysystem;
use _JchOptimizeVendor\League\Flysystem\FilesystemInterface;
use _JchOptimizeVendor\League\Flysystem\Sftp\SftpAdapter;
use Closure;
/**
* @mixin \Illuminate\Contracts\Filesystem\Filesystem
*/
class FilesystemManager implements FactoryContract
{
/**
* The application instance.
*
* @var \Illuminate\Contracts\Foundation\Application
*/
protected $app;
/**
* The array of resolved filesystem drivers.
*
* @var array
*/
protected $disks = [];
/**
* The registered custom driver creators.
*
* @var array
*/
protected $customCreators = [];
/**
* Create a new filesystem manager instance.
*
* @param \Illuminate\Contracts\Foundation\Application $app
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->disk()->{$method}(...$parameters);
}
/**
* Get a filesystem instance.
*
* @param null|string $name
*
* @return \Illuminate\Contracts\Filesystem\Filesystem
*/
public function drive($name = null)
{
return $this->disk($name);
}
/**
* Get a filesystem instance.
*
* @param null|string $name
*
* @return \Illuminate\Contracts\Filesystem\Filesystem
*/
public function disk($name = null)
{
$name = $name ?: $this->getDefaultDriver();
return $this->disks[$name] = $this->get($name);
}
/**
* Get a default cloud filesystem instance.
*
* @return \Illuminate\Contracts\Filesystem\Filesystem
*/
public function cloud()
{
$name = $this->getDefaultCloudDriver();
return $this->disks[$name] = $this->get($name);
}
/**
* Build an on-demand disk.
*
* @param array|string $config
*
* @return \Illuminate\Contracts\Filesystem\Filesystem
*/
public function build($config)
{
return $this->resolve('ondemand', \is_array($config) ? $config : ['driver' => 'local', 'root' => $config]);
}
/**
* Create an instance of the local driver.
*
* @return \Illuminate\Contracts\Filesystem\Filesystem
*/
public function createLocalDriver(array $config)
{
$permissions = $config['permissions'] ?? [];
$links = ($config['links'] ?? null) === 'skip' ? LocalAdapter::SKIP_LINKS : LocalAdapter::DISALLOW_LINKS;
return $this->adapt($this->createFlysystem(new LocalAdapter($config['root'], $config['lock'] ?? \LOCK_EX, $links, $permissions), $config));
}
/**
* Create an instance of the ftp driver.
*
* @return \Illuminate\Contracts\Filesystem\Filesystem
*/
public function createFtpDriver(array $config)
{
return $this->adapt($this->createFlysystem(new FtpAdapter($config), $config));
}
/**
* Create an instance of the sftp driver.
*
* @return \Illuminate\Contracts\Filesystem\Filesystem
*/
public function createSftpDriver(array $config)
{
return $this->adapt($this->createFlysystem(new SftpAdapter($config), $config));
}
/**
* Create an instance of the Amazon S3 driver.
*
* @return \Illuminate\Contracts\Filesystem\Cloud
*/
public function createS3Driver(array $config)
{
$s3Config = $this->formatS3Config($config);
$root = $s3Config['root'] ?? null;
$options = $config['options'] ?? [];
$streamReads = $config['stream_reads'] ?? \false;
return $this->adapt($this->createFlysystem(new S3Adapter(new S3Client($s3Config), $s3Config['bucket'], $root, $options, $streamReads), $config));
}
/**
* Set the given disk instance.
*
* @param string $name
* @param mixed $disk
*
* @return $this
*/
public function set($name, $disk)
{
$this->disks[$name] = $disk;
return $this;
}
/**
* Get the default driver name.
*
* @return string
*/
public function getDefaultDriver()
{
return $this->app['config']['filesystems.default'];
}
/**
* Get the default cloud driver name.
*
* @return string
*/
public function getDefaultCloudDriver()
{
return $this->app['config']['filesystems.cloud'] ?? 's3';
}
/**
* Unset the given disk instances.
*
* @param array|string $disk
*
* @return $this
*/
public function forgetDisk($disk)
{
foreach ((array) $disk as $diskName) {
unset($this->disks[$diskName]);
}
return $this;
}
/**
* Disconnect the given disk and remove from local cache.
*
* @param null|string $name
*/
public function purge($name = null)
{
$name = $name ?? $this->getDefaultDriver();
unset($this->disks[$name]);
}
/**
* Register a custom driver creator Closure.
*
* @param string $driver
*
* @return $this
*/
public function extend($driver, \Closure $callback)
{
$this->customCreators[$driver] = $callback;
return $this;
}
/**
* Set the application instance used by the manager.
*
* @param \Illuminate\Contracts\Foundation\Application $app
*
* @return $this
*/
public function setApplication($app)
{
$this->app = $app;
return $this;
}
/**
* Attempt to get the disk from the local cache.
*
* @param string $name
*
* @return \Illuminate\Contracts\Filesystem\Filesystem
*/
protected function get($name)
{
return $this->disks[$name] ?? $this->resolve($name);
}
/**
* Resolve the given disk.
*
* @param string $name
* @param null|array $config
*
* @return \Illuminate\Contracts\Filesystem\Filesystem
*
* @throws \InvalidArgumentException
*/
protected function resolve($name, $config = null)
{
$config = $config ?? $this->getConfig($name);
if (empty($config['driver'])) {
throw new \InvalidArgumentException("Disk [{$name}] does not have a configured driver.");
}
$name = $config['driver'];
if (isset($this->customCreators[$name])) {
return $this->callCustomCreator($config);
}
$driverMethod = 'create'.\ucfirst($name).'Driver';
if (!\method_exists($this, $driverMethod)) {
throw new \InvalidArgumentException("Driver [{$name}] is not supported.");
}
return $this->{$driverMethod}($config);
}
/**
* Call a custom driver creator.
*
* @return \Illuminate\Contracts\Filesystem\Filesystem
*/
protected function callCustomCreator(array $config)
{
$driver = $this->customCreators[$config['driver']]($this->app, $config);
if ($driver instanceof FilesystemInterface) {
return $this->adapt($driver);
}
return $driver;
}
/**
* Format the given S3 configuration with the default options.
*
* @return array
*/
protected function formatS3Config(array $config)
{
$config += ['version' => 'latest'];
if (!empty($config['key']) && !empty($config['secret'])) {
$config['credentials'] = Arr::only($config, ['key', 'secret', 'token']);
}
return $config;
}
/**
* Create a Flysystem instance with the given adapter.
*
* @param \League\Flysystem\AdapterInterface $adapter
*
* @return \League\Flysystem\FilesystemInterface
*/
protected function createFlysystem(AdapterInterface $adapter, array $config)
{
$cache = Arr::pull($config, 'cache');
$config = Arr::only($config, ['visibility', 'disable_asserts', 'url', 'temporary_url']);
if ($cache) {
$adapter = new CachedAdapter($adapter, $this->createCacheStore($cache));
}
return new Flysystem($adapter, \count($config) > 0 ? $config : null);
}
/**
* Create a cache store instance.
*
* @param mixed $config
*
* @return \League\Flysystem\Cached\CacheInterface
*
* @throws \InvalidArgumentException
*/
protected function createCacheStore($config)
{
if (\true === $config) {
return new MemoryStore();
}
return new Cache($this->app['cache']->store($config['store']), $config['prefix'] ?? 'flysystem', $config['expire'] ?? null);
}
/**
* Adapt the filesystem implementation.
*
* @param \League\Flysystem\FilesystemInterface $filesystem
*
* @return \Illuminate\Contracts\Filesystem\Filesystem
*/
protected function adapt(FilesystemInterface $filesystem)
{
return new FilesystemAdapter($filesystem);
}
/**
* Get the filesystem connection configuration.
*
* @param string $name
*
* @return array
*/
protected function getConfig($name)
{
return $this->app['config']["filesystems.disks.{$name}"] ?: [];
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Filesystem;
use _JchOptimizeVendor\Illuminate\Support\ServiceProvider;
class FilesystemServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*/
public function register()
{
$this->registerNativeFilesystem();
$this->registerFlysystem();
}
/**
* Register the native filesystem implementation.
*/
protected function registerNativeFilesystem()
{
$this->app->singleton('files', function () {
return new Filesystem();
});
}
/**
* Register the driver based filesystem.
*/
protected function registerFlysystem()
{
$this->registerManager();
$this->app->singleton('filesystem.disk', function ($app) {
return $app['filesystem']->disk($this->getDefaultDriver());
});
$this->app->singleton('filesystem.cloud', function ($app) {
return $app['filesystem']->disk($this->getCloudDriver());
});
}
/**
* Register the filesystem manager.
*/
protected function registerManager()
{
$this->app->singleton('filesystem', function ($app) {
return new FilesystemManager($app);
});
}
/**
* Get the default file driver.
*
* @return string
*/
protected function getDefaultDriver()
{
return $this->app['config']['filesystems.default'];
}
/**
* Get the default cloud based file driver.
*
* @return string
*/
protected function getCloudDriver()
{
return $this->app['config']['filesystems.cloud'];
}
}

View File

@@ -0,0 +1,187 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Filesystem;
use _JchOptimizeVendor\Illuminate\Contracts\Filesystem\LockTimeoutException;
class LockableFile
{
/**
* The file resource.
*
* @var resource
*/
protected $handle;
/**
* The file path.
*
* @var string
*/
protected $path;
/**
* Indicates if the file is locked.
*
* @var bool
*/
protected $isLocked = \false;
/**
* Create a new File instance.
*
* @param string $path
* @param string $mode
*/
public function __construct($path, $mode)
{
$this->path = $path;
$this->ensureDirectoryExists($path);
$this->createResource($path, $mode);
}
/**
* Read the file contents.
*
* @param null|int $length
*
* @return string
*/
public function read($length = null)
{
\clearstatcache(\true, $this->path);
return \fread($this->handle, $length ?? ($this->size() ?: 1));
}
/**
* Get the file size.
*
* @return int
*/
public function size()
{
return \filesize($this->path);
}
/**
* Write to the file.
*
* @param string $contents
*
* @return string
*/
public function write($contents)
{
\fwrite($this->handle, $contents);
\fflush($this->handle);
return $this;
}
/**
* Truncate the file.
*
* @return $this
*/
public function truncate()
{
\rewind($this->handle);
\ftruncate($this->handle, 0);
return $this;
}
/**
* Get a shared lock on the file.
*
* @param bool $block
*
* @return $this
*
* @throws \Illuminate\Contracts\Filesystem\LockTimeoutException
*/
public function getSharedLock($block = \false)
{
if (!\flock($this->handle, \LOCK_SH | ($block ? 0 : \LOCK_NB))) {
throw new LockTimeoutException("Unable to acquire file lock at path [{$this->path}].");
}
$this->isLocked = \true;
return $this;
}
/**
* Get an exclusive lock on the file.
*
* @param bool $block
*
* @return bool
*
* @throws \Illuminate\Contracts\Filesystem\LockTimeoutException
*/
public function getExclusiveLock($block = \false)
{
if (!\flock($this->handle, \LOCK_EX | ($block ? 0 : \LOCK_NB))) {
throw new LockTimeoutException("Unable to acquire file lock at path [{$this->path}].");
}
$this->isLocked = \true;
return $this;
}
/**
* Release the lock on the file.
*
* @return $this
*/
public function releaseLock()
{
\flock($this->handle, \LOCK_UN);
$this->isLocked = \false;
return $this;
}
/**
* Close the file.
*
* @return bool
*/
public function close()
{
if ($this->isLocked) {
$this->releaseLock();
}
return \fclose($this->handle);
}
/**
* Create the file's directory if necessary.
*
* @param string $path
*/
protected function ensureDirectoryExists($path)
{
if (!\file_exists(\dirname($path))) {
@\mkdir(\dirname($path), 0777, \true);
}
}
/**
* Create the file resource.
*
* @param string $path
* @param string $mode
*
* @throws \Exception
*/
protected function createResource($path, $mode)
{
$this->handle = @\fopen($path, $mode);
if (!$this->handle) {
throw new \Exception('Unable to create lockable file: '.$path.'. Please ensure you have permission to create files in this location.');
}
}
}

View File

@@ -0,0 +1,109 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support\Traits;
trait Macroable
{
/**
* The registered string macros.
*
* @var array
*/
protected static $macros = [];
/**
* Dynamically handle calls to the class.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*
* @throws \BadMethodCallException
*/
public static function __callStatic($method, $parameters)
{
if (!static::hasMacro($method)) {
throw new \BadMethodCallException(\sprintf('Method %s::%s does not exist.', static::class, $method));
}
$macro = static::$macros[$method];
if ($macro instanceof \Closure) {
$macro = $macro->bindTo(null, static::class);
}
return $macro(...$parameters);
}
/**
* Dynamically handle calls to the class.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*
* @throws \BadMethodCallException
*/
public function __call($method, $parameters)
{
if (!static::hasMacro($method)) {
throw new \BadMethodCallException(\sprintf('Method %s::%s does not exist.', static::class, $method));
}
$macro = static::$macros[$method];
if ($macro instanceof \Closure) {
$macro = $macro->bindTo($this, static::class);
}
return $macro(...$parameters);
}
/**
* Register a custom macro.
*
* @param string $name
* @param callable|object $macro
*/
public static function macro($name, $macro)
{
static::$macros[$name] = $macro;
}
/**
* Mix another object into the class.
*
* @param object $mixin
* @param bool $replace
*
* @throws \ReflectionException
*/
public static function mixin($mixin, $replace = \true)
{
$methods = (new \ReflectionClass($mixin))->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED);
foreach ($methods as $method) {
if ($replace || !static::hasMacro($method->name)) {
$method->setAccessible(\true);
static::macro($method->name, $method->invoke($mixin));
}
}
}
/**
* Checks if macro is registered.
*
* @param string $name
*
* @return bool
*/
public static function hasMacro($name)
{
return isset(static::$macros[$name]);
}
/**
* Flush the existing macros.
*/
public static function flushMacros()
{
static::$macros = [];
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Pipeline;
use _JchOptimizeVendor\Illuminate\Contracts\Container\Container;
use _JchOptimizeVendor\Illuminate\Contracts\Pipeline\Hub as HubContract;
class Hub implements HubContract
{
/**
* The container implementation.
*
* @var null|\Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* All of the available pipelines.
*
* @var array
*/
protected $pipelines = [];
/**
* Create a new Hub instance.
*
* @param null|\Illuminate\Contracts\Container\Container $container
*/
public function __construct(Container $container = null)
{
$this->container = $container;
}
/**
* Define the default named pipeline.
*/
public function defaults(\Closure $callback)
{
return $this->pipeline('default', $callback);
}
/**
* Define a new named pipeline.
*
* @param string $name
*/
public function pipeline($name, \Closure $callback)
{
$this->pipelines[$name] = $callback;
}
/**
* Send an object through one of the available pipelines.
*
* @param mixed $object
* @param null|string $pipeline
*
* @return mixed
*/
public function pipe($object, $pipeline = null)
{
$pipeline = $pipeline ?: 'default';
return \call_user_func($this->pipelines[$pipeline], new Pipeline($this->container), $object);
}
/**
* Get the container instance used by the hub.
*
* @return \Illuminate\Contracts\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Set the container instance used by the hub.
*
* @param \Illuminate\Contracts\Container\Container $container
*
* @return $this
*/
public function setContainer(Container $container)
{
$this->container = $container;
return $this;
}
}

View File

@@ -0,0 +1,252 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Pipeline;
use _JchOptimizeVendor\Illuminate\Contracts\Container\Container;
use _JchOptimizeVendor\Illuminate\Contracts\Pipeline\Pipeline as PipelineContract;
use Closure;
class Pipeline implements PipelineContract
{
/**
* The container implementation.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* The object being passed through the pipeline.
*
* @var mixed
*/
protected $passable;
/**
* The array of class pipes.
*
* @var array
*/
protected $pipes = [];
/**
* The method to call on each pipe.
*
* @var string
*/
protected $method = 'handle';
/**
* Create a new class instance.
*
* @param null|\Illuminate\Contracts\Container\Container $container
*/
public function __construct(Container $container = null)
{
$this->container = $container;
}
/**
* Set the object being sent through the pipeline.
*
* @param mixed $passable
*
* @return $this
*/
public function send($passable)
{
$this->passable = $passable;
return $this;
}
/**
* Set the array of pipes.
*
* @param array|mixed $pipes
*
* @return $this
*/
public function through($pipes)
{
$this->pipes = \is_array($pipes) ? $pipes : \func_get_args();
return $this;
}
/**
* Set the method to call on the pipes.
*
* @param string $method
*
* @return $this
*/
public function via($method)
{
$this->method = $method;
return $this;
}
/**
* Run the pipeline with a final destination callback.
*
* @return mixed
*/
public function then(\Closure $destination)
{
$pipeline = \array_reduce(\array_reverse($this->pipes()), $this->carry(), $this->prepareDestination($destination));
return $pipeline($this->passable);
}
/**
* Run the pipeline and return the result.
*
* @return mixed
*/
public function thenReturn()
{
return $this->then(function ($passable) {
return $passable;
});
}
/**
* Set the container instance.
*
* @param \Illuminate\Contracts\Container\Container $container
*
* @return $this
*/
public function setContainer(Container $container)
{
$this->container = $container;
return $this;
}
/**
* Get the final piece of the Closure onion.
*
* @return \Closure
*/
protected function prepareDestination(\Closure $destination)
{
return function ($passable) use ($destination) {
try {
return $destination($passable);
} catch (\Throwable $e) {
return $this->handleException($passable, $e);
}
};
}
/**
* Get a Closure that represents a slice of the application onion.
*
* @return \Closure
*/
protected function carry()
{
return function ($stack, $pipe) {
return function ($passable) use ($stack, $pipe) {
try {
if (\is_callable($pipe)) {
// If the pipe is a callable, then we will call it directly, but otherwise we
// will resolve the pipes out of the dependency container and call it with
// the appropriate method and arguments, returning the results back out.
return $pipe($passable, $stack);
}
if (!\is_object($pipe)) {
[$name, $parameters] = $this->parsePipeString($pipe);
// If the pipe is a string we will parse the string and resolve the class out
// of the dependency injection container. We can then build a callable and
// execute the pipe function giving in the parameters that are required.
$pipe = $this->getContainer()->make($name);
$parameters = \array_merge([$passable, $stack], $parameters);
} else {
// If the pipe is already an object we'll just make a callable and pass it to
// the pipe as-is. There is no need to do any extra parsing and formatting
// since the object we're given was already a fully instantiated object.
$parameters = [$passable, $stack];
}
$carry = \method_exists($pipe, $this->method) ? $pipe->{$this->method}(...$parameters) : $pipe(...$parameters);
return $this->handleCarry($carry);
} catch (\Throwable $e) {
return $this->handleException($passable, $e);
}
};
};
}
/**
* Parse full pipe string to get name and parameters.
*
* @param string $pipe
*
* @return array
*/
protected function parsePipeString($pipe)
{
[$name, $parameters] = \array_pad(\explode(':', $pipe, 2), 2, []);
if (\is_string($parameters)) {
$parameters = \explode(',', $parameters);
}
return [$name, $parameters];
}
/**
* Get the array of configured pipes.
*
* @return array
*/
protected function pipes()
{
return $this->pipes;
}
/**
* Get the container instance.
*
* @return \Illuminate\Contracts\Container\Container
*
* @throws \RuntimeException
*/
protected function getContainer()
{
if (!$this->container) {
throw new \RuntimeException('A container instance has not been passed to the Pipeline.');
}
return $this->container;
}
/**
* Handle the value returned from each pipe before passing it to the next.
*
* @param mixed $carry
*
* @return mixed
*/
protected function handleCarry($carry)
{
return $carry;
}
/**
* Handle the given exception.
*
* @param mixed $passable
*
* @return mixed
*
* @throws \Throwable
*/
protected function handleException($passable, \Throwable $e)
{
throw $e;
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Pipeline;
use _JchOptimizeVendor\Illuminate\Contracts\Pipeline\Hub as PipelineHubContract;
use _JchOptimizeVendor\Illuminate\Contracts\Support\DeferrableProvider;
use _JchOptimizeVendor\Illuminate\Support\ServiceProvider;
class PipelineServiceProvider extends ServiceProvider implements DeferrableProvider
{
/**
* Register the service provider.
*/
public function register()
{
$this->app->singleton(PipelineHubContract::class, Hub::class);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [PipelineHubContract::class];
}
}

View File

@@ -0,0 +1,47 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
class AggregateServiceProvider extends ServiceProvider
{
/**
* The provider class names.
*
* @var array
*/
protected $providers = [];
/**
* An array of the service provider instances.
*
* @var array
*/
protected $instances = [];
/**
* Register the service provider.
*/
public function register()
{
$this->instances = [];
foreach ($this->providers as $provider) {
$this->instances[] = $this->app->register($provider);
}
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
$provides = [];
foreach ($this->providers as $provider) {
$instance = $this->app->resolveProvider($provider);
$provides = \array_merge($provides, $instance->provides());
}
return $provides;
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Carbon\Carbon as BaseCarbon;
use _JchOptimizeVendor\Carbon\CarbonImmutable as BaseCarbonImmutable;
class Carbon extends BaseCarbon
{
public static function setTestNow($testNow = null)
{
BaseCarbon::setTestNow($testNow);
BaseCarbonImmutable::setTestNow($testNow);
}
}

View File

@@ -0,0 +1,109 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Illuminate\Filesystem\Filesystem;
use _JchOptimizeVendor\Symfony\Component\Process\PhpExecutableFinder;
use _JchOptimizeVendor\Symfony\Component\Process\Process;
class Composer
{
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* The working path to regenerate from.
*
* @var null|string
*/
protected $workingPath;
/**
* Create a new Composer manager instance.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param null|string $workingPath
*/
public function __construct(Filesystem $files, $workingPath = null)
{
$this->files = $files;
$this->workingPath = $workingPath;
}
/**
* Regenerate the Composer autoloader files.
*
* @param array|string $extra
*
* @return int
*/
public function dumpAutoloads($extra = '')
{
$extra = $extra ? (array) $extra : [];
$command = \array_merge($this->findComposer(), ['dump-autoload'], $extra);
return $this->getProcess($command)->run();
}
/**
* Regenerate the optimized Composer autoloader files.
*
* @return int
*/
public function dumpOptimized()
{
return $this->dumpAutoloads('--optimize');
}
/**
* Set the working path used by the class.
*
* @param string $path
*
* @return $this
*/
public function setWorkingPath($path)
{
$this->workingPath = \realpath($path);
return $this;
}
/**
* Get the composer command for the environment.
*
* @return array
*/
protected function findComposer()
{
if ($this->files->exists($this->workingPath.'/composer.phar')) {
return [$this->phpBinary(), 'composer.phar'];
}
return ['composer'];
}
/**
* Get the PHP binary.
*
* @return string
*/
protected function phpBinary()
{
return ProcessUtils::escapeArgument((new PhpExecutableFinder())->find(\false));
}
/**
* Get a new Symfony process instance.
*
* @return \Symfony\Component\Process\Process
*/
protected function getProcess(array $command)
{
return (new Process($command, $this->workingPath))->setTimeout(null);
}
}

View File

@@ -0,0 +1,172 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
class ConfigurationUrlParser
{
/**
* The drivers aliases map.
*
* @var array
*/
protected static $driverAliases = [
'mssql' => 'sqlsrv',
'mysql2' => 'mysql',
// RDS
'postgres' => 'pgsql',
'postgresql' => 'pgsql',
'sqlite3' => 'sqlite',
'redis' => 'tcp',
'rediss' => 'tls',
];
/**
* Parse the database configuration, hydrating options using a database configuration URL if possible.
*
* @param array|string $config
*
* @return array
*/
public function parseConfiguration($config)
{
if (\is_string($config)) {
$config = ['url' => $config];
}
$url = Arr::pull($config, 'url');
if (!$url) {
return $config;
}
$rawComponents = $this->parseUrl($url);
$decodedComponents = $this->parseStringsToNativeTypes(\array_map('rawurldecode', $rawComponents));
return \array_merge($config, $this->getPrimaryOptions($decodedComponents), $this->getQueryOptions($rawComponents));
}
/**
* Get all of the current drivers' aliases.
*
* @return array
*/
public static function getDriverAliases()
{
return static::$driverAliases;
}
/**
* Add the given driver alias to the driver aliases array.
*
* @param string $alias
* @param string $driver
*/
public static function addDriverAlias($alias, $driver)
{
static::$driverAliases[$alias] = $driver;
}
/**
* Get the primary database connection options.
*
* @param array $url
*
* @return array
*/
protected function getPrimaryOptions($url)
{
return \array_filter(['driver' => $this->getDriver($url), 'database' => $this->getDatabase($url), 'host' => $url['host'] ?? null, 'port' => $url['port'] ?? null, 'username' => $url['user'] ?? null, 'password' => $url['pass'] ?? null], function ($value) {
return !\is_null($value);
});
}
/**
* Get the database driver from the URL.
*
* @param array $url
*
* @return null|string
*/
protected function getDriver($url)
{
$alias = $url['scheme'] ?? null;
if (!$alias) {
return;
}
return static::$driverAliases[$alias] ?? $alias;
}
/**
* Get the database name from the URL.
*
* @param array $url
*
* @return null|string
*/
protected function getDatabase($url)
{
$path = $url['path'] ?? null;
return $path && '/' !== $path ? \substr($path, 1) : null;
}
/**
* Get all of the additional database options from the query string.
*
* @param array $url
*
* @return array
*/
protected function getQueryOptions($url)
{
$queryString = $url['query'] ?? null;
if (!$queryString) {
return [];
}
$query = [];
\parse_str($queryString, $query);
return $this->parseStringsToNativeTypes($query);
}
/**
* Parse the string URL to an array of components.
*
* @param string $url
*
* @return array
*
* @throws \InvalidArgumentException
*/
protected function parseUrl($url)
{
$url = \preg_replace('#^(sqlite3?):///#', '$1://null/', $url);
$parsedUrl = \parse_url($url);
if (\false === $parsedUrl) {
throw new \InvalidArgumentException('The database configuration URL is malformed.');
}
return $parsedUrl;
}
/**
* Convert string casted values to their native types.
*
* @param mixed $value
*
* @return mixed
*/
protected function parseStringsToNativeTypes($value)
{
if (\is_array($value)) {
return \array_map([$this, 'parseStringsToNativeTypes'], $value);
}
if (!\is_string($value)) {
return $value;
}
$parsedValue = \json_decode($value, \true);
if (\JSON_ERROR_NONE === \json_last_error()) {
return $parsedValue;
}
return $value;
}
}

View File

@@ -0,0 +1,216 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Carbon\Factory;
/**
* @see https://carbon.nesbot.com/docs/
* @see https://github.com/briannesbitt/Carbon/blob/master/src/Carbon/Factory.php
*
* @method static Carbon create($year = 0, $month = 1, $day = 1, $hour = 0, $minute = 0, $second = 0, $tz = null)
* @method static Carbon createFromDate($year = null, $month = null, $day = null, $tz = null)
* @method static Carbon|false createFromFormat($format, $time, $tz = null)
* @method static Carbon createFromTime($hour = 0, $minute = 0, $second = 0, $tz = null)
* @method static Carbon createFromTimeString($time, $tz = null)
* @method static Carbon createFromTimestamp($timestamp, $tz = null)
* @method static Carbon createFromTimestampMs($timestamp, $tz = null)
* @method static Carbon createFromTimestampUTC($timestamp)
* @method static Carbon createMidnightDate($year = null, $month = null, $day = null, $tz = null)
* @method static Carbon|false createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null)
* @method static Carbon disableHumanDiffOption($humanDiffOption)
* @method static Carbon enableHumanDiffOption($humanDiffOption)
* @method static mixed executeWithLocale($locale, $func)
* @method static Carbon fromSerialized($value)
* @method static array getAvailableLocales()
* @method static array getDays()
* @method static int getHumanDiffOptions()
* @method static array getIsoUnits()
* @method static Carbon getLastErrors()
* @method static string getLocale()
* @method static int getMidDayAt()
* @method static Carbon getTestNow()
* @method static \Symfony\Component\Translation\TranslatorInterface getTranslator()
* @method static int getWeekEndsAt()
* @method static int getWeekStartsAt()
* @method static array getWeekendDays()
* @method static bool hasFormat($date, $format)
* @method static bool hasMacro($name)
* @method static bool hasRelativeKeywords($time)
* @method static bool hasTestNow()
* @method static Carbon instance($date)
* @method static bool isImmutable()
* @method static bool isModifiableUnit($unit)
* @method static Carbon isMutable()
* @method static bool isStrictModeEnabled()
* @method static bool localeHasDiffOneDayWords($locale)
* @method static bool localeHasDiffSyntax($locale)
* @method static bool localeHasDiffTwoDayWords($locale)
* @method static bool localeHasPeriodSyntax($locale)
* @method static bool localeHasShortUnits($locale)
* @method static void macro($name, $macro)
* @method static Carbon|null make($var)
* @method static Carbon maxValue()
* @method static Carbon minValue()
* @method static void mixin($mixin)
* @method static Carbon now($tz = null)
* @method static Carbon parse($time = null, $tz = null)
* @method static string pluralUnit(string $unit)
* @method static void resetMonthsOverflow()
* @method static void resetToStringFormat()
* @method static void resetYearsOverflow()
* @method static void serializeUsing($callback)
* @method static Carbon setHumanDiffOptions($humanDiffOptions)
* @method static bool setLocale($locale)
* @method static void setMidDayAt($hour)
* @method static void setTestNow($testNow = null)
* @method static void setToStringFormat($format)
* @method static void setTranslator(\Symfony\Component\Translation\TranslatorInterface $translator)
* @method static Carbon setUtf8($utf8)
* @method static void setWeekEndsAt($day)
* @method static void setWeekStartsAt($day)
* @method static void setWeekendDays($days)
* @method static bool shouldOverflowMonths()
* @method static bool shouldOverflowYears()
* @method static string singularUnit(string $unit)
* @method static Carbon today($tz = null)
* @method static Carbon tomorrow($tz = null)
* @method static void useMonthsOverflow($monthsOverflow = true)
* @method static Carbon useStrictMode($strictModeEnabled = true)
* @method static void useYearsOverflow($yearsOverflow = true)
* @method static Carbon yesterday($tz = null)
*/
class DateFactory
{
/**
* The default class that will be used for all created dates.
*
* @var string
*/
public const DEFAULT_CLASS_NAME = Carbon::class;
/**
* The type (class) of dates that should be created.
*
* @var string
*/
protected static $dateClass;
/**
* This callable may be used to intercept date creation.
*
* @var callable
*/
protected static $callable;
/**
* The Carbon factory that should be used when creating dates.
*
* @var object
*/
protected static $factory;
/**
* Handle dynamic calls to generate dates.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*
* @throws \RuntimeException
*/
public function __call($method, $parameters)
{
$defaultClassName = static::DEFAULT_CLASS_NAME;
// Using callable to generate dates...
if (static::$callable) {
return \call_user_func(static::$callable, $defaultClassName::$method(...$parameters));
}
// Using Carbon factory to generate dates...
if (static::$factory) {
return static::$factory->{$method}(...$parameters);
}
$dateClass = static::$dateClass ?: $defaultClassName;
// Check if date can be created using public class method...
if (\method_exists($dateClass, $method) || \method_exists($dateClass, 'hasMacro') && $dateClass::hasMacro($method)) {
return $dateClass::$method(...$parameters);
}
// If that fails, create the date with the default class...
$date = $defaultClassName::$method(...$parameters);
// If the configured class has an "instance" method, we'll try to pass our date into there...
if (\method_exists($dateClass, 'instance')) {
return $dateClass::instance($date);
}
// Otherwise, assume the configured class has a DateTime compatible constructor...
return new $dateClass($date->format('Y-m-d H:i:s.u'), $date->getTimezone());
}
/**
* Use the given handler when generating dates (class name, callable, or factory).
*
* @param mixed $handler
*
* @return mixed
*
* @throws \InvalidArgumentException
*/
public static function use($handler)
{
if (\is_callable($handler) && \is_object($handler)) {
return static::useCallable($handler);
}
if (\is_string($handler)) {
return static::useClass($handler);
}
if ($handler instanceof Factory) {
return static::useFactory($handler);
}
throw new \InvalidArgumentException('Invalid date creation handler. Please provide a class name, callable, or Carbon factory.');
}
/**
* Use the default date class when generating dates.
*/
public static function useDefault()
{
static::$dateClass = null;
static::$callable = null;
static::$factory = null;
}
/**
* Execute the given callable on each date creation.
*/
public static function useCallable(callable $callable)
{
static::$callable = $callable;
static::$dateClass = null;
static::$factory = null;
}
/**
* Use the given date type (class) when generating dates.
*
* @param string $dateClass
*/
public static function useClass($dateClass)
{
static::$dateClass = $dateClass;
static::$factory = null;
static::$callable = null;
}
/**
* Use the given Carbon factory when generating dates.
*
* @param object $factory
*/
public static function useFactory($factory)
{
static::$factory = $factory;
static::$dateClass = null;
static::$callable = null;
}
}

View File

@@ -0,0 +1,98 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Dotenv\Repository\Adapter\PutenvAdapter;
use _JchOptimizeVendor\Dotenv\Repository\RepositoryBuilder;
use _JchOptimizeVendor\PhpOption\Option;
class Env
{
/**
* Indicates if the putenv adapter is enabled.
*
* @var bool
*/
protected static $putenv = \true;
/**
* The environment repository instance.
*
* @var null|\Dotenv\Repository\RepositoryInterface
*/
protected static $repository;
/**
* Enable the putenv adapter.
*/
public static function enablePutenv()
{
static::$putenv = \true;
static::$repository = null;
}
/**
* Disable the putenv adapter.
*/
public static function disablePutenv()
{
static::$putenv = \false;
static::$repository = null;
}
/**
* Get the environment repository instance.
*
* @return \Dotenv\Repository\RepositoryInterface
*/
public static function getRepository()
{
if (null === static::$repository) {
$builder = RepositoryBuilder::createWithDefaultAdapters();
if (static::$putenv) {
$builder = $builder->addAdapter(PutenvAdapter::class);
}
static::$repository = $builder->immutable()->make();
}
return static::$repository;
}
/**
* Gets the value of an environment variable.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public static function get($key, $default = null)
{
return Option::fromValue(static::getRepository()->get($key))->map(function ($value) {
switch (\strtolower($value)) {
case 'true':
case '(true)':
return \true;
case 'false':
case '(false)':
return \false;
case 'empty':
case '(empty)':
return '';
case 'null':
case '(null)':
return;
}
if (\preg_match('/\\A([\'"])(.*)\\1\\z/', $value, $matches)) {
return $matches[2];
}
return $value;
})->getOrCall(function () use ($default) {
return value($default);
});
}
}

View File

@@ -0,0 +1,197 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Arrayable;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Jsonable;
class Fluent implements Arrayable, \ArrayAccess, Jsonable, \JsonSerializable
{
/**
* All of the attributes set on the fluent instance.
*
* @var array
*/
protected $attributes = [];
/**
* Create a new fluent instance.
*
* @param array|object $attributes
*/
public function __construct($attributes = [])
{
foreach ($attributes as $key => $value) {
$this->attributes[$key] = $value;
}
}
/**
* Handle dynamic calls to the fluent instance to set attributes.
*
* @param string $method
* @param array $parameters
*
* @return $this
*/
public function __call($method, $parameters)
{
$this->attributes[$method] = \count($parameters) > 0 ? $parameters[0] : \true;
return $this;
}
/**
* Dynamically retrieve the value of an attribute.
*
* @param string $key
*
* @return mixed
*/
public function __get($key)
{
return $this->get($key);
}
/**
* Dynamically set the value of an attribute.
*
* @param string $key
* @param mixed $value
*/
public function __set($key, $value)
{
$this->offsetSet($key, $value);
}
/**
* Dynamically check if an attribute is set.
*
* @param string $key
*
* @return bool
*/
public function __isset($key)
{
return $this->offsetExists($key);
}
/**
* Dynamically unset an attribute.
*
* @param string $key
*/
public function __unset($key)
{
$this->offsetUnset($key);
}
/**
* Get an attribute from the fluent instance.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
public function get($key, $default = null)
{
if (\array_key_exists($key, $this->attributes)) {
return $this->attributes[$key];
}
return value($default);
}
/**
* Get the attributes from the fluent instance.
*
* @return array
*/
public function getAttributes()
{
return $this->attributes;
}
/**
* Convert the fluent instance to an array.
*
* @return array
*/
public function toArray()
{
return $this->attributes;
}
/**
* Convert the object into something JSON serializable.
*
* @return array
*/
#[\ReturnTypeWillChange]
public function jsonSerialize()
{
return $this->toArray();
}
/**
* Convert the fluent instance to JSON.
*
* @param int $options
*
* @return string
*/
public function toJson($options = 0)
{
return \json_encode($this->jsonSerialize(), $options);
}
/**
* Determine if the given offset exists.
*
* @param string $offset
*
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists($offset)
{
return isset($this->attributes[$offset]);
}
/**
* Get the value for a given offset.
*
* @param string $offset
*
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($offset)
{
return $this->get($offset);
}
/**
* Set the value at the given offset.
*
* @param string $offset
* @param mixed $value
*/
#[\ReturnTypeWillChange]
public function offsetSet($offset, $value)
{
$this->attributes[$offset] = $value;
}
/**
* Unset the value at the given offset.
*
* @param string $offset
*/
#[\ReturnTypeWillChange]
public function offsetUnset($offset)
{
unset($this->attributes[$offset]);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
class HigherOrderTapProxy
{
/**
* The target being tapped.
*
* @var mixed
*/
public $target;
/**
* Create a new tap proxy instance.
*
* @param mixed $target
*/
public function __construct($target)
{
$this->target = $target;
}
/**
* Dynamically pass method calls to the target.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
$this->target->{$method}(...$parameters);
return $this->target;
}
}

View File

@@ -0,0 +1,65 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Htmlable;
class HtmlString implements Htmlable
{
/**
* The HTML string.
*
* @var string
*/
protected $html;
/**
* Create a new HTML string instance.
*
* @param string $html
*/
public function __construct($html = '')
{
$this->html = $html;
}
/**
* Get the HTML string.
*
* @return string
*/
public function __toString()
{
return $this->toHtml();
}
/**
* Get the HTML string.
*
* @return string
*/
public function toHtml()
{
return $this->html;
}
/**
* Determine if the given HTML string is empty.
*
* @return bool
*/
public function isEmpty()
{
return '' === $this->html;
}
/**
* Determine if the given HTML string is not empty.
*
* @return bool
*/
public function isNotEmpty()
{
return !$this->isEmpty();
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
trait InteractsWithTime
{
/**
* Get the number of seconds until the given DateTime.
*
* @param \DateInterval|\DateTimeInterface|int $delay
*
* @return int
*/
protected function secondsUntil($delay)
{
$delay = $this->parseDateInterval($delay);
return $delay instanceof \DateTimeInterface ? \max(0, $delay->getTimestamp() - $this->currentTime()) : (int) $delay;
}
/**
* Get the "available at" UNIX timestamp.
*
* @param \DateInterval|\DateTimeInterface|int $delay
*
* @return int
*/
protected function availableAt($delay = 0)
{
$delay = $this->parseDateInterval($delay);
return $delay instanceof \DateTimeInterface ? $delay->getTimestamp() : Carbon::now()->addRealSeconds($delay)->getTimestamp();
}
/**
* If the given value is an interval, convert it to a DateTime instance.
*
* @param \DateInterval|\DateTimeInterface|int $delay
*
* @return \DateTimeInterface|int
*/
protected function parseDateInterval($delay)
{
if ($delay instanceof \DateInterval) {
$delay = Carbon::now()->add($delay);
}
return $delay;
}
/**
* Get the current system time as a UNIX timestamp.
*
* @return int
*/
protected function currentTime()
{
return Carbon::now()->getTimestamp();
}
}

View File

@@ -0,0 +1,143 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Arrayable;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Htmlable;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Jsonable;
class Js implements Htmlable
{
/**
* Flags that should be used when encoding to JSON.
*
* @var int
*/
protected const REQUIRED_FLAGS = \JSON_HEX_TAG | \JSON_HEX_APOS | \JSON_HEX_AMP | \JSON_HEX_QUOT | \JSON_THROW_ON_ERROR;
/**
* The JavaScript string.
*
* @var string
*/
protected $js;
/**
* Create a new class instance.
*
* @param mixed $data
* @param null|int $flags
* @param int $depth
*
* @throws \JsonException
*/
public function __construct($data, $flags = 0, $depth = 512)
{
$this->js = $this->convertDataToJavaScriptExpression($data, $flags, $depth);
}
/**
* Get the string representation of the data for use in HTML.
*
* @return string
*/
public function __toString()
{
return $this->toHtml();
}
/**
* Create a new JavaScript string from the given data.
*
* @param mixed $data
* @param int $flags
* @param int $depth
*
* @return static
*
* @throws \JsonException
*/
public static function from($data, $flags = 0, $depth = 512)
{
return new static($data, $flags, $depth);
}
/**
* Get the string representation of the data for use in HTML.
*
* @return string
*/
public function toHtml()
{
return $this->js;
}
/**
* Convert the given data to a JavaScript expression.
*
* @param mixed $data
* @param int $flags
* @param int $depth
*
* @return string
*
* @throws \JsonException
*/
protected function convertDataToJavaScriptExpression($data, $flags = 0, $depth = 512)
{
if ($data instanceof self) {
return $data->toHtml();
}
$json = $this->jsonEncode($data, $flags, $depth);
if (\is_string($data)) {
return "'".\substr($json, 1, -1)."'";
}
return $this->convertJsonToJavaScriptExpression($json, $flags);
}
/**
* Encode the given data as JSON.
*
* @param mixed $data
* @param int $flags
* @param int $depth
*
* @return string
*
* @throws \JsonException
*/
protected function jsonEncode($data, $flags = 0, $depth = 512)
{
if ($data instanceof Jsonable) {
return $data->toJson($flags | static::REQUIRED_FLAGS);
}
if ($data instanceof Arrayable && !$data instanceof \JsonSerializable) {
$data = $data->toArray();
}
return \json_encode($data, $flags | static::REQUIRED_FLAGS, $depth);
}
/**
* Convert the given JSON to a JavaScript expression.
*
* @param string $json
* @param int $flags
*
* @return string
*
* @throws \JsonException
*/
protected function convertJsonToJavaScriptExpression($json, $flags = 0)
{
if ('[]' === $json || '{}' === $json) {
return $json;
}
if (Str::startsWith($json, ['"', '{', '['])) {
return "JSON.parse('".\substr(\json_encode($json, $flags | static::REQUIRED_FLAGS), 1, -1)."')";
}
return $json;
}
}

View File

@@ -0,0 +1,190 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Illuminate\Contracts\Container\Container;
use Closure;
abstract class Manager
{
/**
* The container instance.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* The configuration repository instance.
*
* @var \Illuminate\Contracts\Config\Repository
*/
protected $config;
/**
* The registered custom driver creators.
*
* @var array
*/
protected $customCreators = [];
/**
* The array of created "drivers".
*
* @var array
*/
protected $drivers = [];
/**
* Create a new manager instance.
*
* @param \Illuminate\Contracts\Container\Container $container
*/
public function __construct(Container $container)
{
$this->container = $container;
$this->config = $container->make('config');
}
/**
* Dynamically call the default driver instance.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->driver()->{$method}(...$parameters);
}
/**
* Get the default driver name.
*
* @return string
*/
abstract public function getDefaultDriver();
/**
* Get a driver instance.
*
* @param null|string $driver
*
* @return mixed
*
* @throws \InvalidArgumentException
*/
public function driver($driver = null)
{
$driver = $driver ?: $this->getDefaultDriver();
if (\is_null($driver)) {
throw new \InvalidArgumentException(\sprintf('Unable to resolve NULL driver for [%s].', static::class));
}
// If the given driver has not been created before, we will create the instances
// here and cache it so we can return it next time very quickly. If there is
// already a driver created by this name, we'll just return that instance.
if (!isset($this->drivers[$driver])) {
$this->drivers[$driver] = $this->createDriver($driver);
}
return $this->drivers[$driver];
}
/**
* Register a custom driver creator Closure.
*
* @param string $driver
*
* @return $this
*/
public function extend($driver, \Closure $callback)
{
$this->customCreators[$driver] = $callback;
return $this;
}
/**
* Get all of the created "drivers".
*
* @return array
*/
public function getDrivers()
{
return $this->drivers;
}
/**
* Get the container instance used by the manager.
*
* @return \Illuminate\Contracts\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Set the container instance used by the manager.
*
* @param \Illuminate\Contracts\Container\Container $container
*
* @return $this
*/
public function setContainer(Container $container)
{
$this->container = $container;
return $this;
}
/**
* Forget all of the resolved driver instances.
*
* @return $this
*/
public function forgetDrivers()
{
$this->drivers = [];
return $this;
}
/**
* Create a new driver instance.
*
* @param string $driver
*
* @return mixed
*
* @throws \InvalidArgumentException
*/
protected function createDriver($driver)
{
// First, we will determine if a custom driver creator exists for the given driver and
// if it does not we will check for a creator method for the driver. Custom creator
// callbacks allow developers to build their own "drivers" easily using Closures.
if (isset($this->customCreators[$driver])) {
return $this->callCustomCreator($driver);
}
$method = 'create'.Str::studly($driver).'Driver';
if (\method_exists($this, $method)) {
return $this->{$method}();
}
throw new \InvalidArgumentException("Driver [{$driver}] not supported.");
}
/**
* Call a custom driver creator.
*
* @param string $driver
*
* @return mixed
*/
protected function callCustomCreator($driver)
{
return $this->customCreators[$driver]($this->container);
}
}

View File

@@ -0,0 +1,413 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Arrayable;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Jsonable;
use _JchOptimizeVendor\Illuminate\Contracts\Support\MessageBag as MessageBagContract;
use _JchOptimizeVendor\Illuminate\Contracts\Support\MessageProvider;
use function _JchOptimizeVendor\collect;
class MessageBag implements Jsonable, \JsonSerializable, MessageBagContract, MessageProvider
{
/**
* All of the registered messages.
*
* @var array
*/
protected $messages = [];
/**
* Default format for message output.
*
* @var string
*/
protected $format = ':message';
/**
* Create a new message bag instance.
*/
public function __construct(array $messages = [])
{
foreach ($messages as $key => $value) {
$value = $value instanceof Arrayable ? $value->toArray() : (array) $value;
$this->messages[$key] = \array_unique($value);
}
}
/**
* Convert the message bag to its string representation.
*
* @return string
*/
public function __toString()
{
return $this->toJson();
}
/**
* Get the keys present in the message bag.
*
* @return array
*/
public function keys()
{
return \array_keys($this->messages);
}
/**
* Add a message to the message bag.
*
* @param string $key
* @param string $message
*
* @return $this
*/
public function add($key, $message)
{
if ($this->isUnique($key, $message)) {
$this->messages[$key][] = $message;
}
return $this;
}
/**
* Add a message to the message bag if the given conditional is "true".
*
* @param bool $boolean
* @param string $key
* @param string $message
*
* @return $this
*/
public function addIf($boolean, $key, $message)
{
return $boolean ? $this->add($key, $message) : $this;
}
/**
* Merge a new array of messages into the message bag.
*
* @param array|\Illuminate\Contracts\Support\MessageProvider $messages
*
* @return $this
*/
public function merge($messages)
{
if ($messages instanceof MessageProvider) {
$messages = $messages->getMessageBag()->getMessages();
}
$this->messages = \array_merge_recursive($this->messages, $messages);
return $this;
}
/**
* Determine if messages exist for all of the given keys.
*
* @param null|array|string $key
*
* @return bool
*/
public function has($key)
{
if ($this->isEmpty()) {
return \false;
}
if (\is_null($key)) {
return $this->any();
}
$keys = \is_array($key) ? $key : \func_get_args();
foreach ($keys as $key) {
if ('' === $this->first($key)) {
return \false;
}
}
return \true;
}
/**
* Determine if messages exist for any of the given keys.
*
* @param array|string $keys
*
* @return bool
*/
public function hasAny($keys = [])
{
if ($this->isEmpty()) {
return \false;
}
$keys = \is_array($keys) ? $keys : \func_get_args();
foreach ($keys as $key) {
if ($this->has($key)) {
return \true;
}
}
return \false;
}
/**
* Get the first message from the message bag for a given key.
*
* @param null|string $key
* @param null|string $format
*
* @return string
*/
public function first($key = null, $format = null)
{
$messages = \is_null($key) ? $this->all($format) : $this->get($key, $format);
$firstMessage = Arr::first($messages, null, '');
return \is_array($firstMessage) ? Arr::first($firstMessage) : $firstMessage;
}
/**
* Get all of the messages from the message bag for a given key.
*
* @param string $key
* @param null|string $format
*
* @return array
*/
public function get($key, $format = null)
{
// If the message exists in the message bag, we will transform it and return
// the message. Otherwise, we will check if the key is implicit & collect
// all the messages that match the given key and output it as an array.
if (\array_key_exists($key, $this->messages)) {
return $this->transform($this->messages[$key], $this->checkFormat($format), $key);
}
if (Str::contains($key, '*')) {
return $this->getMessagesForWildcardKey($key, $format);
}
return [];
}
/**
* Get all of the messages for every key in the message bag.
*
* @param null|string $format
*
* @return array
*/
public function all($format = null)
{
$format = $this->checkFormat($format);
$all = [];
foreach ($this->messages as $key => $messages) {
$all = \array_merge($all, $this->transform($messages, $format, $key));
}
return $all;
}
/**
* Get all of the unique messages for every key in the message bag.
*
* @param null|string $format
*
* @return array
*/
public function unique($format = null)
{
return \array_unique($this->all($format));
}
/**
* Get the raw messages in the message bag.
*
* @return array
*/
public function messages()
{
return $this->messages;
}
/**
* Get the raw messages in the message bag.
*
* @return array
*/
public function getMessages()
{
return $this->messages();
}
/**
* Get the messages for the instance.
*
* @return \Illuminate\Support\MessageBag
*/
public function getMessageBag()
{
return $this;
}
/**
* Get the default message format.
*
* @return string
*/
public function getFormat()
{
return $this->format;
}
/**
* Set the default message format.
*
* @param string $format
*
* @return \Illuminate\Support\MessageBag
*/
public function setFormat($format = ':message')
{
$this->format = $format;
return $this;
}
/**
* Determine if the message bag has any messages.
*
* @return bool
*/
public function isEmpty()
{
return !$this->any();
}
/**
* Determine if the message bag has any messages.
*
* @return bool
*/
public function isNotEmpty()
{
return $this->any();
}
/**
* Determine if the message bag has any messages.
*
* @return bool
*/
public function any()
{
return $this->count() > 0;
}
/**
* Get the number of messages in the message bag.
*
* @return int
*/
#[\ReturnTypeWillChange]
public function count()
{
return \count($this->messages, \COUNT_RECURSIVE) - \count($this->messages);
}
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray()
{
return $this->getMessages();
}
/**
* 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);
}
/**
* Determine if a key and message combination already exists.
*
* @param string $key
* @param string $message
*
* @return bool
*/
protected function isUnique($key, $message)
{
$messages = (array) $this->messages;
return !isset($messages[$key]) || !\in_array($message, $messages[$key]);
}
/**
* Get the messages for a wildcard key.
*
* @param string $key
* @param null|string $format
*
* @return array
*/
protected function getMessagesForWildcardKey($key, $format)
{
return collect($this->messages)->filter(function ($messages, $messageKey) use ($key) {
return Str::is($key, $messageKey);
})->map(function ($messages, $messageKey) use ($format) {
return $this->transform($messages, $this->checkFormat($format), $messageKey);
})->all();
}
/**
* Format an array of messages.
*
* @param array $messages
* @param string $format
* @param string $messageKey
*
* @return array
*/
protected function transform($messages, $format, $messageKey)
{
return collect((array) $messages)->map(function ($message) use ($format, $messageKey) {
// We will simply spin through the given messages and transform each one
// replacing the :message place holder with the real message allowing
// the messages to be easily formatted to each developer's desires.
return \str_replace([':message', ':key'], [$message, $messageKey], $format);
})->all();
}
/**
* Get the appropriate format based on the given format.
*
* @param string $format
*
* @return string
*/
protected function checkFormat($format)
{
return $format ?: $this->format;
}
}

View File

@@ -0,0 +1,184 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use Closure;
abstract class MultipleInstanceManager
{
/**
* The application instance.
*
* @var \Illuminate\Contracts\Foundation\Application
*/
protected $app;
/**
* The array of resolved instances.
*
* @var array
*/
protected $instances = [];
/**
* The registered custom instance creators.
*
* @var array
*/
protected $customCreators = [];
/**
* Create a new manager instance.
*
* @param \Illuminate\Contracts\Foundation\Application $app
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* Dynamically call the default instance.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->instance()->{$method}(...$parameters);
}
/**
* Get the default instance name.
*
* @return string
*/
abstract public function getDefaultInstance();
/**
* Set the default instance name.
*
* @param string $name
*/
abstract public function setDefaultInstance($name);
/**
* Get the instance specific configuration.
*
* @param string $name
*
* @return array
*/
abstract public function getInstanceConfig($name);
/**
* Get an instance instance by name.
*
* @param null|string $name
*
* @return mixed
*/
public function instance($name = null)
{
$name = $name ?: $this->getDefaultInstance();
return $this->instances[$name] = $this->get($name);
}
/**
* Unset the given instances.
*
* @param null|array|string $name
*
* @return $this
*/
public function forgetInstance($name = null)
{
$name = $name ?? $this->getDefaultInstance();
foreach ((array) $name as $instanceName) {
if (isset($this->instances[$instanceName])) {
unset($this->instances[$instanceName]);
}
}
return $this;
}
/**
* Disconnect the given instance and remove from local cache.
*
* @param null|string $name
*/
public function purge($name = null)
{
$name = $name ?? $this->getDefaultInstance();
unset($this->instances[$name]);
}
/**
* Register a custom instance creator Closure.
*
* @param string $name
*
* @return $this
*/
public function extend($name, \Closure $callback)
{
$this->customCreators[$name] = $callback->bindTo($this, $this);
return $this;
}
/**
* Attempt to get an instance from the local cache.
*
* @param string $name
*
* @return mixed
*/
protected function get($name)
{
return $this->instances[$name] ?? $this->resolve($name);
}
/**
* Resolve the given instance.
*
* @param string $name
*
* @return mixed
*
* @throws \InvalidArgumentException
*/
protected function resolve($name)
{
$config = $this->getInstanceConfig($name);
if (\is_null($config)) {
throw new \InvalidArgumentException("Instance [{$name}] is not defined.");
}
if (!\array_key_exists('driver', $config)) {
throw new \RuntimeException("Instance [{$name}] does not specify a driver.");
}
if (isset($this->customCreators[$config['driver']])) {
return $this->callCustomCreator($config);
}
$driverMethod = 'create'.\ucfirst($config['driver']).'Driver';
if (\method_exists($this, $driverMethod)) {
return $this->{$driverMethod}($config);
}
throw new \InvalidArgumentException("Instance driver [{$config['driver']}] is not supported.");
}
/**
* Call a custom instance creator.
*
* @return mixed
*/
protected function callCustomCreator(array $config)
{
return $this->customCreators[$config['driver']]($this->app, $config);
}
}

View File

@@ -0,0 +1,100 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
class NamespacedItemResolver
{
/**
* A cache of the parsed items.
*
* @var array
*/
protected $parsed = [];
/**
* Parse a key into namespace, group, and item.
*
* @param string $key
*
* @return array
*/
public function parseKey($key)
{
// If we've already parsed the given key, we'll return the cached version we
// already have, as this will save us some processing. We cache off every
// key we parse so we can quickly return it on all subsequent requests.
if (isset($this->parsed[$key])) {
return $this->parsed[$key];
}
// If the key does not contain a double colon, it means the key is not in a
// namespace, and is just a regular configuration item. Namespaces are a
// tool for organizing configuration items for things such as modules.
if (\false === \strpos($key, '::')) {
$segments = \explode('.', $key);
$parsed = $this->parseBasicSegments($segments);
} else {
$parsed = $this->parseNamespacedSegments($key);
}
// Once we have the parsed array of this key's elements, such as its groups
// and namespace, we will cache each array inside a simple list that has
// the key and the parsed array for quick look-ups for later requests.
return $this->parsed[$key] = $parsed;
}
/**
* Set the parsed value of a key.
*
* @param string $key
* @param array $parsed
*/
public function setParsedKey($key, $parsed)
{
$this->parsed[$key] = $parsed;
}
/**
* Flush the cache of parsed keys.
*/
public function flushParsedKeys()
{
$this->parsed = [];
}
/**
* Parse an array of basic segments.
*
* @return array
*/
protected function parseBasicSegments(array $segments)
{
// The first segment in a basic array will always be the group, so we can go
// ahead and grab that segment. If there is only one total segment we are
// just pulling an entire group out of the array and not a single item.
$group = $segments[0];
// If there is more than one segment in this group, it means we are pulling
// a specific item out of a group and will need to return this item name
// as well as the group so we know which item to pull from the arrays.
$item = 1 === \count($segments) ? null : \implode('.', \array_slice($segments, 1));
return [null, $group, $item];
}
/**
* Parse an array of namespaced segments.
*
* @param string $key
*
* @return array
*/
protected function parseNamespacedSegments($key)
{
[$namespace, $item] = \explode('::', $key);
// First we'll just explode the first segment to get the namespace and group
// since the item should be in the remaining segments. Once we have these
// two pieces of data we can proceed with parsing out the item's value.
$itemSegments = \explode('.', $item);
$groupAndItem = \array_slice($this->parseBasicSegments($itemSegments), 1);
return \array_merge([$namespace], $groupAndItem);
}
}

View File

@@ -0,0 +1,133 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Illuminate\Support\Traits\Macroable;
class Optional implements \ArrayAccess
{
use Macroable {
__call as macroCall;
}
/**
* The underlying object.
*
* @var mixed
*/
protected $value;
/**
* Create a new optional instance.
*
* @param mixed $value
*/
public function __construct($value)
{
$this->value = $value;
}
/**
* Dynamically access a property on the underlying object.
*
* @param string $key
*
* @return mixed
*/
public function __get($key)
{
if (\is_object($this->value)) {
return $this->value->{$key} ?? null;
}
}
/**
* Dynamically check a property exists on the underlying object.
*
* @param mixed $name
*
* @return bool
*/
public function __isset($name)
{
if (\is_object($this->value)) {
return isset($this->value->{$name});
}
if (\is_array($this->value) || $this->value instanceof \ArrayObject) {
return isset($this->value[$name]);
}
return \false;
}
/**
* Dynamically pass a method to the underlying object.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
if (static::hasMacro($method)) {
return $this->macroCall($method, $parameters);
}
if (\is_object($this->value)) {
return $this->value->{$method}(...$parameters);
}
}
/**
* Determine if an item exists at an offset.
*
* @param mixed $key
*
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists($key)
{
return Arr::accessible($this->value) && Arr::exists($this->value, $key);
}
/**
* Get an item at a given offset.
*
* @param mixed $key
*
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($key)
{
return Arr::get($this->value, $key);
}
/**
* Set the item at a given offset.
*
* @param mixed $key
* @param mixed $value
*/
#[\ReturnTypeWillChange]
public function offsetSet($key, $value)
{
if (Arr::accessible($this->value)) {
$this->value[$key] = $value;
}
}
/**
* Unset the item at a given offset.
*
* @param string $key
*/
#[\ReturnTypeWillChange]
public function offsetUnset($key)
{
if (Arr::accessible($this->value)) {
unset($this->value[$key]);
}
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Doctrine\Inflector\InflectorFactory;
class Pluralizer
{
/**
* Uncountable word forms.
*
* @var string[]
*/
public static $uncountable = ['audio', 'bison', 'cattle', 'chassis', 'compensation', 'coreopsis', 'data', 'deer', 'education', 'emoji', 'equipment', 'evidence', 'feedback', 'firmware', 'fish', 'furniture', 'gold', 'hardware', 'information', 'jedi', 'kin', 'knowledge', 'love', 'metadata', 'money', 'moose', 'news', 'nutrition', 'offspring', 'plankton', 'pokemon', 'police', 'rain', 'recommended', 'related', 'rice', 'series', 'sheep', 'software', 'species', 'swine', 'traffic', 'wheat'];
/**
* Get the plural form of an English word.
*
* @param string $value
* @param array|\Countable|int $count
*
* @return string
*/
public static function plural($value, $count = 2)
{
if (\is_countable($count)) {
$count = \count($count);
}
if (1 === (int) \abs($count) || static::uncountable($value) || 0 == \preg_match('/^(.*)[A-Za-z0-9\\x{0080}-\\x{FFFF}]$/u', $value)) {
return $value;
}
$plural = static::inflector()->pluralize($value);
return static::matchCase($plural, $value);
}
/**
* Get the singular form of an English word.
*
* @param string $value
*
* @return string
*/
public static function singular($value)
{
$singular = static::inflector()->singularize($value);
return static::matchCase($singular, $value);
}
/**
* Get the inflector instance.
*
* @return \Doctrine\Inflector\Inflector
*/
public static function inflector()
{
static $inflector;
if (\is_null($inflector)) {
$inflector = InflectorFactory::createForLanguage('english')->build();
}
return $inflector;
}
/**
* Determine if the given value is uncountable.
*
* @param string $value
*
* @return bool
*/
protected static function uncountable($value)
{
return \in_array(\strtolower($value), static::$uncountable);
}
/**
* Attempt to match the case on two strings.
*
* @param string $value
* @param string $comparison
*
* @return string
*/
protected static function matchCase($value, $comparison)
{
$functions = ['mb_strtolower', 'mb_strtoupper', 'ucfirst', 'ucwords'];
foreach ($functions as $function) {
if ($function($comparison) === $comparison) {
return $function($value);
}
}
return $value;
}
}

View File

@@ -0,0 +1,68 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
/**
* ProcessUtils is a bunch of utility methods.
*
* This class was originally copied from Symfony 3.
*/
class ProcessUtils
{
/**
* Escapes a string to be used as a shell argument.
*
* @param string $argument
*
* @return string
*/
public static function escapeArgument($argument)
{
// Fix for PHP bug #43784 escapeshellarg removes % from given string
// Fix for PHP bug #49446 escapeshellarg doesn't work on Windows
// @see https://bugs.php.net/bug.php?id=43784
// @see https://bugs.php.net/bug.php?id=49446
if ('\\' === \DIRECTORY_SEPARATOR) {
if ('' === $argument) {
return '""';
}
$escapedArgument = '';
$quote = \false;
foreach (\preg_split('/(")/', $argument, -1, \PREG_SPLIT_NO_EMPTY | \PREG_SPLIT_DELIM_CAPTURE) as $part) {
if ('"' === $part) {
$escapedArgument .= '\\"';
} elseif (self::isSurroundedBy($part, '%')) {
// Avoid environment variable expansion
$escapedArgument .= '^%"'.\substr($part, 1, -1).'"^%';
} else {
// escape trailing backslash
if ('\\' === \substr($part, -1)) {
$part .= '\\';
}
$quote = \true;
$escapedArgument .= $part;
}
}
if ($quote) {
$escapedArgument = '"'.$escapedArgument.'"';
}
return $escapedArgument;
}
return "'".\str_replace("'", "'\\''", $argument)."'";
}
/**
* Is the given string surrounded by the given character?
*
* @param string $arg
* @param string $char
*
* @return bool
*/
protected static function isSurroundedBy($arg, $char)
{
return 2 < \strlen($arg) && $char === $arg[0] && $char === $arg[\strlen($arg) - 1];
}
}

View File

@@ -0,0 +1,122 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
class Reflector
{
/**
* This is a PHP 7.4 compatible implementation of is_callable.
*
* @param mixed $var
* @param bool $syntaxOnly
*
* @return bool
*/
public static function isCallable($var, $syntaxOnly = \false)
{
if (!\is_array($var)) {
return \is_callable($var, $syntaxOnly);
}
if (!isset($var[0]) || !isset($var[1]) || !\is_string($var[1] ?? null)) {
return \false;
}
if ($syntaxOnly && (\is_string($var[0]) || \is_object($var[0])) && \is_string($var[1])) {
return \true;
}
$class = \is_object($var[0]) ? \get_class($var[0]) : $var[0];
$method = $var[1];
if (!\class_exists($class)) {
return \false;
}
if (\method_exists($class, $method)) {
return (new \ReflectionMethod($class, $method))->isPublic();
}
if (\is_object($var[0]) && \method_exists($class, '__call')) {
return (new \ReflectionMethod($class, '__call'))->isPublic();
}
if (!\is_object($var[0]) && \method_exists($class, '__callStatic')) {
return (new \ReflectionMethod($class, '__callStatic'))->isPublic();
}
return \false;
}
/**
* Get the class name of the given parameter's type, if possible.
*
* @param \ReflectionParameter $parameter
*
* @return null|string
*/
public static function getParameterClassName($parameter)
{
$type = $parameter->getType();
if (!$type instanceof \ReflectionNamedType || $type->isBuiltin()) {
return;
}
return static::getTypeName($parameter, $type);
}
/**
* Get the class names of the given parameter's type, including union types.
*
* @param \ReflectionParameter $parameter
*
* @return array
*/
public static function getParameterClassNames($parameter)
{
$type = $parameter->getType();
if (!$type instanceof \ReflectionUnionType) {
return \array_filter([static::getParameterClassName($parameter)]);
}
$unionTypes = [];
foreach ($type->getTypes() as $listedType) {
if (!$listedType instanceof \ReflectionNamedType || $listedType->isBuiltin()) {
continue;
}
$unionTypes[] = static::getTypeName($parameter, $listedType);
}
return \array_filter($unionTypes);
}
/**
* Determine if the parameter's type is a subclass of the given type.
*
* @param \ReflectionParameter $parameter
* @param string $className
*
* @return bool
*/
public static function isParameterSubclassOf($parameter, $className)
{
$paramClassName = static::getParameterClassName($parameter);
return $paramClassName && (\class_exists($paramClassName) || \interface_exists($paramClassName)) && (new \ReflectionClass($paramClassName))->isSubclassOf($className);
}
/**
* Get the given type's class name.
*
* @param \ReflectionParameter $parameter
* @param \ReflectionNamedType $type
*
* @return string
*/
protected static function getTypeName($parameter, $type)
{
$name = $type->getName();
if (!\is_null($class = $parameter->getDeclaringClass())) {
if ('self' === $name) {
return $class->getName();
}
if ('parent' === $name && ($parent = $class->getParentClass())) {
return $parent->getName();
}
}
return $name;
}
}

View File

@@ -0,0 +1,397 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Illuminate\Console\Application as Artisan;
use _JchOptimizeVendor\Illuminate\Contracts\Foundation\CachesConfiguration;
use _JchOptimizeVendor\Illuminate\Contracts\Foundation\CachesRoutes;
use _JchOptimizeVendor\Illuminate\Contracts\Support\DeferrableProvider;
use _JchOptimizeVendor\Illuminate\Database\Eloquent\Factory as ModelFactory;
use _JchOptimizeVendor\Illuminate\View\Compilers\BladeCompiler;
abstract class ServiceProvider
{
/**
* The paths that should be published.
*
* @var array
*/
public static $publishes = [];
/**
* The paths that should be published by group.
*
* @var array
*/
public static $publishGroups = [];
/**
* The application instance.
*
* @var \Illuminate\Contracts\Foundation\Application
*/
protected $app;
/**
* All of the registered booting callbacks.
*
* @var array
*/
protected $bootingCallbacks = [];
/**
* All of the registered booted callbacks.
*
* @var array
*/
protected $bootedCallbacks = [];
/**
* Create a new service provider instance.
*
* @param \Illuminate\Contracts\Foundation\Application $app
*/
public function __construct($app)
{
$this->app = $app;
}
/**
* Register any application services.
*/
public function register()
{
}
/**
* Register a booting callback to be run before the "boot" method is called.
*/
public function booting(\Closure $callback)
{
$this->bootingCallbacks[] = $callback;
}
/**
* Register a booted callback to be run after the "boot" method is called.
*/
public function booted(\Closure $callback)
{
$this->bootedCallbacks[] = $callback;
}
/**
* Call the registered booting callbacks.
*/
public function callBootingCallbacks()
{
$index = 0;
while ($index < \count($this->bootingCallbacks)) {
$this->app->call($this->bootingCallbacks[$index]);
++$index;
}
}
/**
* Call the registered booted callbacks.
*/
public function callBootedCallbacks()
{
$index = 0;
while ($index < \count($this->bootedCallbacks)) {
$this->app->call($this->bootedCallbacks[$index]);
++$index;
}
}
/**
* Get the paths to publish.
*
* @param null|string $provider
* @param null|string $group
*
* @return array
*/
public static function pathsToPublish($provider = null, $group = null)
{
if (!\is_null($paths = static::pathsForProviderOrGroup($provider, $group))) {
return $paths;
}
return collect(static::$publishes)->reduce(function ($paths, $p) {
return \array_merge($paths, $p);
}, []);
}
/**
* Get the service providers available for publishing.
*
* @return array
*/
public static function publishableProviders()
{
return \array_keys(static::$publishes);
}
/**
* Get the groups available for publishing.
*
* @return array
*/
public static function publishableGroups()
{
return \array_keys(static::$publishGroups);
}
/**
* Register the package's custom Artisan commands.
*
* @param array|mixed $commands
*/
public function commands($commands)
{
$commands = \is_array($commands) ? $commands : \func_get_args();
Artisan::starting(function ($artisan) use ($commands) {
$artisan->resolveCommands($commands);
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [];
}
/**
* Get the events that trigger this service provider to register.
*
* @return array
*/
public function when()
{
return [];
}
/**
* Determine if the provider is deferred.
*
* @return bool
*/
public function isDeferred()
{
return $this instanceof DeferrableProvider;
}
/**
* Merge the given configuration with the existing configuration.
*
* @param string $path
* @param string $key
*/
protected function mergeConfigFrom($path, $key)
{
if (!($this->app instanceof CachesConfiguration && $this->app->configurationIsCached())) {
$config = $this->app->make('config');
$config->set($key, \array_merge(require $path, $config->get($key, [])));
}
}
/**
* Load the given routes file if routes are not already cached.
*
* @param string $path
*/
protected function loadRoutesFrom($path)
{
if (!($this->app instanceof CachesRoutes && $this->app->routesAreCached())) {
require $path;
}
}
/**
* Register a view file namespace.
*
* @param array|string $path
* @param string $namespace
*/
protected function loadViewsFrom($path, $namespace)
{
$this->callAfterResolving('view', function ($view) use ($path, $namespace) {
if (isset($this->app->config['view']['paths']) && \is_array($this->app->config['view']['paths'])) {
foreach ($this->app->config['view']['paths'] as $viewPath) {
if (\is_dir($appPath = $viewPath.'/vendor/'.$namespace)) {
$view->addNamespace($namespace, $appPath);
}
}
}
$view->addNamespace($namespace, $path);
});
}
/**
* Register the given view components with a custom prefix.
*
* @param string $prefix
*/
protected function loadViewComponentsAs($prefix, array $components)
{
$this->callAfterResolving(BladeCompiler::class, function ($blade) use ($prefix, $components) {
foreach ($components as $alias => $component) {
$blade->component($component, \is_string($alias) ? $alias : null, $prefix);
}
});
}
/**
* Register a translation file namespace.
*
* @param string $path
* @param string $namespace
*/
protected function loadTranslationsFrom($path, $namespace)
{
$this->callAfterResolving('translator', function ($translator) use ($path, $namespace) {
$translator->addNamespace($namespace, $path);
});
}
/**
* Register a JSON translation file path.
*
* @param string $path
*/
protected function loadJsonTranslationsFrom($path)
{
$this->callAfterResolving('translator', function ($translator) use ($path) {
$translator->addJsonPath($path);
});
}
/**
* Register database migration paths.
*
* @param array|string $paths
*/
protected function loadMigrationsFrom($paths)
{
$this->callAfterResolving('migrator', function ($migrator) use ($paths) {
foreach ((array) $paths as $path) {
$migrator->path($path);
}
});
}
/**
* Register Eloquent model factory paths.
*
* @deprecated will be removed in a future Laravel version
*
* @param array|string $paths
*/
protected function loadFactoriesFrom($paths)
{
$this->callAfterResolving(ModelFactory::class, function ($factory) use ($paths) {
foreach ((array) $paths as $path) {
$factory->load($path);
}
});
}
/**
* Setup an after resolving listener, or fire immediately if already resolved.
*
* @param string $name
* @param callable $callback
*/
protected function callAfterResolving($name, $callback)
{
$this->app->afterResolving($name, $callback);
if ($this->app->resolved($name)) {
$callback($this->app->make($name), $this->app);
}
}
/**
* Register paths to be published by the publish command.
*
* @param mixed $groups
*/
protected function publishes(array $paths, $groups = null)
{
$this->ensurePublishArrayInitialized($class = static::class);
static::$publishes[$class] = \array_merge(static::$publishes[$class], $paths);
foreach ((array) $groups as $group) {
$this->addPublishGroup($group, $paths);
}
}
/**
* Ensure the publish array for the service provider is initialized.
*
* @param string $class
*/
protected function ensurePublishArrayInitialized($class)
{
if (!\array_key_exists($class, static::$publishes)) {
static::$publishes[$class] = [];
}
}
/**
* Add a publish group / tag to the service provider.
*
* @param string $group
* @param array $paths
*/
protected function addPublishGroup($group, $paths)
{
if (!\array_key_exists($group, static::$publishGroups)) {
static::$publishGroups[$group] = [];
}
static::$publishGroups[$group] = \array_merge(static::$publishGroups[$group], $paths);
}
/**
* Get the paths for the provider or group (or both).
*
* @param null|string $provider
* @param null|string $group
*
* @return array
*/
protected static function pathsForProviderOrGroup($provider, $group)
{
if ($provider && $group) {
return static::pathsForProviderAndGroup($provider, $group);
}
if ($group && \array_key_exists($group, static::$publishGroups)) {
return static::$publishGroups[$group];
}
if ($provider && \array_key_exists($provider, static::$publishes)) {
return static::$publishes[$provider];
}
if ($group || $provider) {
return [];
}
}
/**
* Get the paths for the provider and group.
*
* @param string $provider
* @param string $group
*
* @return array
*/
protected static function pathsForProviderAndGroup($provider, $group)
{
if (!empty(static::$publishes[$provider]) && !empty(static::$publishGroups[$group])) {
return \array_intersect_key(static::$publishes[$provider], static::$publishGroups[$group]);
}
return [];
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,62 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
class Timebox
{
/**
* Indicates if the timebox is allowed to return early.
*
* @var bool
*/
public $earlyReturn = \false;
/**
* Invoke the given callback within the specified timebox minimum.
*
* @return mixed
*/
public function call(callable $callback, int $microseconds)
{
$start = \microtime(\true);
$result = $callback($this);
$remainder = $microseconds - (\microtime(\true) - $start) * 1000000;
if (!$this->earlyReturn && $remainder > 0) {
$this->usleep($remainder);
}
return $result;
}
/**
* Indicate that the timebox can return early.
*
* @return $this
*/
public function returnEarly()
{
$this->earlyReturn = \true;
return $this;
}
/**
* Indicate that the timebox cannot return early.
*
* @return $this
*/
public function dontReturnEarly()
{
$this->earlyReturn = \false;
return $this;
}
/**
* Sleep for the specified number of microseconds.
*/
protected function usleep($microseconds)
{
\usleep($microseconds);
}
}

View File

@@ -0,0 +1,64 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support\Traits;
use _JchOptimizeVendor\Illuminate\Contracts\Container\Container;
use _JchOptimizeVendor\Illuminate\Support\Fluent;
trait CapsuleManagerTrait
{
/**
* The current globally used instance.
*
* @var object
*/
protected static $instance;
/**
* The container instance.
*
* @var \Illuminate\Contracts\Container\Container
*/
protected $container;
/**
* Make this capsule instance available globally.
*/
public function setAsGlobal()
{
static::$instance = $this;
}
/**
* Get the IoC container instance.
*
* @return \Illuminate\Contracts\Container\Container
*/
public function getContainer()
{
return $this->container;
}
/**
* Set the IoC container instance.
*
* @param \Illuminate\Contracts\Container\Container $container
*/
public function setContainer(Container $container)
{
$this->container = $container;
}
/**
* Setup the IoC container instance.
*
* @param \Illuminate\Contracts\Container\Container $container
*/
protected function setupContainer(Container $container)
{
$this->container = $container;
if (!$this->container->bound('config')) {
$this->container->instance('config', new Fluent());
}
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support\Traits;
trait Conditionable
{
/**
* Apply the callback if the given "value" is truthy.
*
* @param mixed $value
* @param callable $callback
* @param null|callable $default
*
* @return $this|mixed
*/
public function when($value, $callback, $default = null)
{
if ($value) {
return $callback($this, $value) ?: $this;
}
if ($default) {
return $default($this, $value) ?: $this;
}
return $this;
}
/**
* Apply the callback if the given "value" is falsy.
*
* @param mixed $value
* @param callable $callback
* @param null|callable $default
*
* @return $this|mixed
*/
public function unless($value, $callback, $default = null)
{
if (!$value) {
return $callback($this, $value) ?: $this;
}
if ($default) {
return $default($this, $value) ?: $this;
}
return $this;
}
}

View File

@@ -0,0 +1,66 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support\Traits;
trait ForwardsCalls
{
/**
* Forward a method call to the given object.
*
* @param mixed $object
* @param string $method
* @param array $parameters
*
* @return mixed
*
* @throws \BadMethodCallException
*/
protected function forwardCallTo($object, $method, $parameters)
{
try {
return $object->{$method}(...$parameters);
} catch (\Error|\BadMethodCallException $e) {
$pattern = '~^Call to undefined method (?P<class>[^:]+)::(?P<method>[^\\(]+)\\(\\)$~';
if (!\preg_match($pattern, $e->getMessage(), $matches)) {
throw $e;
}
if ($matches['class'] != \get_class($object) || $matches['method'] != $method) {
throw $e;
}
static::throwBadMethodCallException($method);
}
}
/**
* Forward a method call to the given object, returning $this if the forwarded call returned itself.
*
* @param mixed $object
* @param string $method
* @param array $parameters
*
* @return mixed
*
* @throws \BadMethodCallException
*/
protected function forwardDecoratedCallTo($object, $method, $parameters)
{
$result = $this->forwardCallTo($object, $method, $parameters);
if ($result === $object) {
return $this;
}
return $result;
}
/**
* Throw a bad method call exception for the given method.
*
* @param string $method
*
* @throws \BadMethodCallException
*/
protected static function throwBadMethodCallException($method)
{
throw new \BadMethodCallException(\sprintf('Call to undefined method %s::%s()', static::class, $method));
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support\Traits;
use _JchOptimizeVendor\Illuminate\Container\Container;
trait Localizable
{
/**
* Run the callback with the given locale.
*
* @param string $locale
* @param \Closure $callback
*
* @return mixed
*/
public function withLocale($locale, $callback)
{
if (!$locale) {
return $callback();
}
$app = Container::getInstance();
$original = $app->getLocale();
try {
$app->setLocale($locale);
return $callback();
} finally {
$app->setLocale($original);
}
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support\Traits;
use _JchOptimizeVendor\Illuminate\Support\Reflector;
use Closure;
trait ReflectsClosures
{
/**
* Get the class name of the first parameter of the given Closure.
*
* @return string
*
* @throws \ReflectionException
* @throws \RuntimeException
*/
protected function firstClosureParameterType(\Closure $closure)
{
$types = \array_values($this->closureParameterTypes($closure));
if (!$types) {
throw new \RuntimeException('The given Closure has no parameters.');
}
if (null === $types[0]) {
throw new \RuntimeException('The first parameter of the given Closure is missing a type hint.');
}
return $types[0];
}
/**
* Get the class names of the first parameter of the given Closure, including union types.
*
* @return array
*
* @throws \ReflectionException
* @throws \RuntimeException
*/
protected function firstClosureParameterTypes(\Closure $closure)
{
$reflection = new \ReflectionFunction($closure);
$types = collect($reflection->getParameters())->mapWithKeys(function ($parameter) {
if ($parameter->isVariadic()) {
return [$parameter->getName() => null];
}
return [$parameter->getName() => Reflector::getParameterClassNames($parameter)];
})->filter()->values()->all();
if (empty($types)) {
throw new \RuntimeException('The given Closure has no parameters.');
}
if (isset($types[0]) && empty($types[0])) {
throw new \RuntimeException('The first parameter of the given Closure is missing a type hint.');
}
return $types[0];
}
/**
* Get the class names / types of the parameters of the given Closure.
*
* @return array
*
* @throws \ReflectionException
*/
protected function closureParameterTypes(\Closure $closure)
{
$reflection = new \ReflectionFunction($closure);
return collect($reflection->getParameters())->mapWithKeys(function ($parameter) {
if ($parameter->isVariadic()) {
return [$parameter->getName() => null];
}
return [$parameter->getName() => Reflector::getParameterClassName($parameter)];
})->all();
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support\Traits;
use function _JchOptimizeVendor\tap;
trait Tappable
{
/**
* Call the given Closure with this instance then return the instance.
*
* @param null|callable $callback
*
* @return $this|\Illuminate\Support\HigherOrderTapProxy
*/
public function tap($callback = null)
{
return tap($this, $callback);
}
}

View File

@@ -0,0 +1,212 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Illuminate\Contracts\Support\ValidatedData;
class ValidatedInput implements ValidatedData
{
/**
* The underlying input.
*
* @var array
*/
protected $input;
/**
* Create a new validated input container.
*/
public function __construct(array $input)
{
$this->input = $input;
}
/**
* Dynamically access input data.
*
* @param string $name
*
* @return mixed
*/
public function __get($name)
{
return $this->input[$name];
}
/**
* Dynamically set input data.
*
* @param string $name
* @param mixed $value
*
* @return mixed
*/
public function __set($name, $value)
{
$this->input[$name] = $value;
}
/**
* Determine if an input key is set.
*
* @param mixed $name
*
* @return bool
*/
public function __isset($name)
{
return isset($this->input[$name]);
}
/**
* Remove an input key.
*
* @param string $name
*/
public function __unset($name)
{
unset($this->input[$name]);
}
/**
* Get a subset containing the provided keys with values from the input data.
*
* @param array|mixed $keys
*
* @return array
*/
public function only($keys)
{
$results = [];
$input = $this->input;
$placeholder = new \stdClass();
foreach (\is_array($keys) ? $keys : \func_get_args() as $key) {
$value = data_get($input, $key, $placeholder);
if ($value !== $placeholder) {
Arr::set($results, $key, $value);
}
}
return $results;
}
/**
* Get all of the input except for a specified array of items.
*
* @param array|mixed $keys
*
* @return array
*/
public function except($keys)
{
$keys = \is_array($keys) ? $keys : \func_get_args();
$results = $this->input;
Arr::forget($results, $keys);
return $results;
}
/**
* Merge the validated input with the given array of additional data.
*
* @return static
*/
public function merge(array $items)
{
return new static(\array_merge($this->input, $items));
}
/**
* Get the input as a collection.
*
* @return \Illuminate\Support\Collection
*/
public function collect()
{
return new Collection($this->input);
}
/**
* Get the raw, underlying input array.
*
* @return array
*/
public function all()
{
return $this->input;
}
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray()
{
return $this->all();
}
/**
* Determine if an item exists at an offset.
*
* @param mixed $key
*
* @return bool
*/
#[\ReturnTypeWillChange]
public function offsetExists($key)
{
return isset($this->input[$key]);
}
/**
* Get an item at a given offset.
*
* @param mixed $key
*
* @return mixed
*/
#[\ReturnTypeWillChange]
public function offsetGet($key)
{
return $this->input[$key];
}
/**
* Set the item at a given offset.
*
* @param mixed $key
* @param mixed $value
*/
#[\ReturnTypeWillChange]
public function offsetSet($key, $value)
{
if (\is_null($key)) {
$this->input[] = $value;
} else {
$this->input[$key] = $value;
}
}
/**
* Unset the item at a given offset.
*
* @param string $key
*/
#[\ReturnTypeWillChange]
public function offsetUnset($key)
{
unset($this->input[$key]);
}
/**
* Get an iterator for the input.
*
* @return \ArrayIterator
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
return new \ArrayIterator($this->input);
}
}

View File

@@ -0,0 +1,134 @@
<?php
namespace _JchOptimizeVendor\Illuminate\Support;
use _JchOptimizeVendor\Illuminate\Contracts\Support\MessageBag as MessageBagContract;
/**
* @mixin \Illuminate\Contracts\Support\MessageBag
*/
class ViewErrorBag implements \Countable
{
/**
* The array of the view error bags.
*
* @var array
*/
protected $bags = [];
/**
* Dynamically call methods on the default bag.
*
* @param string $method
* @param array $parameters
*
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->getBag('default')->{$method}(...$parameters);
}
/**
* Dynamically access a view error bag.
*
* @param string $key
*
* @return \Illuminate\Contracts\Support\MessageBag
*/
public function __get($key)
{
return $this->getBag($key);
}
/**
* Dynamically set a view error bag.
*
* @param string $key
* @param \Illuminate\Contracts\Support\MessageBag $value
*/
public function __set($key, $value)
{
$this->put($key, $value);
}
/**
* Convert the default bag to its string representation.
*
* @return string
*/
public function __toString()
{
return (string) $this->getBag('default');
}
/**
* Checks if a named MessageBag exists in the bags.
*
* @param string $key
*
* @return bool
*/
public function hasBag($key = 'default')
{
return isset($this->bags[$key]);
}
/**
* Get a MessageBag instance from the bags.
*
* @param string $key
*
* @return \Illuminate\Contracts\Support\MessageBag
*/
public function getBag($key)
{
return Arr::get($this->bags, $key) ?: new MessageBag();
}
/**
* Get all the bags.
*
* @return array
*/
public function getBags()
{
return $this->bags;
}
/**
* Add a new MessageBag instance to the bags.
*
* @param string $key
* @param \Illuminate\Contracts\Support\MessageBag $bag
*
* @return $this
*/
public function put($key, MessageBagContract $bag)
{
$this->bags[$key] = $bag;
return $this;
}
/**
* Determine if the default message bag has any messages.
*
* @return bool
*/
public function any()
{
return $this->count() > 0;
}
/**
* Get the number of messages in the default bag.
*
* @return int
*/
#[\ReturnTypeWillChange]
public function count()
{
return $this->getBag('default')->count();
}
}

View File

@@ -0,0 +1,360 @@
<?php
namespace _JchOptimizeVendor;
use _JchOptimizeVendor\Illuminate\Contracts\Support\DeferringDisplayableValue;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Htmlable;
use _JchOptimizeVendor\Illuminate\Support\Arr;
use _JchOptimizeVendor\Illuminate\Support\Env;
use _JchOptimizeVendor\Illuminate\Support\HigherOrderTapProxy;
use _JchOptimizeVendor\Illuminate\Support\Optional;
if (!\function_exists('_JchOptimizeVendor\\append_config')) {
/**
* Assign high numeric IDs to a config item to force appending.
*
* @return array
*/
function append_config(array $array)
{
$start = 9999;
foreach ($array as $key => $value) {
if (\is_numeric($key)) {
++$start;
$array[$start] = Arr::pull($array, $key);
}
}
return $array;
}
}
if (!\function_exists('_JchOptimizeVendor\\blank')) {
/**
* Determine if the given value is "blank".
*
* @param mixed $value
*
* @return bool
*/
function blank($value)
{
if (\is_null($value)) {
return \true;
}
if (\is_string($value)) {
return '' === \trim($value);
}
if (\is_numeric($value) || \is_bool($value)) {
return \false;
}
if ($value instanceof \Countable) {
return 0 === \count($value);
}
return empty($value);
}
}
if (!\function_exists('_JchOptimizeVendor\\class_basename')) {
/**
* Get the class "basename" of the given object / class.
*
* @param object|string $class
*
* @return string
*/
function class_basename($class)
{
$class = \is_object($class) ? \get_class($class) : $class;
return \basename(\str_replace('\\', '/', $class));
}
}
if (!\function_exists('_JchOptimizeVendor\\class_uses_recursive')) {
/**
* Returns all traits used by a class, its parent classes and trait of their traits.
*
* @param object|string $class
*
* @return array
*/
function class_uses_recursive($class)
{
if (\is_object($class)) {
$class = \get_class($class);
}
$results = [];
foreach (\array_reverse(\class_parents($class)) + [$class => $class] as $class) {
$results += trait_uses_recursive($class);
}
return \array_unique($results);
}
}
if (!\function_exists('_JchOptimizeVendor\\e')) {
/**
* Encode HTML special characters in a string.
*
* @param null|\Illuminate\Contracts\Support\DeferringDisplayableValue|\Illuminate\Contracts\Support\Htmlable|string $value
* @param bool $doubleEncode
*
* @return string
*/
function e($value, $doubleEncode = \true)
{
if ($value instanceof DeferringDisplayableValue) {
$value = $value->resolveDisplayableValue();
}
if ($value instanceof Htmlable) {
return $value->toHtml();
}
return \htmlspecialchars($value ?? '', \ENT_QUOTES, 'UTF-8', $doubleEncode);
}
}
if (!\function_exists('_JchOptimizeVendor\\env')) {
/**
* Gets the value of an environment variable.
*
* @param string $key
* @param mixed $default
*
* @return mixed
*/
function env($key, $default = null)
{
return Env::get($key, $default);
}
}
if (!\function_exists('_JchOptimizeVendor\\filled')) {
/**
* Determine if a value is "filled".
*
* @param mixed $value
*
* @return bool
*/
function filled($value)
{
return !blank($value);
}
}
if (!\function_exists('_JchOptimizeVendor\\object_get')) {
/**
* Get an item from an object using "dot" notation.
*
* @param object $object
* @param null|string $key
* @param mixed $default
*
* @return mixed
*/
function object_get($object, $key, $default = null)
{
if (\is_null($key) || '' === \trim($key)) {
return $object;
}
foreach (\explode('.', $key) as $segment) {
if (!\is_object($object) || !isset($object->{$segment})) {
return value($default);
}
$object = $object->{$segment};
}
return $object;
}
}
if (!\function_exists('_JchOptimizeVendor\\optional')) {
/**
* Provide access to optional objects.
*
* @param mixed $value
*
* @return mixed
*/
function optional($value = null, callable $callback = null)
{
if (\is_null($callback)) {
return new Optional($value);
}
if (!\is_null($value)) {
return $callback($value);
}
}
}
if (!\function_exists('_JchOptimizeVendor\\preg_replace_array')) {
/**
* Replace a given pattern with each value in the array in sequentially.
*
* @param string $pattern
* @param string $subject
*
* @return string
*/
function preg_replace_array($pattern, array $replacements, $subject)
{
return \preg_replace_callback($pattern, function () use (&$replacements) {
foreach ($replacements as $key => $value) {
return \array_shift($replacements);
}
}, $subject);
}
}
if (!\function_exists('_JchOptimizeVendor\\retry')) {
/**
* Retry an operation a given number of times.
*
* @param int $times
* @param \Closure|int $sleepMilliseconds
* @param null|callable $when
*
* @return mixed
*
* @throws \Exception
*/
function retry($times, callable $callback, $sleepMilliseconds = 0, $when = null)
{
$attempts = 0;
beginning:
$attempts++;
--$times;
try {
return $callback($attempts);
} catch (\Exception $e) {
if ($times < 1 || $when && !$when($e)) {
throw $e;
}
if ($sleepMilliseconds) {
\usleep(value($sleepMilliseconds, $attempts) * 1000);
}
goto beginning;
}
}
}
if (!\function_exists('_JchOptimizeVendor\\tap')) {
/**
* Call the given Closure with the given value then return the value.
*
* @param mixed $value
* @param null|callable $callback
*
* @return mixed
*/
function tap($value, $callback = null)
{
if (\is_null($callback)) {
return new HigherOrderTapProxy($value);
}
$callback($value);
return $value;
}
}
if (!\function_exists('_JchOptimizeVendor\\throw_if')) {
/**
* Throw the given exception if the given condition is true.
*
* @param mixed $condition
* @param string|\Throwable $exception
* @param mixed ...$parameters
*
* @return mixed
*
* @throws \Throwable
*/
function throw_if($condition, $exception = 'RuntimeException', ...$parameters)
{
if ($condition) {
if (\is_string($exception) && \class_exists($exception)) {
$exception = new $exception(...$parameters);
}
throw \is_string($exception) ? new \RuntimeException($exception) : $exception;
}
return $condition;
}
}
if (!\function_exists('_JchOptimizeVendor\\throw_unless')) {
/**
* Throw the given exception unless the given condition is true.
*
* @param mixed $condition
* @param string|\Throwable $exception
* @param mixed ...$parameters
*
* @return mixed
*
* @throws \Throwable
*/
function throw_unless($condition, $exception = 'RuntimeException', ...$parameters)
{
throw_if(!$condition, $exception, ...$parameters);
return $condition;
}
}
if (!\function_exists('_JchOptimizeVendor\\trait_uses_recursive')) {
/**
* Returns all traits used by a trait and its traits.
*
* @param string $trait
*
* @return array
*/
function trait_uses_recursive($trait)
{
$traits = \class_uses($trait) ?: [];
foreach ($traits as $trait) {
$traits += trait_uses_recursive($trait);
}
return $traits;
}
}
if (!\function_exists('_JchOptimizeVendor\\transform')) {
/**
* Transform the given value if it is present.
*
* @param mixed $value
* @param mixed $default
*
* @return null|mixed
*/
function transform($value, callable $callback, $default = null)
{
if (filled($value)) {
return $callback($value);
}
if (\is_callable($default)) {
return $default($value);
}
return $default;
}
}
if (!\function_exists('_JchOptimizeVendor\\windows_os')) {
/**
* Determine whether the current environment is Windows based.
*
* @return bool
*/
function windows_os()
{
return \PHP_OS_FAMILY === 'Windows';
}
}
if (!\function_exists('_JchOptimizeVendor\\with')) {
/**
* Return the given value, optionally passed through the given callback.
*
* @param mixed $value
*
* @return mixed
*/
function with($value, callable $callback = null)
{
return \is_null($callback) ? $value : $callback($value);
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace _JchOptimizeVendor\Illuminate\View;
class AnonymousComponent extends Component
{
/**
* The component view.
*
* @var string
*/
protected $view;
/**
* The component data.
*
* @var array
*/
protected $data = [];
/**
* Create a new anonymous component instance.
*
* @param string $view
* @param array $data
*/
public function __construct($view, $data)
{
$this->view = $view;
$this->data = $data;
}
/**
* Get the view / view contents that represent the component.
*
* @return string
*/
public function render()
{
return $this->view;
}
/**
* Get the data that should be supplied to the view.
*
* @return array
*/
public function data()
{
$this->attributes = $this->attributes ?: $this->newAttributeBag();
return \array_merge(optional($this->data['attributes'] ?? null)->getAttributes() ?: [], $this->attributes->getAttributes(), $this->data, ['attributes' => $this->attributes]);
}
}

View File

@@ -0,0 +1,33 @@
<?php
namespace _JchOptimizeVendor\Illuminate\View;
class AppendableAttributeValue
{
/**
* The attribute value.
*
* @var mixed
*/
public $value;
/**
* Create a new appendable attribute value.
*
* @param mixed $value
*/
public function __construct($value)
{
$this->value = $value;
}
/**
* Get the string value.
*
* @return string
*/
public function __toString()
{
return (string) $this->value;
}
}

View File

@@ -0,0 +1,761 @@
<?php
namespace _JchOptimizeVendor\Illuminate\View\Compilers;
use _JchOptimizeVendor\Illuminate\Container\Container;
use _JchOptimizeVendor\Illuminate\Contracts\Support\Htmlable;
use _JchOptimizeVendor\Illuminate\Contracts\View\Factory as ViewFactory;
use _JchOptimizeVendor\Illuminate\Contracts\View\View;
use _JchOptimizeVendor\Illuminate\Support\Arr;
use _JchOptimizeVendor\Illuminate\Support\Str;
use _JchOptimizeVendor\Illuminate\Support\Traits\ReflectsClosures;
use _JchOptimizeVendor\Illuminate\View\Component;
use function _JchOptimizeVendor\collect;
class BladeCompiler extends Compiler implements CompilerInterface
{
use Concerns\CompilesAuthorizations;
use Concerns\CompilesClasses;
use Concerns\CompilesComments;
use Concerns\CompilesComponents;
use Concerns\CompilesConditionals;
use Concerns\CompilesEchos;
use Concerns\CompilesErrors;
use Concerns\CompilesHelpers;
use Concerns\CompilesIncludes;
use Concerns\CompilesInjections;
use Concerns\CompilesJson;
use Concerns\CompilesJs;
use Concerns\CompilesLayouts;
use Concerns\CompilesLoops;
use Concerns\CompilesRawPhp;
use Concerns\CompilesStacks;
use Concerns\CompilesTranslations;
use ReflectsClosures;
/**
* All of the registered extensions.
*
* @var array
*/
protected $extensions = [];
/**
* All custom "directive" handlers.
*
* @var array
*/
protected $customDirectives = [];
/**
* All custom "condition" handlers.
*
* @var array
*/
protected $conditions = [];
/**
* All of the registered precompilers.
*
* @var array
*/
protected $precompilers = [];
/**
* The file currently being compiled.
*
* @var string
*/
protected $path;
/**
* All of the available compiler functions.
*
* @var string[]
*/
protected $compilers = [
// 'Comments',
'Extensions',
'Statements',
'Echos',
];
/**
* Array of opening and closing tags for raw echos.
*
* @var string[]
*/
protected $rawTags = ['{!!', '!!}'];
/**
* Array of opening and closing tags for regular echos.
*
* @var string[]
*/
protected $contentTags = ['{{', '}}'];
/**
* Array of opening and closing tags for escaped echos.
*
* @var string[]
*/
protected $escapedTags = ['{{{', '}}}'];
/**
* The "regular" / legacy echo string format.
*
* @var string
*/
protected $echoFormat = 'e(%s)';
/**
* Array of footer lines to be added to the template.
*
* @var array
*/
protected $footer = [];
/**
* Array to temporarily store the raw blocks found in the template.
*
* @var array
*/
protected $rawBlocks = [];
/**
* The array of class component aliases and their class names.
*
* @var array
*/
protected $classComponentAliases = [];
/**
* The array of class component namespaces to autoload from.
*
* @var array
*/
protected $classComponentNamespaces = [];
/**
* Indicates if component tags should be compiled.
*
* @var bool
*/
protected $compilesComponentTags = \true;
/**
* Compile the view at the given path.
*
* @param null|string $path
*/
public function compile($path = null)
{
if ($path) {
$this->setPath($path);
}
if (!\is_null($this->cachePath)) {
$contents = $this->compileString($this->files->get($this->getPath()));
if (!empty($this->getPath())) {
$contents = $this->appendFilePath($contents);
}
$this->ensureCompiledDirectoryExists($compiledPath = $this->getCompiledPath($this->getPath()));
$this->files->put($compiledPath, $contents);
}
}
/**
* Get the path currently being compiled.
*
* @return string
*/
public function getPath()
{
return $this->path;
}
/**
* Set the path currently being compiled.
*
* @param string $path
*/
public function setPath($path)
{
$this->path = $path;
}
/**
* Compile the given Blade template contents.
*
* @param string $value
*
* @return string
*/
public function compileString($value)
{
[$this->footer, $result] = [[], ''];
// First we will compile the Blade component tags. This is a precompile style
// step which compiles the component Blade tags into @component directives
// that may be used by Blade. Then we should call any other precompilers.
$value = $this->compileComponentTags($this->compileComments($this->storeUncompiledBlocks($value)));
foreach ($this->precompilers as $precompiler) {
$value = \call_user_func($precompiler, $value);
}
// Here we will loop through all of the tokens returned by the Zend lexer and
// parse each one into the corresponding valid PHP. We will then have this
// template as the correctly rendered PHP that can be rendered natively.
foreach (\token_get_all($value) as $token) {
$result .= \is_array($token) ? $this->parseToken($token) : $token;
}
if (!empty($this->rawBlocks)) {
$result = $this->restoreRawContent($result);
}
// If there are any footer lines that need to get added to a template we will
// add them here at the end of the template. This gets used mainly for the
// template inheritance via the extends keyword that should be appended.
if (\count($this->footer) > 0) {
$result = $this->addFooters($result);
}
if (!empty($this->echoHandlers)) {
$result = $this->addBladeCompilerVariable($result);
}
return \str_replace(['##BEGIN-COMPONENT-CLASS##', '##END-COMPONENT-CLASS##'], '', $result);
}
/**
* Evaluate and render a Blade string to HTML.
*
* @param string $string
* @param array $data
* @param bool $deleteCachedView
*
* @return string
*/
public static function render($string, $data = [], $deleteCachedView = \false)
{
$component = new class($string) extends Component {
protected $template;
public function __construct($template)
{
$this->template = $template;
}
public function render()
{
return $this->template;
}
};
$view = Container::getInstance()->make(ViewFactory::class)->make($component->resolveView(), $data);
return tap($view->render(), function () use ($view, $deleteCachedView) {
if ($deleteCachedView) {
\unlink($view->getPath());
}
});
}
/**
* Render a component instance to HTML.
*
* @return string
*/
public static function renderComponent(Component $component)
{
$data = $component->data();
$view = value($component->resolveView(), $data);
if ($view instanceof View) {
return $view->with($data)->render();
}
if ($view instanceof Htmlable) {
return $view->toHtml();
}
return Container::getInstance()->make(ViewFactory::class)->make($view, $data)->render();
}
/**
* Strip the parentheses from the given expression.
*
* @param string $expression
*
* @return string
*/
public function stripParentheses($expression)
{
if (Str::startsWith($expression, '(')) {
$expression = \substr($expression, 1, -1);
}
return $expression;
}
/**
* Register a custom Blade compiler.
*/
public function extend(callable $compiler)
{
$this->extensions[] = $compiler;
}
/**
* Get the extensions used by the compiler.
*
* @return array
*/
public function getExtensions()
{
return $this->extensions;
}
/**
* Register an "if" statement directive.
*
* @param string $name
*/
public function if($name, callable $callback)
{
$this->conditions[$name] = $callback;
$this->directive($name, function ($expression) use ($name) {
return '' !== $expression ? "<?php if (\\_JchOptimizeVendor\\Illuminate\\Support\\Facades\\Blade::check('{$name}', {$expression})): ?>" : "<?php if (\\_JchOptimizeVendor\\Illuminate\\Support\\Facades\\Blade::check('{$name}')): ?>";
});
$this->directive('unless'.$name, function ($expression) use ($name) {
return '' !== $expression ? "<?php if (! \\_JchOptimizeVendor\\Illuminate\\Support\\Facades\\Blade::check('{$name}', {$expression})): ?>" : "<?php if (! \\_JchOptimizeVendor\\Illuminate\\Support\\Facades\\Blade::check('{$name}')): ?>";
});
$this->directive('else'.$name, function ($expression) use ($name) {
return '' !== $expression ? "<?php elseif (\\_JchOptimizeVendor\\Illuminate\\Support\\Facades\\Blade::check('{$name}', {$expression})): ?>" : "<?php elseif (\\_JchOptimizeVendor\\Illuminate\\Support\\Facades\\Blade::check('{$name}')): ?>";
});
$this->directive('end'.$name, function () {
return '<?php endif; ?>';
});
}
/**
* Check the result of a condition.
*
* @param string $name
* @param array $parameters
*
* @return bool
*/
public function check($name, ...$parameters)
{
return \call_user_func($this->conditions[$name], ...$parameters);
}
/**
* Register a class-based component alias directive.
*
* @param string $class
* @param null|string $alias
* @param string $prefix
*/
public function component($class, $alias = null, $prefix = '')
{
if (!\is_null($alias) && Str::contains($alias, '\\')) {
[$class, $alias] = [$alias, $class];
}
if (\is_null($alias)) {
$alias = Str::contains($class, '\\View\\Components\\') ? collect(\explode('\\', Str::after($class, '\\View\\Components\\')))->map(function ($segment) {
return Str::kebab($segment);
})->implode(':') : Str::kebab(class_basename($class));
}
if (!empty($prefix)) {
$alias = $prefix.'-'.$alias;
}
$this->classComponentAliases[$alias] = $class;
}
/**
* Register an array of class-based components.
*
* @param string $prefix
*/
public function components(array $components, $prefix = '')
{
foreach ($components as $key => $value) {
if (\is_numeric($key)) {
$this->component($value, null, $prefix);
} else {
$this->component($key, $value, $prefix);
}
}
}
/**
* Get the registered class component aliases.
*
* @return array
*/
public function getClassComponentAliases()
{
return $this->classComponentAliases;
}
/**
* Register a class-based component namespace.
*
* @param string $namespace
* @param string $prefix
*/
public function componentNamespace($namespace, $prefix)
{
$this->classComponentNamespaces[$prefix] = $namespace;
}
/**
* Get the registered class component namespaces.
*
* @return array
*/
public function getClassComponentNamespaces()
{
return $this->classComponentNamespaces;
}
/**
* Register a component alias directive.
*
* @param string $path
* @param null|string $alias
*/
public function aliasComponent($path, $alias = null)
{
$alias = $alias ?: Arr::last(\explode('.', $path));
$this->directive($alias, function ($expression) use ($path) {
return $expression ? "<?php \$__env->startComponent('{$path}', {$expression}); ?>" : "<?php \$__env->startComponent('{$path}'); ?>";
});
$this->directive('end'.$alias, function ($expression) {
return '<?php echo $__env->renderComponent(); ?>';
});
}
/**
* Register an include alias directive.
*
* @param string $path
* @param null|string $alias
*/
public function include($path, $alias = null)
{
$this->aliasInclude($path, $alias);
}
/**
* Register an include alias directive.
*
* @param string $path
* @param null|string $alias
*/
public function aliasInclude($path, $alias = null)
{
$alias = $alias ?: Arr::last(\explode('.', $path));
$this->directive($alias, function ($expression) use ($path) {
$expression = $this->stripParentheses($expression) ?: '[]';
return "<?php echo \$__env->make('{$path}', {$expression}, \\_JchOptimizeVendor\\Illuminate\\Support\\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>";
});
}
/**
* Register a handler for custom directives.
*
* @param string $name
*
* @throws \InvalidArgumentException
*/
public function directive($name, callable $handler)
{
if (!\preg_match('/^\\w+(?:::\\w+)?$/x', $name)) {
throw new \InvalidArgumentException("The directive name [{$name}] is not valid. Directive names must only contain alphanumeric characters and underscores.");
}
$this->customDirectives[$name] = $handler;
}
/**
* Get the list of custom directives.
*
* @return array
*/
public function getCustomDirectives()
{
return $this->customDirectives;
}
/**
* Register a new precompiler.
*/
public function precompiler(callable $precompiler)
{
$this->precompilers[] = $precompiler;
}
/**
* Set the echo format to be used by the compiler.
*
* @param string $format
*/
public function setEchoFormat($format)
{
$this->echoFormat = $format;
}
/**
* Set the "echo" format to double encode entities.
*/
public function withDoubleEncoding()
{
$this->setEchoFormat('e(%s, true)');
}
/**
* Set the "echo" format to not double encode entities.
*/
public function withoutDoubleEncoding()
{
$this->setEchoFormat('e(%s, false)');
}
/**
* Indicate that component tags should not be compiled.
*/
public function withoutComponentTags()
{
$this->compilesComponentTags = \false;
}
/**
* Append the file path to the compiled string.
*
* @param string $contents
*
* @return string
*/
protected function appendFilePath($contents)
{
$tokens = $this->getOpenAndClosingPhpTokens($contents);
if ($tokens->isNotEmpty() && \T_CLOSE_TAG !== $tokens->last()) {
$contents .= ' ?>';
}
return $contents."<?php /**PATH {$this->getPath()} ENDPATH**/ ?>";
}
/**
* Get the open and closing PHP tag tokens from the given string.
*
* @param string $contents
*
* @return \_JchOptimizeVendor\Illuminate\Support\Collection
*/
protected function getOpenAndClosingPhpTokens($contents)
{
return collect(\token_get_all($contents))->pluck(0)->filter(function ($token) {
return \in_array($token, [\T_OPEN_TAG, \T_OPEN_TAG_WITH_ECHO, \T_CLOSE_TAG]);
});
}
/**
* Store the blocks that do not receive compilation.
*
* @param string $value
*
* @return string
*/
protected function storeUncompiledBlocks($value)
{
if (\false !== \strpos($value, '@verbatim')) {
$value = $this->storeVerbatimBlocks($value);
}
if (\false !== \strpos($value, '@php')) {
$value = $this->storePhpBlocks($value);
}
return $value;
}
/**
* Store the verbatim blocks and replace them with a temporary placeholder.
*
* @param string $value
*
* @return string
*/
protected function storeVerbatimBlocks($value)
{
return \preg_replace_callback('/(?<!@)@verbatim(.*?)@endverbatim/s', function ($matches) {
return $this->storeRawBlock($matches[1]);
}, $value);
}
/**
* Store the PHP blocks and replace them with a temporary placeholder.
*
* @param string $value
*
* @return string
*/
protected function storePhpBlocks($value)
{
return \preg_replace_callback('/(?<!@)@php(.*?)@endphp/s', function ($matches) {
return $this->storeRawBlock("<?php{$matches[1]}?>");
}, $value);
}
/**
* Store a raw block and return a unique raw placeholder.
*
* @param string $value
*
* @return string
*/
protected function storeRawBlock($value)
{
return $this->getRawPlaceholder(\array_push($this->rawBlocks, $value) - 1);
}
/**
* Compile the component tags.
*
* @param string $value
*
* @return string
*/
protected function compileComponentTags($value)
{
if (!$this->compilesComponentTags) {
return $value;
}
return (new ComponentTagCompiler($this->classComponentAliases, $this->classComponentNamespaces, $this))->compile($value);
}
/**
* Replace the raw placeholders with the original code stored in the raw blocks.
*
* @param string $result
*
* @return string
*/
protected function restoreRawContent($result)
{
$result = \preg_replace_callback('/'.$this->getRawPlaceholder('(\\d+)').'/', function ($matches) {
return $this->rawBlocks[$matches[1]];
}, $result);
$this->rawBlocks = [];
return $result;
}
/**
* Get a placeholder to temporarily mark the position of raw blocks.
*
* @param int|string $replace
*
* @return string
*/
protected function getRawPlaceholder($replace)
{
return \str_replace('#', $replace, '@__raw_block_#__@');
}
/**
* Add the stored footers onto the given content.
*
* @param string $result
*
* @return string
*/
protected function addFooters($result)
{
return \ltrim($result, "\n")."\n".\implode("\n", \array_reverse($this->footer));
}
/**
* Parse the tokens from the template.
*
* @param array $token
*
* @return string
*/
protected function parseToken($token)
{
[$id, $content] = $token;
if (\T_INLINE_HTML == $id) {
foreach ($this->compilers as $type) {
$content = $this->{"compile{$type}"}($content);
}
}
return $content;
}
/**
* Execute the user defined extensions.
*
* @param string $value
*
* @return string
*/
protected function compileExtensions($value)
{
foreach ($this->extensions as $compiler) {
$value = $compiler($value, $this);
}
return $value;
}
/**
* Compile Blade statements that start with "@".
*
* @param string $value
*
* @return string
*/
protected function compileStatements($value)
{
return \preg_replace_callback('/\\B@(@?\\w+(?:::\\w+)?)([ \\t]*)(\\( ( (?>[^()]+) | (?3) )* \\))?/x', function ($match) {
return $this->compileStatement($match);
}, $value);
}
/**
* Compile a single Blade @ statement.
*
* @param array $match
*
* @return string
*/
protected function compileStatement($match)
{
if (Str::contains($match[1], '@')) {
$match[0] = isset($match[3]) ? $match[1].$match[3] : $match[1];
} elseif (isset($this->customDirectives[$match[1]])) {
$match[0] = $this->callCustomDirective($match[1], Arr::get($match, 3));
} elseif (\method_exists($this, $method = 'compile'.\ucfirst($match[1]))) {
$match[0] = $this->{$method}(Arr::get($match, 3));
}
return isset($match[3]) ? $match[0] : $match[0].$match[2];
}
/**
* Call the given directive with the given value.
*
* @param string $name
* @param null|string $value
*
* @return string
*/
protected function callCustomDirective($name, $value)
{
$value = $value ?? '';
if (Str::startsWith($value, '(') && Str::endsWith($value, ')')) {
$value = Str::substr($value, 1, -1);
}
return \call_user_func($this->customDirectives[$name], \trim($value));
}
}

Some files were not shown because too many files have changed in this diff Show More