ALPHA 3.0.2a

This commit is contained in:
TheGamecraft
2018-09-10 08:51:18 -04:00
parent 7fe13ae0a7
commit 0e0ef86b71
1404 changed files with 10604 additions and 33714 deletions

View File

@@ -41,9 +41,11 @@
<div class="form-group row">
<div class="col-md-6 offset-md-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> {{ __('Remember Me') }}
<div class="form-check">
<input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="form-check-label" for="remember">
{{ __('Remember Me') }}
</label>
</div>
</div>

View File

@@ -15,7 +15,7 @@
<!-- Fonts -->
<link rel="dns-prefetch" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Raleway:300,400,600" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">

View File

@@ -21,7 +21,7 @@ class Recaller
*/
public function __construct($recaller)
{
$this->recaller = $recaller;
$this->recaller = @unserialize($recaller, ['allowed_classes' => false]) ?: $recaller;
}
/**

View File

@@ -128,10 +128,8 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
// First we will try to load the user using the identifier in the session if
// one exists. Otherwise we will check for a "remember me" cookie in this
// request, and if one exists, attempt to retrieve the user using that.
if (! is_null($id)) {
if ($this->user = $this->provider->retrieveById($id)) {
$this->fireAuthenticatedEvent($this->user);
}
if (! is_null($id) && $this->user = $this->provider->retrieveById($id)) {
$this->fireAuthenticatedEvent($this->user);
}
// If the user is null, but we decrypt a "recaller" cookie we can attempt to
@@ -541,7 +539,7 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
*
* @param string $password
* @param string $attribute
* @return null|bool
* @return bool|null
*/
public function logoutOtherDevices($password, $attribute = 'password')
{
@@ -549,9 +547,13 @@ class SessionGuard implements StatefulGuard, SupportsBasicAuth
return;
}
return tap($this->user()->forceFill([
$result = tap($this->user()->forceFill([
$attribute => Hash::make($password),
]))->save();
$this->queueRecallerCookie($this->user());
return $result;
}
/**

View File

@@ -172,7 +172,7 @@ class Repository implements CacheContract, ArrayAccess
*/
public function pull($key, $default = null)
{
return tap($this->get($key, $default), function ($value) use ($key) {
return tap($this->get($key, $default), function () use ($key) {
$this->forget($key);
});
}
@@ -419,7 +419,7 @@ class Repository implements CacheContract, ArrayAccess
throw new BadMethodCallException('This cache store does not support tagging.');
}
$cache = $this->store->tags($names);
$cache = $this->store->tags(is_array($names) ? $names : func_get_args());
if (! is_null($this->events)) {
$cache->setEventDispatcher($this->events);

View File

@@ -166,6 +166,8 @@ class Application extends SymfonyApplication implements ApplicationContract
* @param array $parameters
* @param \Symfony\Component\Console\Output\OutputInterface|null $outputBuffer
* @return int
*
* @throws \Symfony\Component\Console\Exception\CommandNotFoundException
*/
public function call($command, array $parameters = [], $outputBuffer = null)
{

View File

@@ -130,13 +130,8 @@ class Command extends SymfonyCommand
// After parsing the signature we will spin through the arguments and options
// and set them on this command. These will already be changed into proper
// instances of these "InputArgument" and "InputOption" Symfony classes.
foreach ($arguments as $argument) {
$this->getDefinition()->addArgument($argument);
}
foreach ($options as $option) {
$this->getDefinition()->addOption($option);
}
$this->getDefinition()->addArguments($arguments);
$this->getDefinition()->addOptions($options);
}
/**
@@ -246,7 +241,7 @@ class Command extends SymfonyCommand
* Get the value of a command argument.
*
* @param string|null $key
* @return string|array
* @return string|array|null
*/
public function argument($key = null)
{
@@ -282,7 +277,7 @@ class Command extends SymfonyCommand
* Get the value of a command option.
*
* @param string|null $key
* @return string|array
* @return string|array|null
*/
public function option($key = null)
{
@@ -320,7 +315,7 @@ class Command extends SymfonyCommand
*
* @param string $question
* @param string|null $default
* @return string
* @return mixed
*/
public function ask($question, $default = null)
{
@@ -333,7 +328,7 @@ class Command extends SymfonyCommand
* @param string $question
* @param array $choices
* @param string|null $default
* @return string
* @return mixed
*/
public function anticipate($question, array $choices, $default = null)
{
@@ -346,7 +341,7 @@ class Command extends SymfonyCommand
* @param string $question
* @param array $choices
* @param string|null $default
* @return string
* @return mixed
*/
public function askWithCompletion($question, array $choices, $default = null)
{
@@ -362,7 +357,7 @@ class Command extends SymfonyCommand
*
* @param string $question
* @param bool $fallback
* @return string
* @return mixed
*/
public function secret($question, $fallback = true)
{
@@ -422,7 +417,7 @@ class Command extends SymfonyCommand
* Write a string as information output.
*
* @param string $string
* @param null|int|string $verbosity
* @param int|string|null $verbosity
* @return void
*/
public function info($string, $verbosity = null)
@@ -435,7 +430,7 @@ class Command extends SymfonyCommand
*
* @param string $string
* @param string $style
* @param null|int|string $verbosity
* @param int|string|null $verbosity
* @return void
*/
public function line($string, $style = null, $verbosity = null)
@@ -449,7 +444,7 @@ class Command extends SymfonyCommand
* Write a string as comment output.
*
* @param string $string
* @param null|int|string $verbosity
* @param int|string|null $verbosity
* @return void
*/
public function comment($string, $verbosity = null)
@@ -461,7 +456,7 @@ class Command extends SymfonyCommand
* Write a string as question output.
*
* @param string $string
* @param null|int|string $verbosity
* @param int|string|null $verbosity
* @return void
*/
public function question($string, $verbosity = null)
@@ -473,7 +468,7 @@ class Command extends SymfonyCommand
* Write a string as error output.
*
* @param string $string
* @param null|int|string $verbosity
* @param int|string|null $verbosity
* @return void
*/
public function error($string, $verbosity = null)
@@ -485,7 +480,7 @@ class Command extends SymfonyCommand
* Write a string as warning output.
*
* @param string $string
* @param null|int|string $verbosity
* @param int|string|null $verbosity
* @return void
*/
public function warn($string, $verbosity = null)

View File

@@ -35,6 +35,8 @@ class Parser
*
* @param string $expression
* @return string
*
* @throws \InvalidArgumentException
*/
protected static function name($expression)
{

View File

@@ -23,7 +23,7 @@ interface Validator extends MessageProvider
/**
* Add conditions to a given field based on a Closure.
*
* @param string $attribute
* @param string|array $attribute
* @param string|array $rules
* @param callable $callback
* @return $this

View File

@@ -25,6 +25,13 @@ class EncryptCookies
*/
protected $except = [];
/**
* Indicates if cookies should be serialized.
*
* @var bool
*/
protected static $serialize = false;
/**
* Create a new CookieGuard instance.
*
@@ -73,7 +80,7 @@ class EncryptCookies
}
try {
$request->cookies->set($key, $this->decryptCookie($cookie));
$request->cookies->set($key, $this->decryptCookie($key, $cookie));
} catch (DecryptException $e) {
$request->cookies->set($key, null);
}
@@ -85,14 +92,15 @@ class EncryptCookies
/**
* Decrypt the given cookie and return the value.
*
* @param string $name
* @param string|array $cookie
* @return string|array
*/
protected function decryptCookie($cookie)
protected function decryptCookie($name, $cookie)
{
return is_array($cookie)
? $this->decryptArray($cookie)
: $this->encrypter->decrypt($cookie);
: $this->encrypter->decrypt($cookie, static::serialized($name));
}
/**
@@ -107,7 +115,7 @@ class EncryptCookies
foreach ($cookie as $key => $value) {
if (is_string($value)) {
$decrypted[$key] = $this->encrypter->decrypt($value);
$decrypted[$key] = $this->encrypter->decrypt($value, static::serialized($key));
}
}
@@ -128,7 +136,7 @@ class EncryptCookies
}
$response->headers->setCookie($this->duplicate(
$cookie, $this->encrypter->encrypt($cookie->getValue())
$cookie, $this->encrypter->encrypt($cookie->getValue(), static::serialized($cookie->getName()))
));
}
@@ -161,4 +169,15 @@ class EncryptCookies
{
return in_array($name, $this->except);
}
/**
* Determine if the cookie contents should be serialized.
*
* @param string $name
* @return bool
*/
public static function serialized($name)
{
return static::$serialize;
}
}

View File

@@ -83,7 +83,7 @@ trait BuildsQueries
* @param mixed $value
* @param callable $callback
* @param callable $default
* @return mixed
* @return mixed|$this
*/
public function when($value, $callback, $default = null)
{
@@ -113,7 +113,7 @@ trait BuildsQueries
* @param mixed $value
* @param callable $callback
* @param callable $default
* @return mixed
* @return mixed|$this
*/
public function unless($value, $callback, $default = null)
{

View File

@@ -26,7 +26,7 @@ trait ManagesTransactions
// catch any exception we can rollback this transaction so that none of this
// gets actually persisted to a database or stored in a permanent fashion.
try {
return tap($callback($this), function ($result) {
return tap($callback($this), function () {
$this->commit();
});
}
@@ -166,6 +166,8 @@ trait ManagesTransactions
*
* @param int|null $toLevel
* @return void
*
* @throws \Exception
*/
public function rollBack($toLevel = null)
{
@@ -183,7 +185,11 @@ trait ManagesTransactions
// Next, we will actually perform this rollback within this database and fire the
// rollback event. We will also set the current transaction level to the given
// level that was passed into this method so it will be right from here out.
$this->performRollBack($toLevel);
try {
$this->performRollBack($toLevel);
} catch (Exception $e) {
$this->handleRollBackException($e);
}
$this->transactions = $toLevel;
@@ -207,6 +213,22 @@ trait ManagesTransactions
}
}
/**
* Handle an exception from a rollback.
*
* @param \Exception $e
*
* @throws \Exception
*/
protected function handleRollBackException($e)
{
if ($this->causedByLostConnection($e)) {
$this->transactions = 0;
}
throw $e;
}
/**
* Get the number of active transactions.
*

View File

@@ -552,7 +552,7 @@ class Connection implements ConnectionInterface
// Now we'll execute this callback and capture the result. Once it has been
// executed we will restore the value of query logging and give back the
// value of hte callback so the original callers can have the results.
// value of the callback so the original callers can have the results.
$result = $callback();
$this->loggingQueries = $loggingQueries;

View File

@@ -11,7 +11,6 @@ use Illuminate\Database\SQLiteConnection;
use Illuminate\Database\PostgresConnection;
use Illuminate\Database\SqlServerConnection;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Debug\ExceptionHandler;
class ConnectionFactory
{
@@ -182,9 +181,7 @@ class ConnectionFactory
try {
return $this->createConnector($config)->connect($config);
} catch (PDOException $e) {
if (count($hosts) - 1 === $key && $this->container->bound(ExceptionHandler::class)) {
$this->container->make(ExceptionHandler::class)->report($e);
}
continue;
}
}

View File

@@ -31,7 +31,7 @@ class SQLiteConnector extends Connector implements ConnectorInterface
// as the developer probably wants to know if the database exists and this
// SQLite driver will not throw any exception if it does not by default.
if ($path === false) {
throw new InvalidArgumentException("Database (${config['database']}) does not exist.");
throw new InvalidArgumentException("Database ({$config['database']}) does not exist.");
}
return $this->createConnection("sqlite:{$path}", $config, $options);

View File

@@ -50,6 +50,7 @@ class FreshCommand extends Command
$this->call('migrate', [
'--database' => $database,
'--path' => $this->input->getOption('path'),
'--realpath' => $this->input->getOption('realpath'),
'--force' => true,
]);

View File

@@ -84,11 +84,7 @@ class MigrateMakeCommand extends BaseCommand
// "create" in the name. This will allow us to provide a convenient way
// of creating migrations that create new tables for the application.
if (! $table) {
if (preg_match('/^create_(\w+)_table$/', $name, $matches)) {
$table = $matches[1];
$create = true;
}
[$table, $create] = TableGuesser::guess($name);
}
// Now we are ready to write the migration out to disk. Once we've written

View File

@@ -61,6 +61,7 @@ class RefreshCommand extends Command
$this->call('migrate', [
'--database' => $database,
'--path' => $path,
'--realpath' => $this->input->getOption('realpath'),
'--force' => $force,
]);
@@ -83,6 +84,7 @@ class RefreshCommand extends Command
$this->call('migrate:rollback', [
'--database' => $database,
'--path' => $path,
'--realpath' => $this->input->getOption('realpath'),
'--step' => $step,
'--force' => $force,
]);
@@ -101,6 +103,7 @@ class RefreshCommand extends Command
$this->call('migrate:reset', [
'--database' => $database,
'--path' => $path,
'--realpath' => $this->input->getOption('realpath'),
'--force' => $force,
]);
}

View File

@@ -34,6 +34,7 @@ trait DetectsLostConnections
'reset by peer',
'Physical connection is not usable',
'TCP Provider: Error code 0x68',
'Name or service not known',
]);
}
}

View File

@@ -68,7 +68,7 @@ class Builder
*/
protected $passthru = [
'insert', 'insertGetId', 'getBindings', 'toSql',
'exists', 'doesntExist', 'count', 'min', 'max', 'avg', 'sum', 'getConnection',
'exists', 'doesntExist', 'count', 'min', 'max', 'avg', 'average', 'sum', 'getConnection',
];
/**
@@ -152,12 +152,12 @@ class Builder
*/
public function withoutGlobalScopes(array $scopes = null)
{
if (is_array($scopes)) {
foreach ($scopes as $scope) {
$this->withoutGlobalScope($scope);
}
} else {
$this->scopes = [];
if (! is_array($scopes)) {
$scopes = array_keys($this->scopes);
}
foreach ($scopes as $scope) {
$this->withoutGlobalScope($scope);
}
return $this;
@@ -312,7 +312,7 @@ class Builder
*
* @param mixed $id
* @param array $columns
* @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static|static[]
*
* @throws \Illuminate\Database\Eloquent\ModelNotFoundException
*/
@@ -543,7 +543,7 @@ class Builder
// and error prone. We don't want constraints because we add eager ones.
$relation = Relation::noConstraints(function () use ($name) {
try {
return $this->getModel()->{$name}();
return $this->getModel()->newInstance()->$name();
} catch (BadMethodCallException $e) {
throw RelationNotFoundException::make($this->getModel(), $name);
}
@@ -612,7 +612,7 @@ class Builder
*
* @param int $count
* @param callable $callback
* @param string $column
* @param string|null $column
* @param string|null $alias
* @return bool
*/

View File

@@ -361,9 +361,7 @@ class Collection extends BaseCollection implements QueueableCollection
*/
public function makeHidden($attributes)
{
return $this->each(function ($model) use ($attributes) {
$model->addHidden($attributes);
});
return $this->each->addHidden($attributes);
}
/**
@@ -374,9 +372,7 @@ class Collection extends BaseCollection implements QueueableCollection
*/
public function makeVisible($attributes)
{
return $this->each(function ($model) use ($attributes) {
$model->makeVisible($attributes);
});
return $this->each->makeVisible($attributes);
}
/**

View File

@@ -495,7 +495,7 @@ trait HasRelationships
}
/**
* Instantiate a new HasManyThrough relationship.
* Instantiate a new MorphToMany relationship.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $parent

View File

@@ -3,9 +3,11 @@
namespace Illuminate\Database\Eloquent\Concerns;
use Closure;
use RuntimeException;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Expression;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Database\Query\Builder as QueryBuilder;
@@ -29,6 +31,10 @@ trait QueriesRelationships
$relation = $this->getRelationWithoutConstraints($relation);
if ($relation instanceof MorphTo) {
throw new RuntimeException('has() and whereHas() do not support MorphTo relationships.');
}
// If we only need to check for the existence of the relation, then we can optimize
// the subquery to only run a "where exists" clause instead of this full "count"
// clause. This will make these queries run much faster compared with a count.

View File

@@ -117,6 +117,17 @@ class FactoryBuilder
return $this;
}
/**
* Set the state to be applied to the model.
*
* @param string $state
* @return $this
*/
public function state($state)
{
return $this->states([$state]);
}
/**
* Set the states to be applied to the model.
*

View File

@@ -746,7 +746,7 @@ abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializab
// If the model has an incrementing key, we can use the "insertGetId" method on
// the query builder, which will give us back the final inserted ID for this
// table from the database. Not all tables have to be incrementing though.
$attributes = $this->attributes;
$attributes = $this->getAttributes();
if ($this->getIncrementing()) {
$this->insertAndSetId($query, $attributes);

View File

@@ -274,7 +274,7 @@ class BelongsTo extends Relation
$query->getModel()->setTable($hash);
return $query->whereColumn(
$hash.'.'.$query->getModel()->getKeyName(), '=', $this->getQualifiedForeignKey()
$hash.'.'.$this->ownerKey, '=', $this->getQualifiedForeignKey()
);
}

View File

@@ -288,7 +288,7 @@ class BelongsToMany extends Relation
* Specify the custom pivot model to use for the relationship.
*
* @param string $class
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
* @return $this
*/
public function using($class)
{
@@ -301,7 +301,7 @@ class BelongsToMany extends Relation
* Specify the custom pivot accessor to use for the relationship.
*
* @param string $accessor
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
* @return $this
*/
public function as($accessor)
{
@@ -317,7 +317,7 @@ class BelongsToMany extends Relation
* @param string $operator
* @param mixed $value
* @param string $boolean
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
* @return $this
*/
public function wherePivot($column, $operator = null, $value = null, $boolean = 'and')
{
@@ -333,7 +333,7 @@ class BelongsToMany extends Relation
* @param mixed $values
* @param string $boolean
* @param bool $not
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
* @return $this
*/
public function wherePivotIn($column, $values, $boolean = 'and', $not = false)
{
@@ -348,7 +348,7 @@ class BelongsToMany extends Relation
* @param string $column
* @param string $operator
* @param mixed $value
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
* @return $this
*/
public function orWherePivot($column, $operator = null, $value = null)
{
@@ -362,7 +362,7 @@ class BelongsToMany extends Relation
*
* @param string $column
* @param mixed $value
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
* @return $this
*/
public function withPivotValue($column, $value = null)
{
@@ -388,7 +388,7 @@ class BelongsToMany extends Relation
*
* @param string $column
* @param mixed $values
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
* @return $this
*/
public function orWherePivotIn($column, $values)
{
@@ -568,10 +568,10 @@ class BelongsToMany extends Relation
// First we'll add the proper select columns onto the query so it is run with
// the proper columns. Then, we will get the results and hydrate out pivot
// models with the result of those columns as a separate model relation.
$columns = $this->query->getQuery()->columns ? [] : $columns;
$builder = $this->query->applyScopes();
$columns = $builder->getQuery()->columns ? [] : $columns;
$models = $builder->addSelect(
$this->shouldSelect($columns)
)->getModels();
@@ -592,7 +592,7 @@ class BelongsToMany extends Relation
* Get the select columns for the relation query.
*
* @param array $columns
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
* @return array
*/
protected function shouldSelect(array $columns = ['*'])
{
@@ -796,7 +796,7 @@ class BelongsToMany extends Relation
{
$model->save(['touch' => false]);
$this->attach($model->getKey(), $pivotAttributes, $touch);
$this->attach($model, $pivotAttributes, $touch);
return $model;
}
@@ -836,7 +836,7 @@ class BelongsToMany extends Relation
// accomplish this which will insert the record and any more attributes.
$instance->save(['touch' => false]);
$this->attach($instance->getKey(), $joining, $touch);
$this->attach($instance, $joining, $touch);
return $instance;
}
@@ -926,7 +926,7 @@ class BelongsToMany extends Relation
*
* @param mixed $createdAt
* @param mixed $updatedAt
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
* @return $this
*/
public function withTimestamps($createdAt = null, $updatedAt = null)
{

View File

@@ -474,11 +474,11 @@ trait InteractsWithPivotTable
protected function parseIds($value)
{
if ($value instanceof Model) {
return [$value->getKey()];
return [$value->{$this->relatedKey}];
}
if ($value instanceof Collection) {
return $value->modelKeys();
return $value->pluck($this->relatedKey)->all();
}
if ($value instanceof BaseCollection) {
@@ -496,7 +496,7 @@ trait InteractsWithPivotTable
*/
protected function parseId($value)
{
return $value instanceof Model ? $value->getKey() : $value;
return $value instanceof Model ? $value->{$this->relatedKey} : $value;
}
/**

View File

@@ -135,9 +135,7 @@ class HasManyThrough extends Relation
*/
public function throughParentSoftDeletes()
{
return in_array(SoftDeletes::class, class_uses_recursive(
get_class($this->throughParent)
));
return in_array(SoftDeletes::class, class_uses_recursive($this->throughParent));
}
/**
@@ -427,6 +425,16 @@ class HasManyThrough extends Relation
return $this->prepareQueryBuilder()->chunk($count, $callback);
}
/**
* Get a generator for the given query.
*
* @return \Generator
*/
public function cursor()
{
return $this->prepareQueryBuilder()->cursor();
}
/**
* Execute a callback over each item while chunking.
*
@@ -453,8 +461,10 @@ class HasManyThrough extends Relation
*/
protected function prepareQueryBuilder($columns = ['*'])
{
return $this->query->applyScopes()->addSelect(
$this->shouldSelect($this->query->getQuery()->columns ? [] : $columns)
$builder = $this->query->applyScopes();
return $builder->addSelect(
$this->shouldSelect($builder->getQuery()->columns ? [] : $columns)
);
}
@@ -500,7 +510,7 @@ class HasManyThrough extends Relation
$query->getModel()->setTable($hash);
return $query->select($columns)->whereColumn(
$parentQuery->getQuery()->from.'.'.$query->getModel()->getKeyName(), '=', $this->getQualifiedFirstKeyName()
$parentQuery->getQuery()->from.'.'.$this->localKey, '=', $this->getQualifiedFirstKeyName()
);
}

View File

@@ -223,6 +223,36 @@ class MorphTo extends BelongsTo
return $this->parent->setRelation($this->relation, null);
}
/**
* Touch all of the related models for the relationship.
*
* @return void
*/
public function touch()
{
if (! is_null($this->ownerKey)) {
parent::touch();
}
}
/**
* Remove all or passed registered global scopes.
*
* @param array|null $scopes
* @return $this
*/
public function withoutGlobalScopes(array $scopes = null)
{
$this->getQuery()->withoutGlobalScopes($scopes);
$this->macroBuffer[] = [
'method' => __FUNCTION__,
'parameters' => [$scopes],
];
return $this;
}
/**
* Get the foreign key "type" name.
*

View File

@@ -223,7 +223,7 @@ abstract class Relation
{
return collect($models)->map(function ($value) use ($key) {
return $key ? $value->getAttribute($key) : $value->getKey();
})->values()->unique()->sort()->all();
})->values()->unique(null, true)->sort()->all();
}
/**

View File

@@ -76,9 +76,7 @@ trait SoftDeletes
$columns[$this->getUpdatedAtColumn()] = $this->fromDateTime($time);
}
if ($query->update($columns)) {
$this->syncOriginal();
}
$query->update($columns);
}
/**

View File

@@ -58,7 +58,7 @@ abstract class Grammar
// If the value being wrapped has a column alias we will need to separate out
// the pieces so we can wrap each of the segments of the expression on its
// own, and then join these both back together using the "as" connector.
if (strpos(strtolower($value), ' as ') !== false) {
if (stripos($value, ' as ') !== false) {
return $this->wrapAliasedValue($value, $prefixAlias);
}

View File

@@ -480,6 +480,16 @@ class Migrator
return $this->paths;
}
/**
* Get the default connection name.
*
* @return string
*/
public function getConnection()
{
return $this->connection;
}
/**
* Set the default connection name.
*

View File

@@ -319,7 +319,7 @@ class Builder
*/
protected function parseSub($query)
{
if ($query instanceof self) {
if ($query instanceof self || $query instanceof EloquentBuilder) {
return [$query->toSql(), $query->getBindings()];
} elseif (is_string($query)) {
return [$query, []];
@@ -1389,7 +1389,7 @@ class Builder
{
$type = $not ? 'NotExists' : 'Exists';
$this->wheres[] = compact('type', 'operator', 'query', 'boolean');
$this->wheres[] = compact('type', 'query', 'boolean');
$this->addBinding($query->getBindings(), 'where');
@@ -1415,7 +1415,7 @@ class Builder
$this->wheres[] = compact('type', 'columns', 'operator', 'values', 'boolean');
$this->addBinding($values);
$this->addBinding($this->cleanBindings($values));
return $this;
}
@@ -2057,7 +2057,7 @@ class Builder
protected function withoutSelectAliases(array $columns)
{
return array_map(function ($column) {
return is_string($column) && ($aliasPosition = strpos(strtolower($column), ' as ')) !== false
return is_string($column) && ($aliasPosition = stripos($column, ' as ')) !== false
? substr($column, 0, $aliasPosition) : $column;
}, $columns);
}
@@ -2084,7 +2084,7 @@ class Builder
* @param int $count
* @param callable $callback
* @param string $column
* @param string $alias
* @param string|null $alias
* @return bool
*/
public function chunkById($count, callable $callback, $column = 'id', $alias = null)

View File

@@ -490,9 +490,11 @@ class Grammar extends BaseGrammar
*/
protected function whereRowValues(Builder $query, $where)
{
$columns = $this->columnize($where['columns']);
$values = $this->parameterize($where['values']);
return '('.implode(', ', $where['columns']).') '.$where['operator'].' ('.$values.')';
return '('.$columns.') '.$where['operator'].' ('.$values.')';
}
/**
@@ -905,7 +907,7 @@ class Grammar extends BaseGrammar
// If the value being wrapped has a column alias we will need to separate out
// the pieces so we can wrap each of the segments of the expression on its
// own, and then join these both back together using the "as" connector.
if (strpos(strtolower($value), ' as ') !== false) {
if (stripos($value, ' as ') !== false) {
return $this->wrapAliasedValue($value, $prefixAlias);
}
@@ -930,6 +932,17 @@ class Grammar extends BaseGrammar
throw new RuntimeException('This database engine does not support JSON operations.');
}
/**
* Wrap the given JSON path.
*
* @param string $value
* @return string
*/
protected function wrapJsonPath($value)
{
return '\'$."'.str_replace('->', '"."', $value).'"\'';
}
/**
* Determine if the given string is a JSON selector.
*

View File

@@ -276,7 +276,7 @@ class MySqlGrammar extends Grammar
{
$joins = ' '.$this->compileJoins($query, $query->joins);
$alias = strpos(strtolower($table), ' as ') !== false
$alias = stripos($table, ' as ') !== false
? explode(' as ', $table)[1] : $table;
return trim("delete {$alias} from {$table}{$joins} {$where}");
@@ -301,11 +301,15 @@ class MySqlGrammar extends Grammar
*/
protected function wrapJsonSelector($value)
{
$path = explode('->', $value);
$delimiter = str_contains($value, '->>')
? '->>'
: '->';
$path = explode($delimiter, $value);
$field = $this->wrapSegments(explode('.', array_shift($path)));
return sprintf('%s->\'$.%s\'', $field, collect($path)->map(function ($part) {
return sprintf('%s'.$delimiter.'\'$.%s\'', $field, collect($path)->map(function ($part) {
return '"'.$part.'"';
})->implode('.'));
}

View File

@@ -273,4 +273,23 @@ class SQLiteGrammar extends Grammar
'delete from '.$this->wrapTable($query->from) => [],
];
}
/**
* Wrap the given JSON selector.
*
* @param string $value
* @return string
*/
protected function wrapJsonSelector($value)
{
$parts = explode('->', $value, 2);
$field = $this->wrap($parts[0]);
$path = count($parts) > 1 ? ', '.$this->wrapJsonPath($parts[1]) : '';
$selector = 'json_extract('.$field.$path.')';
return $selector;
}
}

View File

@@ -103,6 +103,20 @@ class SqlServerGrammar extends Grammar
return 'cast('.$this->wrap($where['column']).' as date) '.$where['operator'].' '.$value;
}
/**
* Compile a "where time" clause.
*
* @param \Illuminate\Database\Query\Builder $query
* @param array $where
* @return string
*/
protected function whereTime(Builder $query, $where)
{
$value = $this->parameter($where['value']);
return 'cast('.$this->wrap($where['column']).' as time) '.$where['operator'].' '.$value;
}
/**
* Compile a "JSON contains" statement into SQL.
*
@@ -185,7 +199,7 @@ class SqlServerGrammar extends Grammar
{
$constraint = $this->compileRowConstraint($query);
return "select * from ({$sql}) as temp_table where row_num {$constraint}";
return "select * from ({$sql}) as temp_table where row_num {$constraint} order by row_num";
}
/**
@@ -298,7 +312,7 @@ class SqlServerGrammar extends Grammar
{
$joins = ' '.$this->compileJoins($query, $query->joins);
$alias = strpos(strtolower($table), ' as ') !== false
$alias = stripos($table, ' as ') !== false
? explode(' as ', $table)[1] : $table;
return trim("delete {$alias} from {$table}{$joins} {$where}");
@@ -364,7 +378,7 @@ class SqlServerGrammar extends Grammar
{
$table = $alias = $this->wrapTable($table);
if (strpos(strtolower($table), '] as [') !== false) {
if (stripos($table, '] as [') !== false) {
$alias = '['.explode('] as [', $table)[1];
}
@@ -458,17 +472,6 @@ class SqlServerGrammar extends Grammar
return 'json_value('.$field.', '.$this->wrapJsonPath($parts[0]).')';
}
/**
* Wrap the given JSON path.
*
* @param string $value
* @return string
*/
protected function wrapJsonPath($value)
{
return '\'$."'.str_replace('->', '"."', $value).'"\'';
}
/**
* Wrap a table in keyword identifiers.
*

View File

@@ -1062,7 +1062,7 @@ class Blueprint
* Create a new point column on the table.
*
* @param string $column
* @param null|int $srid
* @param int|null $srid
* @return \Illuminate\Support\Fluent
*/
public function point($column, $srid = null)

View File

@@ -69,7 +69,7 @@ class Builder
{
$table = $this->connection->getTablePrefix().$table;
return count($this->connection->select(
return count($this->connection->selectFromWriteConnection(
$this->grammar->compileTableExists(), [$table]
)) > 0;
}
@@ -130,7 +130,7 @@ class Builder
*/
public function getColumnListing($table)
{
$results = $this->connection->select($this->grammar->compileColumnListing(
$results = $this->connection->selectFromWriteConnection($this->grammar->compileColumnListing(
$this->connection->getTablePrefix().$table
));

View File

@@ -96,7 +96,7 @@ class CallQueuedListener implements ShouldQueue
*/
protected function setJobInstanceIfNecessary(Job $job, $instance)
{
if (in_array(InteractsWithQueue::class, class_uses_recursive(get_class($instance)))) {
if (in_array(InteractsWithQueue::class, class_uses_recursive($instance))) {
$instance->setJob($job);
}

View File

@@ -452,10 +452,8 @@ class Filesystem
*/
public function moveDirectory($from, $to, $overwrite = false)
{
if ($overwrite && $this->isDirectory($to)) {
if (! $this->deleteDirectory($to)) {
return false;
}
if ($overwrite && $this->isDirectory($to) && ! $this->deleteDirectory($to)) {
return false;
}
return @rename($from, $to) === true;
@@ -553,6 +551,27 @@ class Filesystem
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.
*

View File

@@ -204,7 +204,7 @@ class FilesystemAdapter implements FilesystemContract, CloudFilesystemContract
*/
public function putFileAs($path, $file, $name, $options = [])
{
$stream = fopen($file->getRealPath(), 'r+');
$stream = fopen($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

View File

@@ -220,7 +220,7 @@ class FilesystemManager implements FactoryContract
$config += ['version' => 'latest'];
if ($config['key'] && $config['secret']) {
$config['credentials'] = Arr::only($config, ['key', 'secret']);
$config['credentials'] = Arr::only($config, ['key', 'secret', 'token']);
}
return $config;
@@ -236,7 +236,7 @@ class FilesystemManager implements FactoryContract
{
$client = new Rackspace($config['endpoint'], [
'username' => $config['username'], 'apiKey' => $config['key'],
]);
], $config['options'] ?? []);
$root = $config['root'] ?? null;

View File

@@ -29,7 +29,7 @@ class Application extends Container implements ApplicationContract, HttpKernelIn
*
* @var string
*/
const VERSION = '5.6.26';
const VERSION = '5.6.38';
/**
* The base path for the Laravel installation.

View File

@@ -116,7 +116,7 @@ trait AuthenticatesUsers
*/
protected function authenticated(Request $request, $user)
{
$user->updateAPI();
//
}
/**
@@ -156,7 +156,18 @@ trait AuthenticatesUsers
$request->session()->invalidate();
return redirect('/');
return $this->loggedOut($request) ?: redirect('/');
}
/**
* The user has logged out of the application.
*
* @param \Illuminate\Http\Request $request
* @return mixed
*/
protected function loggedOut(Request $request)
{
//
}
/**

View File

@@ -70,9 +70,9 @@ trait SendsPasswordResetEmails
*/
protected function sendResetLinkFailedResponse(Request $request, $response)
{
return back()->withErrors(
['email' => trans($response)]
);
return back()
->withInput($request->only('email'))
->withErrors(['email' => trans($response)]);
}
/**

View File

@@ -2,6 +2,8 @@
namespace Illuminate\Foundation\Console;
use Throwable;
use LogicException;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Contracts\Console\Kernel as ConsoleKernelContract;
@@ -52,11 +54,20 @@ class ConfigCacheCommand extends Command
$this->call('config:clear');
$config = $this->getFreshConfiguration();
$configPath = $this->laravel->getCachedConfigPath();
$this->files->put(
$this->laravel->getCachedConfigPath(), '<?php return '.var_export($config, true).';'.PHP_EOL
$configPath, '<?php return '.var_export($config, true).';'.PHP_EOL
);
try {
require $configPath;
} catch (Throwable $e) {
$this->files->delete($configPath);
throw new LogicException('Your configuration files are not serializable.', 0, $e);
}
$this->info('Configuration cached successfully!');
}

View File

@@ -84,6 +84,10 @@ class ModelMakeCommand extends GeneratorCommand
{
$table = Str::plural(Str::snake(class_basename($this->argument('name'))));
if ($this->option('pivot')) {
$table = Str::singular($table);
}
$this->call('make:migration', [
'name' => "create_{$table}_table",
'--create' => $table,

View File

@@ -1,8 +1,20 @@
// Body
$body-bg: #f5f8fa;
$body-bg: #f8fafc;
// Typography
$font-family-sans-serif: "Raleway", sans-serif;
$font-family-sans-serif: "Nunito", sans-serif;
$font-size-base: 0.9rem;
$line-height-base: 1.6;
// Colors
$blue: #3490dc;
$indigo: #6574cd;
$purple: #9561e2;
$pink: #f66D9b;
$red: #e3342f;
$orange: #f6993f;
$yellow: #ffed4a;
$green: #38c172;
$teal: #4dc0b5;
$cyan: #6cb2eb;

View File

@@ -1,9 +1,9 @@
// Fonts
@import url("https://fonts.googleapis.com/css?family=Raleway:300,400,600");
@import url('https://fonts.googleapis.com/css?family=Nunito');
// Variables
@import "variables";
@import 'variables';
// Bootstrap
@import '~bootstrap/scss/bootstrap';

View File

@@ -46,6 +46,8 @@ class ViewClearCommand extends Command
* Execute the console command.
*
* @return void
*
* @throws \RuntimeException
*/
public function handle()
{

View File

@@ -7,7 +7,7 @@ use NamespacedDummyModel;
class DummyClass
{
/**
* Handle to the DocDummyModel "created" event.
* Handle the DocDummyModel "created" event.
*
* @param \NamespacedDummyModel $dummyModel
* @return void
@@ -38,4 +38,26 @@ class DummyClass
{
//
}
/**
* Handle the DocDummyModel "restored" event.
*
* @param \NamespacedDummyModel $dummyModel
* @return void
*/
public function restored(DummyModel $dummyModel)
{
//
}
/**
* Handle the DocDummyModel "force deleted" event.
*
* @param \NamespacedDummyModel $dummyModel
* @return void
*/
public function forceDeleted(DummyModel $dummyModel)
{
//
}
}

View File

@@ -56,4 +56,28 @@ class DummyClass
{
//
}
/**
* Determine whether the user can restore the DocDummyModel.
*
* @param \NamespacedDummyUserModel $user
* @param \NamespacedDummyModel $dummyModel
* @return mixed
*/
public function restore(DummyUser $user, DummyModel $dummyModel)
{
//
}
/**
* Determine whether the user can permanently delete the DocDummyModel.
*
* @param \NamespacedDummyUserModel $user
* @param \NamespacedDummyModel $dummyModel
* @return mixed
*/
public function forceDelete(DummyUser $user, DummyModel $dummyModel)
{
//
}
}

View File

@@ -162,7 +162,7 @@ class Handler implements ExceptionHandlerContract
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Symfony\Component\HttpFoundation\Response
* @return \Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
*/
public function render($request, Exception $e)
{

View File

@@ -8,14 +8,14 @@
<title>@yield('title')</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
<!-- Styles -->
<style>
html, body {
background-color: #fff;
color: #636b6f;
font-family: 'Raleway', sans-serif;
font-family: 'Nunito', sans-serif;
font-weight: 100;
height: 100vh;
margin: 0;

View File

@@ -16,6 +16,13 @@ class CheckForMaintenanceMode
*/
protected $app;
/**
* The URIs that should be accessible while maintenance mode is enabled.
*
* @var array
*/
protected $except = [];
/**
* Create a new middleware instance.
*
@@ -45,9 +52,34 @@ class CheckForMaintenanceMode
return $next($request);
}
if ($this->inExceptArray($request)) {
return $next($request);
}
throw new MaintenanceModeException($data['time'], $data['retry'], $data['message']);
}
return $next($request);
}
/**
* Determine if the request has a URI that should be accessible in maintenance mode.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function inExceptArray($request)
{
foreach ($this->except as $except) {
if ($except !== '/') {
$except = trim($except, '/');
}
if ($request->fullUrlIs($except) || $request->is($except)) {
return true;
}
}
return false;
}
}

View File

@@ -8,6 +8,7 @@ use Illuminate\Support\InteractsWithTime;
use Symfony\Component\HttpFoundation\Cookie;
use Illuminate\Contracts\Encryption\Encrypter;
use Illuminate\Session\TokenMismatchException;
use Illuminate\Cookie\Middleware\EncryptCookies;
class VerifyCsrfToken
{
@@ -138,7 +139,7 @@ class VerifyCsrfToken
$token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN');
if (! $token && $header = $request->header('X-XSRF-TOKEN')) {
$token = $this->encrypter->decrypt($header);
$token = $this->encrypter->decrypt($header, static::serialized());
}
return $token;
@@ -164,4 +165,14 @@ class VerifyCsrfToken
return $response;
}
/**
* Determine if the cookie contents should be serialized.
*
* @return bool
*/
public static function serialized()
{
return EncryptCookies::serialized('XSRF-TOKEN');
}
}

View File

@@ -97,6 +97,8 @@ class PackageManifest
$this->build();
}
$this->files->get($this->manifestPath, true);
return $this->manifest = file_exists($this->manifestPath) ?
$this->files->getRequire($this->manifestPath) : [];
}
@@ -166,7 +168,8 @@ class PackageManifest
}
$this->files->put(
$this->manifestPath, '<?php return '.var_export($manifest, true).';'
$this->manifestPath, '<?php return '.var_export($manifest, true).';',
true
);
}
}

View File

@@ -207,7 +207,7 @@ class ArtisanServiceProvider extends ServiceProvider
*/
protected function registerAuthMakeCommand()
{
$this->app->singleton('command.auth.make', function ($app) {
$this->app->singleton('command.auth.make', function () {
return new AuthMakeCommand;
});
}
@@ -622,7 +622,7 @@ class ArtisanServiceProvider extends ServiceProvider
*/
protected function registerPackageDiscoverCommand()
{
$this->app->singleton('command.package.discover', function ($app) {
$this->app->singleton('command.package.discover', function () {
return new PackageDiscoverCommand;
});
}
@@ -966,7 +966,7 @@ class ArtisanServiceProvider extends ServiceProvider
*/
protected function registerViewCacheCommand()
{
$this->app->singleton('command.view.cache', function ($app) {
$this->app->singleton('command.view.cache', function () {
return new ViewCacheCommand;
});
}

View File

@@ -221,9 +221,10 @@ class TestResponse
* @param string $cookieName
* @param mixed $value
* @param bool $encrypted
* @param bool $unserialize
* @return $this
*/
public function assertCookie($cookieName, $value = null, $encrypted = true)
public function assertCookie($cookieName, $value = null, $encrypted = true, $unserialize = false)
{
PHPUnit::assertNotNull(
$cookie = $this->getCookie($cookieName),
@@ -237,7 +238,7 @@ class TestResponse
$cookieValue = $cookie->getValue();
$actual = $encrypted
? app('encrypter')->decrypt($cookieValue) : $cookieValue;
? app('encrypter')->decrypt($cookieValue, $unserialize) : $cookieValue;
PHPUnit::assertEquals(
$value, $actual,
@@ -466,12 +467,12 @@ class TestResponse
));
foreach (Arr::sortRecursive($data) as $key => $value) {
$expected = substr(json_encode([$key => $value]), 1, -1);
$expected = $this->jsonSearchStrings($key, $value);
PHPUnit::assertTrue(
Str::contains($actual, $expected),
'Unable to find JSON fragment: '.PHP_EOL.PHP_EOL.
"[{$expected}]".PHP_EOL.PHP_EOL.
'['.json_encode([$key => $value]).']'.PHP_EOL.PHP_EOL.
'within'.PHP_EOL.PHP_EOL.
"[{$actual}]."
);
@@ -498,12 +499,12 @@ class TestResponse
));
foreach (Arr::sortRecursive($data) as $key => $value) {
$unexpected = substr(json_encode([$key => $value]), 1, -1);
$unexpected = $this->jsonSearchStrings($key, $value);
PHPUnit::assertFalse(
Str::contains($actual, $unexpected),
'Found unexpected JSON fragment: '.PHP_EOL.PHP_EOL.
"[{$unexpected}]".PHP_EOL.PHP_EOL.
'['.json_encode([$key => $value]).']'.PHP_EOL.PHP_EOL.
'within'.PHP_EOL.PHP_EOL.
"[{$actual}]."
);
@@ -525,7 +526,7 @@ class TestResponse
));
foreach (Arr::sortRecursive($data) as $key => $value) {
$unexpected = substr(json_encode([$key => $value]), 1, -1);
$unexpected = $this->jsonSearchStrings($key, $value);
if (! Str::contains($actual, $unexpected)) {
return $this;
@@ -540,6 +541,24 @@ class TestResponse
);
}
/**
* Get the strings we need to search for when examining the JSON.
*
* @param string $key
* @param string $value
* @return array
*/
protected function jsonSearchStrings($key, $value)
{
$needle = substr(json_encode([$key => $value]), 1, -1);
return [
$needle.']',
$needle.'}',
$needle.',',
];
}
/**
* Assert that the response has a given JSON structure.
*
@@ -550,7 +569,7 @@ class TestResponse
public function assertJsonStructure(array $structure = null, $responseData = null)
{
if (is_null($structure)) {
return $this->assertJson($this->json());
return $this->assertExactJson($this->json());
}
if (is_null($responseData)) {

View File

@@ -372,11 +372,12 @@ if (! function_exists('decrypt')) {
* Decrypt the given value.
*
* @param string $value
* @param bool $unserialize
* @return mixed
*/
function decrypt($value)
function decrypt($value, $unserialize = true)
{
return app('encrypter')->decrypt($value);
return app('encrypter')->decrypt($value, $unserialize);
}
}
@@ -452,11 +453,12 @@ if (! function_exists('encrypt')) {
* Encrypt the given value.
*
* @param mixed $value
* @param bool $serialize
* @return string
*/
function encrypt($value)
function encrypt($value, $serialize = true)
{
return app('encrypter')->encrypt($value);
return app('encrypter')->encrypt($value, $serialize);
}
}
@@ -779,10 +781,10 @@ if (! function_exists('response')) {
/**
* Return a new response from the application.
*
* @param string|array $content
* @param \Illuminate\View\View|string|array|null $content
* @param int $status
* @param array $headers
* @return \Symfony\Component\HttpFoundation\Response|\Illuminate\Contracts\Routing\ResponseFactory
* @return \Illuminate\Http\Response|\Illuminate\Contracts\Routing\ResponseFactory
*/
function response($content = '', $status = 200, array $headers = [])
{

View File

@@ -47,6 +47,8 @@ class ArgonHasher extends AbstractHasher implements HasherContract
* @param string $value
* @param array $options
* @return string
*
* @throws \RuntimeException
*/
public function make($value, array $options = [])
{

View File

@@ -26,7 +26,7 @@ class RedirectResponse extends BaseRedirectResponse
protected $request;
/**
* The session store implementation.
* The session store instance.
*
* @var \Illuminate\Session\Store
*/
@@ -192,7 +192,7 @@ class RedirectResponse extends BaseRedirectResponse
}
/**
* Get the session store implementation.
* Get the session store instance.
*
* @return \Illuminate\Session\Store|null
*/
@@ -202,7 +202,7 @@ class RedirectResponse extends BaseRedirectResponse
}
/**
* Set the session store implementation.
* Set the session store instance.
*
* @param \Illuminate\Session\Store $session
* @return void

View File

@@ -309,6 +309,20 @@ class Request extends SymfonyRequest implements Arrayable, ArrayAccess
return $this;
}
/**
* This method belongs to Symfony HttpFoundation and is not usually needed when using Laravel.
*
* Instead, you may use the "input" method.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
return parent::get($key, $default);
}
/**
* Get the JSON payload for the request.
*

View File

@@ -28,7 +28,7 @@ trait ConditionallyLoadsAttributes
}
if (is_numeric($key) && $value instanceof MergeValue) {
return $this->merge($data, $index, $this->filter($value->data), $numericKeys);
return $this->mergeData($data, $index, $this->filter($value->data), $numericKeys);
}
if ($value instanceof self && is_null($value->resource)) {
@@ -48,7 +48,7 @@ trait ConditionallyLoadsAttributes
* @param bool $numericKeys
* @return array
*/
protected function merge($data, $index, $merge, $numericKeys)
protected function mergeData($data, $index, $merge, $numericKeys)
{
if ($numericKeys) {
return $this->removeMissingValues(array_merge(
@@ -101,12 +101,23 @@ trait ConditionallyLoadsAttributes
return func_num_args() === 3 ? value($default) : new MissingValue;
}
/**
* Merge a value into the array.
*
* @param mixed $value
* @return \Illuminate\Http\Resources\MergeValue|mixed
*/
protected function merge($value)
{
return $this->mergeWhen(true, $value);
}
/**
* Merge a value based on a given condition.
*
* @param bool $condition
* @param mixed $value
* @return \Illuminate\Http\Resources\MissingValue|mixed
* @return \Illuminate\Http\Resources\MergeValue|mixed
*/
protected function mergeWhen($condition, $value)
{
@@ -141,7 +152,7 @@ trait ConditionallyLoadsAttributes
}
if (! $this->resource->relationLoaded($relationship)) {
return $default;
return value($default);
}
if (func_num_args() === 1) {

View File

@@ -60,7 +60,7 @@ class JsonResource implements ArrayAccess, JsonSerializable, Responsable, UrlRou
/**
* Create a new resource instance.
*
* @param dynamic $parameters
* @param mixed $parameters
* @return static
*/
public static function make(...$parameters)
@@ -110,7 +110,9 @@ class JsonResource implements ArrayAccess, JsonSerializable, Responsable, UrlRou
*/
public function toArray($request)
{
return $this->resource->toArray();
return is_array($this->resource)
? $this->resource
: $this->resource->toArray();
}
/**

View File

@@ -2,6 +2,8 @@
namespace Illuminate\Http\Testing;
use Illuminate\Support\Str;
class FileFactory
{
/**
@@ -28,7 +30,9 @@ class FileFactory
*/
public function image($name, $width = 10, $height = 10)
{
return new File($name, $this->generateImage($width, $height));
return new File($name, $this->generateImage(
$width, $height, Str::endsWith(Str::lower($name), ['.jpg', '.jpeg']) ? 'jpeg' : 'png'
));
}
/**
@@ -36,14 +40,24 @@ class FileFactory
*
* @param int $width
* @param int $height
* @param string $type
* @return resource
*/
protected function generateImage($width, $height)
protected function generateImage($width, $height, $type)
{
return tap(tmpfile(), function ($temp) use ($width, $height) {
return tap(tmpfile(), function ($temp) use ($width, $height, $type) {
ob_start();
imagepng(imagecreatetruecolor($width, $height));
$image = imagecreatetruecolor($width, $height);
switch ($type) {
case 'jpeg':
imagejpeg($image);
break;
case 'png':
imagepng($image);
break;
}
fwrite($temp, ob_get_clean());
});

View File

@@ -5,6 +5,7 @@ namespace Illuminate\Http;
use Illuminate\Support\Arr;
use Illuminate\Container\Container;
use Illuminate\Support\Traits\Macroable;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Contracts\Filesystem\Factory as FilesystemFactory;
use Symfony\Component\HttpFoundation\File\UploadedFile as SymfonyUploadedFile;
@@ -86,6 +87,22 @@ class UploadedFile extends SymfonyUploadedFile
);
}
/**
* Get the contents of the uploaded file.
*
* @return bool|string
*
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function get()
{
if (! $this->isValid()) {
throw new FileNotFoundException("File does not exist at path {$this->getPathname()}");
}
return file_get_contents($this->getPathname());
}
/**
* Create a new file instance from a base instance.
*

View File

@@ -157,7 +157,7 @@ class Mailable implements MailableContract, Renderable
*/
public function queue(Queue $queue)
{
if (property_exists($this, 'delay')) {
if (isset($this->delay)) {
return $this->later($this->delay, $queue);
}
@@ -212,7 +212,7 @@ class Mailable implements MailableContract, Renderable
if (isset($this->html)) {
return array_filter([
'html' => new HtmlString($this->html),
'text' => isset($this->textView) ? $this->textView : null,
'text' => $this->textView ?? null,
]);
}

View File

@@ -236,7 +236,7 @@ class Mailer implements MailerContract, MailQueueContract
// message. This is primarily useful during local development in which each
// message should be delivered into a single mail address for inspection.
if (isset($this->to['address'])) {
$this->setGlobalTo($message);
$this->setGlobalToAndRemoveCcAndBcc($message);
}
// Next we will determine if the message should be sent. We give the developer
@@ -347,7 +347,7 @@ class Mailer implements MailerContract, MailQueueContract
* @param \Illuminate\Mail\Message $message
* @return void
*/
protected function setGlobalTo($message)
protected function setGlobalToAndRemoveCcAndBcc($message)
{
$message->to($this->to['address'], $this->to['name'], true);
$message->cc(null, null, true);

View File

@@ -21,7 +21,7 @@
{{-- Footer --}}
@slot('footer')
@component('mail::footer')
&copy; {{ date('Y') }} {{ config('app.name') }}. All rights reserved.
© {{ date('Y') }} {{ config('app.name') }}. @lang('All rights reserved.')
@endcomponent
@endslot
@endcomponent

View File

@@ -21,7 +21,7 @@
{{-- Footer --}}
@slot('footer')
@component('mail::footer')
© {{ date('Y') }} {{ config('app.name') }}. All rights reserved.
© {{ date('Y') }} {{ config('app.name') }}. @lang('All rights reserved.')
@endcomponent
@endslot
@endcomponent

View File

@@ -186,7 +186,7 @@ class MailChannel
return collect($recipients)->mapWithKeys(function ($recipient, $email) {
return is_numeric($email)
? [(is_string($recipient) ? $recipient : $recipient->email)]
? [$email => (is_string($recipient) ? $recipient : $recipient->email)]
: [$email => $recipient];
})->all();
}

View File

@@ -33,7 +33,7 @@ class SlackWebhookChannel
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return \Psr\Http\Message\ResponseInterface
* @return void
*/
public function send($notifiable, Notification $notification)
{

View File

@@ -2,6 +2,9 @@
namespace Illuminate\Notifications\Messages;
use Traversable;
use Illuminate\Contracts\Support\Arrayable;
class MailMessage extends SimpleMessage
{
/**
@@ -144,7 +147,11 @@ class MailMessage extends SimpleMessage
*/
public function replyTo($address, $name = null)
{
$this->replyTo[] = [$address, $name];
if ($this->arrayOfAddresses($address)) {
$this->replyTo += $this->parseAddresses($address);
} else {
$this->replyTo[] = [$address, $name];
}
return $this;
}
@@ -152,13 +159,17 @@ class MailMessage extends SimpleMessage
/**
* Set the cc address for the mail message.
*
* @param string $address
* @param array|string $address
* @param string|null $name
* @return $this
*/
public function cc($address, $name = null)
{
$this->cc[] = [$address, $name];
if ($this->arrayOfAddresses($address)) {
$this->cc += $this->parseAddresses($address);
} else {
$this->cc[] = [$address, $name];
}
return $this;
}
@@ -166,13 +177,17 @@ class MailMessage extends SimpleMessage
/**
* Set the bcc address for the mail message.
*
* @param string $address
* @param array|string $address
* @param string|null $name
* @return $this
*/
public function bcc($address, $name = null)
{
$this->bcc[] = [$address, $name];
if ($this->arrayOfAddresses($address)) {
$this->bcc += $this->parseAddresses($address);
} else {
$this->bcc[] = [$address, $name];
}
return $this;
}
@@ -230,4 +245,30 @@ class MailMessage extends SimpleMessage
{
return array_merge($this->toArray(), $this->viewData);
}
/**
* Parse the multi-address array into the necessary format.
*
* @param array $value
* @return array
*/
protected function parseAddresses($value)
{
return collect($value)->map(function ($address, $name) {
return [$address, is_numeric($name) ? null : $name];
})->values()->all();
}
/**
* Determine if the given "address" is actually an array of addresses.
*
* @param mixed $address
* @return bool
*/
protected function arrayOfAddresses($address)
{
return is_array($address) ||
$address instanceof Arrayable ||
$address instanceof Traversable;
}
}

View File

@@ -25,7 +25,7 @@ class SendQueuedNotifications implements ShouldQueue
public $notification;
/**
* All of the channels to send the notification too.
* All of the channels to send the notification to.
*
* @var array
*/

View File

@@ -85,7 +85,7 @@ class CallQueuedHandler
*/
protected function setJobInstanceIfNecessary(Job $job, $instance)
{
if (in_array(InteractsWithQueue::class, class_uses_recursive(get_class($instance)))) {
if (in_array(InteractsWithQueue::class, class_uses_recursive($instance))) {
$instance->setJob($job);
}

View File

@@ -19,7 +19,7 @@ class SqsConnector implements ConnectorInterface
$config = $this->getDefaultConfiguration($config);
if ($config['key'] && $config['secret']) {
$config['credentials'] = Arr::only($config, ['key', 'secret']);
$config['credentials'] = Arr::only($config, ['key', 'secret', 'token']);
}
return new SqsQueue(

View File

@@ -222,7 +222,7 @@ class Listener
*/
public function memoryExceeded($memoryLimit)
{
return (memory_get_usage() / 1024 / 1024) >= $memoryLimit;
return (memory_get_usage(true) / 1024 / 1024) >= $memoryLimit;
}
/**

View File

@@ -162,7 +162,11 @@ class RedisQueue extends Queue implements QueueContract
{
$this->migrate($prefixed = $this->getQueue($queue));
list($job, $reserved) = $this->retrieveNextJob($prefixed);
if (empty($nextJob = $this->retrieveNextJob($prefixed))) {
return;
}
list($job, $reserved) = $nextJob;
if ($reserved) {
return new RedisJob(

View File

@@ -251,10 +251,14 @@ class Worker
$this->exceptions->report($e);
$this->stopWorkerIfLostConnection($e);
$this->sleep(1);
} catch (Throwable $e) {
$this->exceptions->report($e = new FatalThrowableError($e));
$this->stopWorkerIfLostConnection($e);
$this->sleep(1);
}
}
@@ -541,7 +545,7 @@ class Worker
*/
public function memoryExceeded($memoryLimit)
{
return (memory_get_usage() / 1024 / 1024) >= $memoryLimit;
return (memory_get_usage(true) / 1024 / 1024) >= $memoryLimit;
}
/**

View File

@@ -92,9 +92,21 @@ class PhpRedisConnector
*/
protected function establishConnection($client, array $config)
{
$client->{($config['persistent'] ?? false) === true ? 'pconnect' : 'connect'}(
$config['host'], $config['port'], Arr::get($config, 'timeout', 0)
);
$persistent = $config['persistent'] ?? false;
$parameters = [
$config['host'],
$config['port'],
Arr::get($config, 'timeout', 0.0),
$persistent ? Arr::get($config, 'persistent_id', null) : null,
Arr::get($config, 'retry_interval', 0),
];
if (version_compare(phpversion('redis'), '3.1.3', '>=')) {
$parameters[] = Arr::get($config, 'read_timeout', 0.0);
}
$client->{($persistent ? 'pconnect' : 'connect')}(...$parameters);
}
/**

View File

@@ -43,13 +43,15 @@ class ControllerMakeCommand extends GeneratorCommand
$stub = '/stubs/controller.nested.stub';
} elseif ($this->option('model')) {
$stub = '/stubs/controller.model.stub';
} elseif ($this->option('invokable')) {
$stub = '/stubs/controller.invokable.stub';
} elseif ($this->option('resource')) {
$stub = '/stubs/controller.stub';
}
if ($this->option('api') && is_null($stub)) {
$stub = '/stubs/controller.api.stub';
} elseif ($this->option('api') && ! is_null($stub)) {
} elseif ($this->option('api') && ! is_null($stub) && ! $this->option('invokable')) {
$stub = str_replace('.stub', '.api.stub', $stub);
}
@@ -173,11 +175,9 @@ class ControllerMakeCommand extends GeneratorCommand
{
return [
['model', 'm', InputOption::VALUE_OPTIONAL, 'Generate a resource controller for the given model.'],
['resource', 'r', InputOption::VALUE_NONE, 'Generate a resource controller class.'],
['invokable', 'i', InputOption::VALUE_NONE, 'Generate a single method, invokable controller class.'],
['parent', 'p', InputOption::VALUE_OPTIONAL, 'Generate a nested resource controller class.'],
['api', null, InputOption::VALUE_NONE, 'Exclude the create and edit methods from the controller.'],
];
}

View File

@@ -147,7 +147,7 @@ class Redirector
* Create a new redirect response to a named route.
*
* @param string $route
* @param array $parameters
* @param mixed $parameters
* @param int $status
* @param array $headers
* @return \Illuminate\Http\RedirectResponse
@@ -161,7 +161,7 @@ class Redirector
* Create a new redirect response to a controller action.
*
* @param string $action
* @param array $parameters
* @param mixed $parameters
* @param int $status
* @param array $headers
* @return \Illuminate\Http\RedirectResponse

View File

@@ -80,6 +80,8 @@ class RouteAction
*
* @param string $action
* @return string
*
* @throws \UnexpectedValueException
*/
protected static function makeInvokable($action)
{

View File

@@ -21,6 +21,7 @@ use InvalidArgumentException;
* @method \Illuminate\Routing\RouteRegistrar name(string $value)
* @method \Illuminate\Routing\RouteRegistrar namespace(string $value)
* @method \Illuminate\Routing\RouteRegistrar prefix(string $prefix)
* @method \Illuminate\Routing\RouteRegistrar where(array $where)
*/
class RouteRegistrar
{
@@ -53,7 +54,7 @@ class RouteRegistrar
* @var array
*/
protected $allowedAttributes = [
'as', 'domain', 'middleware', 'name', 'namespace', 'prefix',
'as', 'domain', 'middleware', 'name', 'namespace', 'prefix', 'where',
];
/**
@@ -175,6 +176,8 @@ class RouteRegistrar
* @param string $method
* @param array $parameters
* @return \Illuminate\Routing\Route|$this
*
* @throws \BadMethodCallException
*/
public function __call($method, $parameters)
{

View File

@@ -425,7 +425,7 @@ class Router implements RegistrarContract, BindingRegistrar
* @param \Closure|array|string|null $action
* @return \Illuminate\Routing\Route
*/
protected function addRoute($methods, $uri, $action)
public function addRoute($methods, $uri, $action)
{
return $this->routes->add($this->createRoute($methods, $uri, $action));
}
@@ -1131,7 +1131,7 @@ class Router implements RegistrarContract, BindingRegistrar
// Authentication Routes...
$this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
$this->post('login', 'Auth\LoginController@login');
$this->get('logout', 'Auth\LoginController@logout')->name('logout');
$this->post('logout', 'Auth\LoginController@logout')->name('logout');
// Registration Routes...
$this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');

View File

@@ -66,9 +66,9 @@ class FileSessionHandler implements SessionHandlerInterface
*/
public function read($sessionId)
{
if ($this->files->exists($path = $this->path.'/'.$sessionId)) {
if (filemtime($path) >= Carbon::now()->subMinutes($this->minutes)->getTimestamp()) {
return $this->files->get($path, true);
if ($this->files->isFile($path = $this->path.'/'.$sessionId)) {
if ($this->files->lastModified($path) >= Carbon::now()->subMinutes($this->minutes)->getTimestamp()) {
return $this->files->sharedGet($path);
}
}

View File

@@ -480,7 +480,7 @@ class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate
* @param bool $value
* @param callable $callback
* @param callable $default
* @return mixed
* @return static|mixed
*/
public function when($value, callable $callback, callable $default = null)
{
@@ -499,7 +499,7 @@ class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate
* @param bool $value
* @param callable $callback
* @param callable $default
* @return mixed
* @return static|mixed
*/
public function unless($value, callable $callback, callable $default = null)
{
@@ -1245,7 +1245,7 @@ class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate
* Push all of the given items onto the collection.
*
* @param \Traversable|array $source
* @return $this
* @return static
*/
public function concat($source)
{
@@ -1288,7 +1288,7 @@ class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate
* Get one or a specified number of items randomly from the collection.
*
* @param int|null $number
* @return mixed
* @return static|mixed
*
* @throws \InvalidArgumentException
*/

View File

@@ -25,14 +25,16 @@ abstract class Facade
/**
* Convert the facade into a Mockery spy.
*
* @return void
* @return \Mockery\MockInterface
*/
public static function spy()
{
if (! static::isMock()) {
$class = static::getMockableClass();
static::swap($class ? Mockery::spy($class) : Mockery::spy());
return tap($class ? Mockery::spy($class) : Mockery::spy(), function ($spy) {
static::swap($spy);
});
}
}

View File

@@ -8,7 +8,7 @@ namespace Illuminate\Support\Facades;
* @method static bool check(string $value, string $hashedValue, array $options = [])
* @method static bool needsRehash(string $hashedValue, array $options = [])
*
* @see \Illuminate\Hashing\BcryptHasher
* @see \Illuminate\Hashing\HashManager
*/
class Hash extends Facade
{

View File

@@ -12,6 +12,7 @@ namespace Illuminate\Support\Facades;
* @method static \Illuminate\Routing\Route any(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Routing\Route match(array|string $methods, string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Routing\RouteRegistrar prefix(string $prefix)
* @method static \Illuminate\Routing\RouteRegistrar where(array $where)
* @method static \Illuminate\Routing\PendingResourceRegistration resource(string $name, string $controller, array $options = [])
* @method static \Illuminate\Routing\PendingResourceRegistration apiResource(string $name, string $controller, array $options = [])
* @method static void apiResources(array $resources)

View File

@@ -51,6 +51,8 @@ abstract class Manager
*
* @param string $driver
* @return mixed
*
* @throws \InvalidArgumentException
*/
public function driver($driver = null)
{

View File

@@ -64,7 +64,7 @@ class Pluralizer
*/
public static function plural($value, $count = 2)
{
if ((int) $count === 1 || static::uncountable($value)) {
if ((int) abs($count) === 1 || static::uncountable($value)) {
return $value;
}

View File

@@ -2,6 +2,7 @@
namespace Illuminate\Support\Testing\Fakes;
use Closure;
use Illuminate\Support\Arr;
use PHPUnit\Framework\Assert as PHPUnit;
use Illuminate\Contracts\Events\Dispatcher;
@@ -134,7 +135,7 @@ class EventFake implements Dispatcher
*/
public function listen($events, $listener)
{
//
$this->dispatcher->listen($events, $listener);
}
/**
@@ -145,7 +146,7 @@ class EventFake implements Dispatcher
*/
public function hasListeners($eventName)
{
//
return $this->dispatcher->hasListeners($eventName);
}
/**
@@ -168,7 +169,7 @@ class EventFake implements Dispatcher
*/
public function subscribe($subscriber)
{
//
$this->dispatcher->subscribe($subscriber);
}
/**
@@ -207,7 +208,7 @@ class EventFake implements Dispatcher
{
$name = is_object($event) ? get_class($event) : (string) $event;
if ($this->shouldFakeEvent($name)) {
if ($this->shouldFakeEvent($name, $payload)) {
$this->events[$name][] = func_get_args();
} else {
$this->dispatcher->dispatch($event, $payload, $halt);
@@ -218,11 +219,22 @@ class EventFake implements Dispatcher
* Determine if an event should be faked or actually dispatched.
*
* @param string $eventName
* @param mixed $payload
* @return bool
*/
protected function shouldFakeEvent($eventName)
protected function shouldFakeEvent($eventName, $payload)
{
return empty($this->eventsToFake) || in_array($eventName, $this->eventsToFake);
if (empty($this->eventsToFake)) {
return true;
}
return collect($this->eventsToFake)
->filter(function ($event) use ($eventName, $payload) {
return $event instanceof Closure
? $event($eventName, $payload)
: $event === $eventName;
})
->isNotEmpty();
}
/**

View File

@@ -36,9 +36,15 @@ class MailFake implements Mailer
return $this->assertSentTimes($mailable, $callback);
}
$message = "The expected [{$mailable}] mailable was not sent.";
if (count($this->queuedMailables) > 0) {
$message .= ' Did you mean to use assertQueued() instead?';
}
PHPUnit::assertTrue(
$this->sent($mailable, $callback)->count() > 0,
"The expected [{$mailable}] mailable was not sent."
$message
);
}

View File

@@ -57,7 +57,7 @@ class NotificationFake implements NotificationFactory, NotificationDispatcher
{
PHPUnit::assertTrue(
($count = $this->sent($notifiable, $notification)->count()) === $times,
"Expected [{$notification}] to be sent {$count} times, but was sent {$times} times."
"Expected [{$notification}] to be sent {$times} times, but was sent {$count} times."
);
}

View File

@@ -1126,9 +1126,13 @@ trait ValidatesAttributes
return false;
}
$phpExtensions = [
'php', 'php3', 'php4', 'php5', 'phtml',
];
return ($value instanceof UploadedFile)
? trim(strtolower($value->getClientOriginalExtension())) === 'php'
: trim(strtolower($value->getExtension())) === 'php';
? in_array(trim(strtolower($value->getClientOriginalExtension())), $phpExtensions)
: in_array(trim(strtolower($value->getExtension())), $phpExtensions);
}
/**
@@ -1524,7 +1528,7 @@ trait ValidatesAttributes
((aaa|aaas|about|acap|acct|acr|adiumxtra|afp|afs|aim|apt|attachment|aw|barion|beshare|bitcoin|blob|bolo|callto|cap|chrome|chrome-extension|cid|coap|coaps|com-eventbrite-attendee|content|crid|cvs|data|dav|dict|dlna-playcontainer|dlna-playsingle|dns|dntp|dtn|dvb|ed2k|example|facetime|fax|feed|feedready|file|filesystem|finger|fish|ftp|geo|gg|git|gizmoproject|go|gopher|gtalk|h323|ham|hcp|http|https|iax|icap|icon|im|imap|info|iotdisco|ipn|ipp|ipps|irc|irc6|ircs|iris|iris.beep|iris.lwz|iris.xpc|iris.xpcs|itms|jabber|jar|jms|keyparc|lastfm|ldap|ldaps|magnet|mailserver|mailto|maps|market|message|mid|mms|modem|ms-help|ms-settings|ms-settings-airplanemode|ms-settings-bluetooth|ms-settings-camera|ms-settings-cellular|ms-settings-cloudstorage|ms-settings-emailandaccounts|ms-settings-language|ms-settings-location|ms-settings-lock|ms-settings-nfctransactions|ms-settings-notifications|ms-settings-power|ms-settings-privacy|ms-settings-proximity|ms-settings-screenrotation|ms-settings-wifi|ms-settings-workplace|msnim|msrp|msrps|mtqp|mumble|mupdate|mvn|news|nfs|ni|nih|nntp|notes|oid|opaquelocktoken|pack|palm|paparazzi|pkcs11|platform|pop|pres|prospero|proxy|psyc|query|redis|rediss|reload|res|resource|rmi|rsync|rtmfp|rtmp|rtsp|rtsps|rtspu|secondlife|s3|service|session|sftp|sgn|shttp|sieve|sip|sips|skype|smb|sms|smtp|snews|snmp|soap.beep|soap.beeps|soldat|spotify|ssh|steam|stun|stuns|submit|svn|tag|teamspeak|tel|teliaeid|telnet|tftp|things|thismessage|tip|tn3270|turn|turns|tv|udp|unreal|urn|ut2004|vemmi|ventrilo|videotex|view-source|wais|webcal|ws|wss|wtai|wyciwyg|xcon|xcon-userid|xfire|xmlrpc\.beep|xmlrpc.beeps|xmpp|xri|ymsgr|z39\.50|z39\.50r|z39\.50s)):// # protocol
(([\pL\pN-]+:)?([\pL\pN-]+)@)? # basic auth
(
([\pL\pN\pS-\.])+(\.?([\pL]|xn\-\-[\pL\pN-]+)+\.?) # a domain name
([\pL\pN\pS\-\.])+(\.?([\pL]|xn\-\-[\pL\pN-]+)+\.?) # a domain name
| # or
\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # an IP address
| # or

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