Added details++; Vendor updates

This commit is contained in:
2017-09-24 18:42:53 +02:00
parent 848c9b1222
commit 783985b7ec
53 changed files with 761 additions and 447 deletions

View File

@@ -26,7 +26,7 @@ Laravel is accessible, yet powerful, providing tools needed for large, robust ap
Laravel has the most extensive and thorough documentation and video tutorial library of any modern web application framework. The [Laravel documentation](https://laravel.com/docs) is thorough, complete, and makes it a breeze to get started learning the framework.
If you're not in the mood to read, [Laracasts](https://laracasts.com) contains over 900 video tutorials covering a range of topics including Laravel, modern PHP, unit testing, JavaScript, and more. Boost the skill level of yourself and your entire team by digging into our comprehensive video library.
If you're not in the mood to read, [Laracasts](https://laracasts.com) contains over 1100 video tutorials covering a range of topics including Laravel, modern PHP, unit testing, JavaScript, and more. Boost the skill level of yourself and your entire team by digging into our comprehensive video library.
## Contributing

View File

@@ -68,12 +68,10 @@ class DatabaseUserProvider implements UserProvider
*/
public function retrieveByToken($identifier, $token)
{
$user = $this->conn->table($this->table)
->where('id', $identifier)
->where('remember_token', $token)
->first();
$user = $this->conn->table($this->table)->find($identifier);
return $this->getGenericUser($user);
return $user && hash_equals($user->remember_token, $token)
? $this->getGenericUser($user) : null;
}
/**

View File

@@ -62,10 +62,11 @@ class EloquentUserProvider implements UserProvider
{
$model = $this->createModel();
return $model->newQuery()
->where($model->getAuthIdentifierName(), $identifier)
->where($model->getRememberTokenName(), $token)
->first();
$model = $model->where($model->getAuthIdentifierName(), $identifier)->first();
$rememberToken = $model->getRememberToken();
return $model && $rememberToken && hash_equals($rememberToken, $token) ? $model : null;
}
/**

View File

@@ -4,6 +4,7 @@ namespace Illuminate\Cache\Console;
use Illuminate\Console\Command;
use Illuminate\Cache\CacheManager;
use Illuminate\Filesystem\Filesystem;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
@@ -30,17 +31,26 @@ class ClearCommand extends Command
*/
protected $cache;
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* Create a new cache clear command instance.
*
* @param \Illuminate\Cache\CacheManager $cache
* @param \Illuminate\Filesystem\Filesystem $files
* @return void
*/
public function __construct(CacheManager $cache)
public function __construct(CacheManager $cache, Filesystem $files)
{
parent::__construct();
$this->cache = $cache;
$this->files = $files;
}
/**
@@ -50,15 +60,35 @@ class ClearCommand extends Command
*/
public function handle()
{
$this->laravel['events']->fire('cache:clearing', [$this->argument('store'), $this->tags()]);
$this->laravel['events']->fire(
'cache:clearing', [$this->argument('store'), $this->tags()]
);
$this->cache()->flush();
$this->laravel['events']->fire('cache:cleared', [$this->argument('store'), $this->tags()]);
$this->flushFacades();
$this->laravel['events']->fire(
'cache:cleared', [$this->argument('store'), $this->tags()]
);
$this->info('Cache cleared successfully.');
}
/**
* Flush the real-time facades stored in the cache directory.
*
* @return void
*/
public function flushFacades()
{
foreach ($this->files->files(storage_path('framework/cache')) as $file) {
if (preg_match('/facade-.*\.php$/', $file)) {
$this->files->delete($file);
}
}
}
/**
* Get the cache instance for the command.
*

View File

@@ -378,10 +378,11 @@ class Command extends SymfonyCommand
*
* @param array $headers
* @param \Illuminate\Contracts\Support\Arrayable|array $rows
* @param string $style
* @param string $tableStyle
* @param array $columnStyles
* @return void
*/
public function table($headers, $rows, $style = 'default')
public function table($headers, $rows, $tableStyle = 'default', array $columnStyles = [])
{
$table = new Table($this->output);
@@ -389,7 +390,13 @@ class Command extends SymfonyCommand
$rows = $rows->toArray();
}
$table->setHeaders((array) $headers)->setRows($rows)->setStyle($style)->render();
$table->setHeaders((array) $headers)->setRows($rows)->setStyle($tableStyle);
foreach ($columnStyles as $columnIndex => $columnStyle) {
$table->setColumnStyle($columnIndex, $columnStyle);
}
$table->render();
}
/**

View File

@@ -15,7 +15,7 @@ interface Queue
/**
* Push a new job onto the queue.
*
* @param string $job
* @param string|object $job
* @param mixed $data
* @param string $queue
* @return mixed
@@ -26,7 +26,7 @@ interface Queue
* Push a new job onto the queue.
*
* @param string $queue
* @param string $job
* @param string|object $job
* @param mixed $data
* @return mixed
*/
@@ -46,7 +46,7 @@ interface Queue
* Push a new job onto the queue after a delay.
*
* @param \DateTimeInterface|\DateInterval|int $delay
* @param string $job
* @param string|object $job
* @param mixed $data
* @param string $queue
* @return mixed
@@ -58,7 +58,7 @@ interface Queue
*
* @param string $queue
* @param \DateTimeInterface|\DateInterval|int $delay
* @param string $job
* @param string|object $job
* @param mixed $data
* @return mixed
*/

View File

@@ -892,11 +892,13 @@ class Connection implements ConnectionInterface
public function getDoctrineConnection()
{
if (is_null($this->doctrineConnection)) {
$data = ['pdo' => $this->getPdo(), 'dbname' => $this->getConfig('database')];
$driver = $this->getDoctrineDriver();
$this->doctrineConnection = new DoctrineConnection(
$data, $this->getDoctrineDriver()
);
$this->doctrineConnection = new DoctrineConnection([
'pdo' => $this->getPdo(),
'dbname' => $this->getConfig('database'),
'driver' => $driver->getName(),
], $driver);
}
return $this->doctrineConnection;

View File

@@ -78,7 +78,7 @@ class FactoryMakeCommand extends GeneratorCommand
protected function getOptions()
{
return [
['model', null, InputOption::VALUE_OPTIONAL, 'The name of the model'],
['model', 'm', InputOption::VALUE_OPTIONAL, 'The name of the model'],
];
}
}

View File

@@ -38,7 +38,7 @@ trait HasTimestamps
{
$time = $this->freshTimestamp();
if (! $this->isDirty(static::UPDATED_AT)) {
if (! is_null(static::UPDATED_AT) && ! $this->isDirty(static::UPDATED_AT)) {
$this->setUpdatedAt($time);
}

View File

@@ -16,10 +16,6 @@ use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Database\ConnectionResolverInterface as Resolver;
/**
* @mixin \Illuminate\Database\Eloquent\Builder
* @mixin \Illuminate\Database\Query\Builder
*/
abstract class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable, QueueableEntity, UrlRoutable
{
use Concerns\HasAttributes,

View File

@@ -188,7 +188,9 @@ trait InteractsWithPivotTable
$attributes = $this->addTimestampsToAttachment($attributes, true);
}
$updated = $this->newPivotStatementForId($id)->update($attributes);
$updated = $this->newPivotStatementForId($id)->update(
$this->castAttributes($attributes)
);
if ($touch) {
$this->touchIfTouching();
@@ -236,10 +238,6 @@ trait InteractsWithPivotTable
// To create the attachment records, we will simply spin through the IDs given
// and create a new record to insert for each ID. Each ID may actually be a
// key in the array, with extra attributes to be placed in other columns.
$attributes = $this->using
? $this->newPivot()->forceFill($attributes)->getAttributes()
: $attributes;
foreach ($ids as $key => $value) {
$records[] = $this->formatAttachRecord(
$key, $value, $attributes, $hasTimestamps
@@ -263,7 +261,7 @@ trait InteractsWithPivotTable
list($id, $attributes) = $this->extractAttachIdAndAttributes($key, $value, $attributes);
return array_merge(
$this->baseAttachRecord($id, $hasTimestamps), $attributes
$this->baseAttachRecord($id, $hasTimestamps), $this->castAttributes($attributes)
);
}
@@ -503,4 +501,17 @@ trait InteractsWithPivotTable
{
return is_numeric($key) ? (int) $key : (string) $key;
}
/**
* Cast the given pivot attributes.
*
* @param array $attributes
* @return array
*/
protected function castAttributes($attributes)
{
return $this->using
? $this->newPivot()->forceFill($attributes)->getAttributes()
: $attributes;
}
}

View File

@@ -194,9 +194,13 @@ class MorphTo extends BelongsTo
*/
public function associate($model)
{
$this->parent->setAttribute($this->foreignKey, $model->getKey());
$this->parent->setAttribute(
$this->foreignKey, $model instanceof Model ? $model->getKey() : null
);
$this->parent->setAttribute($this->morphType, $model->getMorphClass());
$this->parent->setAttribute(
$this->morphType, $model instanceof Model ? $model->getMorphClass() : null
);
return $this->parent->setRelation($this->relation, $model);
}

View File

@@ -66,7 +66,7 @@ trait SoftDeletes
$this->{$this->getDeletedAtColumn()} = $time;
if ($this->timestamps) {
if ($this->timestamps && ! is_null($this->getUpdatedAtColumn())) {
$this->{$this->getUpdatedAtColumn()} = $time;
$columns[$this->getUpdatedAtColumn()] = $this->fromDateTime($time);

View File

@@ -741,10 +741,10 @@ class Grammar extends BaseGrammar
*/
public function prepareBindingsForUpdate(array $bindings, array $values)
{
$bindingsWithoutJoin = Arr::except($bindings, 'join');
$cleanBindings = Arr::except($bindings, ['join', 'select']);
return array_values(
array_merge($bindings['join'], $values, Arr::flatten($bindingsWithoutJoin))
array_merge($bindings['join'], $values, Arr::flatten($cleanBindings))
);
}

View File

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

View File

@@ -24,7 +24,7 @@ trait AuthenticatesUsers
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
*/
public function login(Request $request)
{
@@ -74,7 +74,7 @@ trait AuthenticatesUsers
protected function attemptLogin(Request $request)
{
return $this->guard()->attempt(
$this->credentials($request), $request->has('remember')
$this->credentials($request), $request->filled('remember')
);
}
@@ -121,7 +121,9 @@ trait AuthenticatesUsers
* Get the failed login response instance.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws ValidationException
*/
protected function sendFailedLoginResponse(Request $request)
{

View File

@@ -33,7 +33,7 @@ trait ResetsPasswords
* Reset the given user's password.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
public function reset(Request $request)
{
@@ -117,7 +117,7 @@ trait ResetsPasswords
* Get the response for a successful password reset.
*
* @param string $response
* @return \Illuminate\Http\RedirectResponse
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
protected function sendResetResponse($response)
{
@@ -130,7 +130,7 @@ trait ResetsPasswords
*
* @param \Illuminate\Http\Request
* @param string $response
* @return \Illuminate\Http\RedirectResponse
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
protected function sendResetFailedResponse(Request $request, $response)
{

View File

@@ -21,7 +21,7 @@ trait SendsPasswordResetEmails
* Send a reset link to the given user.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
public function sendResetLinkEmail(Request $request)
{
@@ -54,7 +54,7 @@ trait SendsPasswordResetEmails
* Get the response for a successful password reset link.
*
* @param string $response
* @return \Illuminate\Http\RedirectResponse
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
protected function sendResetLinkResponse($response)
{
@@ -66,7 +66,7 @@ trait SendsPasswordResetEmails
*
* @param \Illuminate\Http\Request
* @param string $response
* @return \Illuminate\Http\RedirectResponse
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
protected function sendResetLinkFailedResponse(Request $request, $response)
{

View File

@@ -383,10 +383,11 @@ class Handler implements ExceptionHandlerContract
{
$status = $e->getStatusCode();
view()->replaceNamespace('errors', [
resource_path('views/errors'),
__DIR__.'/views',
]);
$paths = collect(config('view.paths'));
view()->replaceNamespace('errors', $paths->map(function ($path) {
return "{$path}/errors";
})->push(__DIR__.'/views')->all());
if (view()->exists($view = "errors::{$status}")) {
return response()->view($view, ['exception' => $e], $status, $e->getHeaders());

View File

@@ -214,7 +214,7 @@ class ArtisanServiceProvider extends ServiceProvider
protected function registerCacheClearCommand()
{
$this->app->singleton('command.cache.clear', function ($app) {
return new CacheClearCommand($app['cache']);
return new CacheClearCommand($app['cache'], $app['files']);
});
}

View File

@@ -241,12 +241,13 @@ class TestResponse
* Assert that the response is a superset of the given JSON.
*
* @param array $data
* @param bool $strict
* @return $this
*/
public function assertJson(array $data)
public function assertJson(array $data, $strict = false)
{
PHPUnit::assertArraySubset(
$data, $this->decodeResponseJson(), false, $this->assertJsonMessage($data)
$data, $this->decodeResponseJson(), $strict, $this->assertJsonMessage($data)
);
return $this;

View File

@@ -2,6 +2,7 @@
namespace Illuminate\Foundation\Validation;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Contracts\Validation\Factory;
use Illuminate\Validation\ValidationException;
@@ -25,9 +26,7 @@ trait ValidatesRequests
$validator->validate();
return $request->only(collect($validator->getRules())->keys()->map(function ($rule) {
return str_contains($rule, '.') ? explode('.', $rule)[0] : $rule;
})->unique()->toArray());
return $this->extractInputFromRules($request, $validator->getRules());
}
/**
@@ -46,8 +45,20 @@ trait ValidatesRequests
->make($request->all(), $rules, $messages, $customAttributes)
->validate();
return $this->extractInputFromRules($request, $rules);
}
/**
* Get the request input based on the given validation rules.
*
* @param \Illuminate\Http\Request $request
* @param array $rules
* @return array
*/
protected function extractInputFromRules(Request $request, array $rules)
{
return $request->only(collect($rules)->keys()->map(function ($rule) {
return str_contains($rule, '.') ? explode('.', $rule)[0] : $rule;
return Str::contains($rule, '.') ? explode('.', $rule)[0] : $rule;
})->unique()->toArray());
}

View File

@@ -107,9 +107,7 @@ if (! function_exists('app')) {
return Container::getInstance();
}
return empty($parameters)
? Container::getInstance()->make($abstract)
: Container::getInstance()->makeWith($abstract, $parameters);
return Container::getInstance()->make($abstract, $parameters);
}
}
@@ -204,7 +202,7 @@ if (! function_exists('broadcast')) {
* Begin broadcasting an event.
*
* @param mixed|null $event
* @return \Illuminate\Broadcasting\PendingBroadcast|void
* @return \Illuminate\Broadcasting\PendingBroadcast
*/
function broadcast($event = null)
{
@@ -219,7 +217,7 @@ if (! function_exists('cache')) {
* If an array is passed, we'll assume you want to put to the cache.
*
* @param dynamic key|key,default|data,expiration|null
* @return mixed
* @return mixed|\Illuminate\Cache\CacheManager
*
* @throws \Exception
*/
@@ -259,7 +257,7 @@ if (! function_exists('config')) {
*
* @param array|string $key
* @param mixed $default
* @return mixed
* @return mixed|\Illuminate\Config\Repository
*/
function config($key = null, $default = null)
{
@@ -299,7 +297,7 @@ if (! function_exists('cookie')) {
* @param string $domain
* @param bool $secure
* @param bool $httpOnly
* @return \Symfony\Component\HttpFoundation\Cookie
* @return \Illuminate\Cookie\CookieJar|\Symfony\Component\HttpFoundation\Cookie
*/
function cookie($name = null, $value = null, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true)
{
@@ -818,7 +816,7 @@ if (! function_exists('session')) {
*
* @param array|string $key
* @param mixed $default
* @return mixed
* @return mixed|\Illuminate\Session\Store|\Illuminate\Session\SessionManager
*/
function session($key = null, $default = null)
{
@@ -902,9 +900,9 @@ if (! function_exists('__')) {
* @param string $key
* @param array $replace
* @param string $locale
* @return \Illuminate\Contracts\Translation\Translator|string
* @return string
*/
function __($key = null, $replace = [], $locale = null)
function __($key, $replace = [], $locale = null)
{
return app('translator')->getFromJson($key, $replace, $locale);
}

View File

@@ -42,6 +42,13 @@ class Route
*/
public $action;
/**
* Indicates whether the route is a fallback route.
*
* @var bool
*/
public $isFallback = false;
/**
* The controller instance.
*
@@ -484,6 +491,18 @@ class Route
return $this;
}
/**
* Mark this route as a fallback route.
*
* @return $this
*/
public function fallback()
{
$this->isFallback = true;
return $this;
}
/**
* Get the HTTP verbs the route responds to.
*

View File

@@ -189,7 +189,11 @@ class RouteCollection implements Countable, IteratorAggregate
*/
protected function matchAgainstRoutes(array $routes, $request, $includingMethod = true)
{
return Arr::first($routes, function ($value) use ($request, $includingMethod) {
list($fallbacks, $routes) = collect($routes)->partition(function ($route) {
return $route->isFallback;
});
return $routes->merge($fallbacks)->first(function ($value) use ($request, $includingMethod) {
return $value->matches($request, $includingMethod);
});
}

View File

@@ -212,6 +212,21 @@ class Router implements RegistrarContract, BindingRegistrar
return $this->addRoute(self::$verbs, $uri, $action);
}
/**
* Register a new Fallback route with the router.
*
* @param \Closure|array|string|null $action
* @return \Illuminate\Routing\Route
*/
public function fallback($action)
{
$placeholder = 'fallbackPlaceholder';
return $this->addRoute(
'GET', "{{$placeholder}}", $action
)->where($placeholder, '.*')->fallback();
}
/**
* Create a redirect from one URI to another.
*
@@ -536,6 +551,19 @@ class Router implements RegistrarContract, BindingRegistrar
$route->setAction($this->mergeWithLastGroup($route->getAction()));
}
/**
* Return the response returned by the given route.
*
* @param string $name
* @return mixed
*/
public function respondWithRoute($name)
{
$route = tap($this->routes->getByName($name))->bind($this->currentRequest);
return $this->runRoute($this->currentRequest, $route);
}
/**
* Dispatch the request to the application.
*
@@ -557,20 +585,7 @@ class Router implements RegistrarContract, BindingRegistrar
*/
public function dispatchToRoute(Request $request)
{
// First we will find a route that matches this request. We will also set the
// route resolver on the request so middlewares assigned to the route will
// receive access to this route instance for checking of the parameters.
$route = $this->findRoute($request);
$request->setRouteResolver(function () use ($route) {
return $route;
});
$this->events->dispatch(new Events\RouteMatched($route, $request));
$response = $this->runRouteWithinStack($route, $request);
return $this->prepareResponse($request, $response);
return $this->runRoute($request, $this->findRoute($request));
}
/**
@@ -588,6 +603,26 @@ class Router implements RegistrarContract, BindingRegistrar
return $route;
}
/**
* Return the response for the given route.
*
* @param Route $route
* @param Request $request
* @return mixed
*/
protected function runRoute(Request $request, Route $route)
{
$request->setRouteResolver(function () use ($route) {
return $route;
});
$this->events->dispatch(new Events\RouteMatched($route, $request));
return $this->prepareResponse($request,
$this->runRouteWithinStack($route, $request)
);
}
/**
* Run the given route within a Stack "onion" instance.
*

View File

@@ -93,7 +93,7 @@ class DatabaseSessionHandler implements SessionHandlerInterface, ExistenceAwareI
if ($this->expired($session)) {
$this->exists = true;
return;
return '';
}
if (isset($session->payload)) {
@@ -101,6 +101,8 @@ class DatabaseSessionHandler implements SessionHandlerInterface, ExistenceAwareI
return base64_decode($session->payload);
}
return '';
}
/**

View File

@@ -1340,7 +1340,7 @@ class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate
*/
public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
{
$results = [];
list($values, $results) = [[], []];
$callback = $this->valueRetriever($callback);
@@ -1348,16 +1348,19 @@ class Collection implements ArrayAccess, Arrayable, Countable, IteratorAggregate
// function which we were given. Then, we will sort the returned values and
// and grab the corresponding values for the sorted keys from this array.
foreach ($this->items as $key => $value) {
$results[$key] = $callback($value, $key);
$values[] = $callback($value, $key);
}
$descending ? arsort($results, $options)
: asort($results, $options);
$keys = array_keys($this->items);
$order = $descending ? SORT_DESC : SORT_ASC;
array_multisort($values, $order, $options, $keys, $order);
// Once we have sorted all of the keys in the array, we will loop through them
// and grab the corresponding model so we can set the underlying items list
// to the sorted version. Then we'll just return the collection instance.
foreach (array_keys($results) as $key) {
foreach ($keys as $key) {
$results[$key] = $this->items[$key];
}

View File

@@ -3,21 +3,25 @@
namespace Illuminate\Support\Facades;
/**
* @method static \Illuminate\Routing\Route get(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Routing\Route post(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Routing\Route put(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Routing\Route delete(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Routing\Route patch(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Routing\Route options(string $uri, \Closure|array|string|null $action = null)
* @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\Route prefix(string $prefix)
* @method static \Illuminate\Support\Facades\Route get(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Support\Facades\Route post(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Support\Facades\Route put(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Support\Facades\Route delete(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Support\Facades\Route patch(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Support\Facades\Route options(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Support\Facades\Route any(string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Support\Facades\Route match(array|string $methods, string $uri, \Closure|array|string|null $action = null)
* @method static \Illuminate\Support\Facades\Route prefix(string $prefix)
* @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 group(array $attributes, \Closure|string $callback)
* @method static \Illuminate\Routing\Route middleware(array|string|null $middleware)
* @method static \Illuminate\Routing\Route substituteBindings(\Illuminate\Routing\Route $route)
* @method static void substituteImplicitBindings(\Illuminate\Routing\Route $route)
* @method static \Illuminate\Support\Facades\Route middleware(array|string|null $middleware)
* @method static \Illuminate\Support\Facades\Route substituteBindings(\Illuminate\Support\Facades\Route $route)
* @method static void substituteImplicitBindings(\Illuminate\Support\Facades\Route $route)
* @method \Illuminate\Support\Facades\Route as(string $value)
* @method \Illuminate\Support\Facades\Route domain(string $value)
* @method \Illuminate\Support\Facades\Route name(string $value)
* @method \Illuminate\Support\Facades\Route namespace(string $value)
* @method \Illuminate\Routing\Route group(string $value)
*
* @see \Illuminate\Routing\Router
*/

View File

@@ -24,9 +24,11 @@ class Pluralizer
'equipment',
'evidence',
'feedback',
'firmware',
'fish',
'furniture',
'gold',
'hardware',
'information',
'jedi',
'knowledge',
@@ -44,6 +46,7 @@ class Pluralizer
'rice',
'series',
'sheep',
'software',
'species',
'swine',
'traffic',

View File

@@ -118,7 +118,7 @@ class Str
public static function endsWith($haystack, $needles)
{
foreach ((array) $needles as $needle) {
if (substr($haystack, -strlen($needle)) === (string) $needle) {
if (mb_substr($haystack, -mb_strlen($needle)) === (string) $needle) {
return true;
}
}
@@ -328,10 +328,10 @@ class Str
return $subject;
}
$position = strpos($subject, $search);
$position = mb_strpos($subject, $search);
if ($position !== false) {
return substr_replace($subject, $replace, $position, strlen($search));
return mb_substr($subject, 0, $position).$replace.mb_substr($subject, $position + mb_strlen($search));
}
return $subject;
@@ -347,10 +347,10 @@ class Str
*/
public static function replaceLast($search, $replace, $subject)
{
$position = strrpos($subject, $search);
$position = mb_strrpos($subject, $search);
if ($position !== false) {
return substr_replace($subject, $replace, $position, strlen($search));
return mb_substr($subject, 0, $position).$replace.mb_substr($subject, $position + mb_strlen($search));
}
return $subject;
@@ -466,7 +466,7 @@ class Str
public static function startsWith($haystack, $needles)
{
foreach ((array) $needles as $needle) {
if ($needle !== '' && substr($haystack, 0, strlen($needle)) === (string) $needle) {
if ($needle !== '' && mb_substr($haystack, 0, mb_strlen($needle)) === (string) $needle) {
return true;
}
}

View File

@@ -190,6 +190,8 @@ trait FormatsMessages
$message, $this->getDisplayableAttribute($attribute)
);
$message = $this->replaceInputPlaceholder($message, $attribute);
if (isset($this->replacers[Str::snake($rule)])) {
return $this->callReplacer($message, $attribute, Str::snake($rule), $parameters, $this);
} elseif (method_exists($this, $replacer = "replace{$rule}")) {
@@ -265,6 +267,24 @@ trait FormatsMessages
);
}
/**
* Replace the :input placeholder in the given message.
*
* @param string $message
* @param string $value
* @return string
*/
protected function replaceInputPlaceholder($message, $attribute)
{
$actualValue = $this->getValue($attribute);
if (is_scalar($actualValue) || is_null($actualValue)) {
$message = str_replace(':input', $actualValue, $message);
}
return $message;
}
/**
* Get the displayable name of the value.
*

View File

@@ -53,4 +53,17 @@ trait CompilesIncludes
return "<?php echo \$__env->renderWhen($expression, array_except(get_defined_vars(), array('__data', '__path'))); ?>";
}
/**
* Compile the include-first statements into valid PHP.
*
* @param string $expression
* @return string
*/
protected function compileIncludeFirst($expression)
{
$expression = $this->stripParentheses($expression);
return "<?php echo \$__env->first({$expression}, array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>";
}
}