Coder Social home page Coder Social logo

ideas's Introduction

ideas's People

Contributors

driesvints avatar taylorotwell avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ideas's Issues

Collection sortBy() on multiple fields

I commonly find that there is no shorthand way of sorting collections by multiple fields. A large amount of extra code is required just by adding in an extra field. What I really want to do is this:

$collection->sortBy(['Surname', 'Forename']);

Instead you need to pass a callback concatenating all of the fields you want:

$collection->sortBy(function($item) {
  return $item->Surname.'-'.$item->Forename;
});

You have to do something similar if you want to groupBy() on multiple fields.

There have been several SO questions on the topic, but there's never been a clean solution

A Pseudo Relation

here is a situation I run into with a site of mine quite often. I have Teams that are comprised of Players. Over the course of many seasons, a Player can be on many Teams. Coaches add Players to Teams. Ideally the Player is also a User on the site as well, so they can track all of the Teams they are on. The reality of it is, more often than not, Players will not not be Users.

Even if a Player eventually becomes a User, when the Coach adds the Player, they may not be a User yet. Therefore, when creating their Team, Coaches fill in first_name, last_name, and email for the Player. My Player table looks like this:

Player

  • id
  • team_id
  • first_name
  • last_name
  • email
  • user_id (nullable)

If someone does sign up, they can connect this Player to their User.

here is where the problem arises. On my Player model, I have a relationship for the User.

public function user()
{
    return $this->belongsTo(User::class);
}

However, if this Player has not been connected to a User, this doesn't work. What I would like to do in this case is create a 'Pseudo User' that is returned instead.

public function user()
{
    if($this->user_id){
        return $this->belongsTo(User::class);
    }

    $user = new User();
    $user->first_name = $this->first_name;
    $user->last_name = $this->last_name;
    $user->email = $this->email;

    return $user;
}

The problem here is that we cannot return a Model, we need to return a Relation. I'm not exactly sure how this would work, but I would like to create our own Relation and populate the getResults() method with our Pseudo User.

Some people may ask, why not just actually create the pseudo user in the User table. I have gone back and forth on this, and when I made the decision years ago, I decided not to. Not sure if it was the right decision, but it's what I went with.

Looking for some thoughts on this.

Thanks!

migrate:reset ignores foreign key constraints

I've encountered this many times and can't think of a scenario where a php artisan migrate:reset should obey foreign keys, at least in the local development environment. I've cloned the framework repo and am considering a pull request but was hoping to get some feedback on an acceptable implementation within https://github.com/laravel/framework/blob/master/src/Illuminate/Database/Migrations/Migrator.php#L194 before I submitted a PR so I could focus my efforts in the right direction.

It looks like all officially supported database drivers support foreign key implementation and I'm not aware of a database that doesn't. With that in mind, I was considering adding disableKeyChecks() and reenableKeyChecks() steps to the reset process.

If implemented across all supported database drivers, would this be a branch that could be a candidate to be merged in?

Form requests skip the HTTP middleware stack

Im sure there is a good reason, although FormRequests skip the middleware stack.

Currently we have a middleware that transforms any input data coming into our API from snake_case to camelCase.

    /**
     * Convert the case of keys on incoming requests.
     *
     * @param  \Dingo\Api\Http\Request $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        $formatted = CaseTransformer::snakeCaseKeys($request->toArray());

        $request->replace($formatted);

        return $next($request);
    }

although when validating Requests with a FormRequest those transformations are not present. After investigating the Illuminate\Foundation\Providers\FoundationServiceProvider class, its clear that FormRequests are initialised very early on and do not receive any middleware present within the app.

Can someone please explain to me the purpose of form request validators if they are not being transformed through middleware?

If they are simply to validate raw input then how do we validate input AFTER our HTTP middleware stack? As this is also very important.

thanks!

Should collection forPage() 0 return NULL ?

Hi
I tried collection forPage() method in Tinker
and relize the if I get element for page 0, forPage() method will return the last elements like following image.

collection_for_page

For page 1 , We get the first 3 elements from collection.
For page 0, We get the last 3 elements from collection.
For page -1, We get the 2nd last 3 elements from collection.

Should we change the behavior that:
For page 0, We get nothing.
For page -1, We get the 1st last 3 elements from collection ?

[5.3] Closure vs callable

MOVING from laravel/framework#9565 to here. Let's continue discussion here.

Hey good folks,

I have a question, related to a design problem I stumbled upon today while developing some nice code with Laravel:

Why don't we use callable type-hint instead of \Closure wherever applicable? The former covers the latter, whereas the other way around isn't valid. Example code:

Router::group($someOptionsHere, [$this, 'myCallbackMethod']);

won't work with Laravel's current signatures. However if one changed these sigs, let's say for the group() method above FROM

public function group(array $attributes, \Closure $callback)

TO

public function group(array $attributes, callable $callback)

everything would be honkie dorie. We could use both Closures and regular callables. Additionally, let me note that callable type-hinting has been introduced in PHP 5.4, so we are covered. As you can see there are no BC implications involved as well.

Thoughts?

CC: @taylorotwell , @GrahamCampbell

Eloquent Events

I would suppose we want to move these away from strings and to objects in the future.
Any ideas of a smooth way to go about this in a general way?

Move the integrated test package to it's own repository / project

The idea is to move everything under src/Illuminate/Foundation/Testing to its own repository.

That way it would be a new package / library included by default as a dev-dependency in the laravel/laravel project.

Advantages:

  • Adapters for multiple versions of Laravel, even the old ones (4.2, 5.0)
  • When migrating a project from, let's say 5.1 to 5.5 the same testing package with the same API, etc. will be available for both, so it is more powerful and reliable.
  • Testing is a dev-dependency, no need to deploy it.
  • Can be easier to maintain / organise, since it will have its own repository, issues, PRs, etc.
  • Could even have adapters for non-laravel projects.
  • laravel/testing sounds good

Fluent interface for the validation package

Several features in Laravel has a fluent interface which is nice, for example:

The migrations: $table->integer('id')->unsigned()->index()

Or Fluent: ->select()->where()->get()

But not the validator:

required|max:2|unique:table,column,id,this,make,no,sense

What if we change this for a future version of Laravel?

$rules = rules();
$rules->add('title')
    ->required()
    ->max(2)
    ->unique('table','column')
    ->ignore($id)
    ->uniqueWhere(['this' => 'make', 'more' => 'sense']);

$this->validate($request, $rules);

We could even support both ways (fluent interface or strings).

What do you think?

Eloquent ArrayAccess

Can we adjust this to use the attributes only?

I don't think people expect this to return properties if they exist and has caused a few people to run into issues with property names that match attribute names. Especially because of how Arr::get and other functions work, since it will use the model as an array not as an object, which means it will return a property value not an attribute's value if a property exists.

Mailer: add inline css and extend send() method without callback

1) Right now each time to send an email you have to write many extra lines of code, like:

        Mail::send('emails.reminder', ['user' => $user], function ($m) use ($user) {
            $m->from('[email protected]', 'Your Application');

            $m->to($user->email, $user->name)->subject('Your Reminder!');
        });

While it could be something like Mail::send($user->email, 'reminder')

2) You have to manually control each mail's subject and pass it to closure while it could be stored in lang/en/mail.php where key = template name

3) Each email template requires inline CSS and since maintaining it is a pain, there are some composer packages could be used to automatically inline css from file.

My current working codebase:

I have extended Mailer with 2 new methods:

First one

    public function sendTo($email_to, $view, array $data = []) // data is optional now
    {
        $subject = Lang::get('mail.'.$view); // automatically get subject by template name

        parent::send(
            'emails.' . $view,
            $data,
            function ($message) use ($email_to, $subject) {
                $message->to($email_to);
                $message->subject($subject);
            }
        );
    }

$message->from() is set in mail config 'from' => ['address' => '[email protected]', 'name' => 'Your Application'],

second method extends getView() and parses resources/assets/css/email.css and makes inline CSS via package Pelago\Emogrifier

    protected function getView($view, $data)
    {
        $content = $this->views->make($view, $data)->render();
        $css = file_get_contents(resource_path('assets/css/email.css'));
        $inliner = new Emogrifier();
        $inliner->setCss($css);
        $inliner->setHtml($content);
        $content = $inliner->emogrify();

        return $content;
    }

4) I also added new ENV variable in mail config to allow each developer set his own email for testing

    'to' => [
        'address' => env('MAIL_FORCE_TO_ADDRESS', null),
        'name' => null
    ],

Config Cache problem

If i can directly config:cache command, .env file could not run correctly. And i dont read it env variables.
But i run config:clear after everything is ok. it is very annoying error.

Eloquent Group By Relation

Hi,

I'm not too sure how to go about reporting an issue/bug even if it is.

////Model
public function leads()
{
return $this->hasMany('App\Models\Lead', 'trackingId');
}

////Controller
public function pageUsers($pageId){
return view('admin.lists.pageUsers', [
'trackings' => Tracking::where('pageId', "=", $pageId)->groupBy('trackingId')->get()
]);
}

////View
@foreach($trackings as $tracking)

{{ $tracking->id }}

@foreach($tracking->leads as $lead)
{{ $lead->firstName }} <--- Nothing displays
@Endforeach
{{ count($tracking->leads) }} <--- Displays 0
{{ $tracking->trackingId }}

{{ $tracking->referer }}
{{ $tracking->created_at }}

@Endforeach

Queue without listeners (background/cron)

Currently, there is a simple DB driver, but this still requires to setup a listener (and monitor that the process keeps running). For small sites, I usually find that there are some tasks that are slow and can be done using queues, but setting up the listeners + supervisor seems unnecessary complex.

Using the DB driver, we can have 2 alternatives:

  • Push to background, using a process in the background (eg. php artisan queue:work $id > /dev/null 2>&1 &. Fires directly (like sync), but isn't blocking. Downside: not 100% crossplatform. Example: https://github.com/barryvdh/laravel-async-queue
  • Schedule by cron. Instead of running directly, the cron scheduler calls a command to process the existing tasks in the queue. This isn't instantly, but every minute (or as often as the cron is run).
    This is also what Magento does for sending emails.

These two methods are not for 'heavy' sites, as they probably don't scale as well, but for simple sites it can be easy to just push emails to the queue without any additional config (aside from setting up the cron once). Both options can use the database driver.

The cron idea seems relatively easy to implement without configuration. What do you think?

Force Index on a query

I'd like to be able to push "FORCE INDEX (index_name)" into a query built with eloquent to force MySQL to use the correct index. I understand I can chain "->from(DB::raw('table_name FORCE INDEX (index_name)')" into a query but this is hardcoding a table name and doesn't seem laravel-esque given the query would break if the model/table name changed.

Having a forceIndex method that allowed an index to be specified (but not a table name) would ensure the query continues to follow the model's auto-detected table name.

I need this specifically to resolve an issue where MySQL is not able to find existing records when it tries to create an intersect between two indexes on the fly on a WHERE EXISTS sub-select like the one below. The issue is resolved by forcing MySQL to the correct index. Granted this is not laravel's problem but it would be handy (and tidy) feature.

select * from `messages` where exists (select * from message_routes where `message_routes`.`message_id` = `messages`.`id` and `owner` = ?) and `messages`.`id` = ?

Container can get contextual dependency for method by looking at method's class object

Basically a PR has already been made for it, so read all of the details there.

Usage:

class Foo
{
    public function bar(QueueContract $queue)
    {
        ...
    }
}

$container->when(Foo::class)->needs(QueueContract::class)->give(Queue::class);

$container->call('Foo@bar');

Also more fine grained contextual binding is possible:

$container->when('Foo@bar')->needs(QueueContract::class)->give(Queue::class);

This will get priority over any ->when(Foo::class) contextual binding.

Works in controller methods as well.

laravel/framework#12183

Capsule with bootEloquent(), setAsGlobal() using beginTransaction()

Hi all!

I'm using Capsule Manager to boot some Eloquent models, without Laravel. It's used inside some unit tests and I need to rollback the changes that are made. All my unit tests classes extends my own BaseTest with setUp() and tearDown() methods, where I begin transactions and make the rollback.

First I tried to get Capsule as global but Capsule::connection()->beginTransaction() and ->rollBack() is not working.

protected function setUp()
{
    foreach ($this->dbConnections as $name) {
        Capsule::connection($name)->beginTransaction();
    }
}

protected function tearDown()
{
    foreach ($this->dbConnections as $name) {
        Capsule::connection($name)->rollBack();
    }
}

Second I tried to begin transaction and roll inside my Eloquent model like:

$comment = new Comment;
$comment->getConnection()->beginTransaction();
// ... code
$comment->save();
$comment->getConnection()->rollBack();

No success in both cases.

Any suggestion?

Thanks.

Laravel Localization 2.0

As discussed many times on slack Laravel today needs a full-featured support for easily making multilingual websites out of the box. Right now there are only translation files and App::set/getLocale() and many core features missing:

  1. Laravel itself is not setting locale. It automatically can be done by 1st URI segment or by subdomain.
  2. Routes, URLs, requests can't be easily used with translated URLs containing 1st segment like "/de", for example, redirect to url when you don't need to manually pass a locale string.
  3. There is option to set default locale and fallback locale, but no way to set additional locales supported by application.
  4. Laravel still uses languages instead of locales, for example, "lang" folder and not "locale" folder, "en" folder and not "en_US". There were many thoughts that it must be renamed. However, I personally not a fan of doing ab_CD and having /ab-cd/ in URL all the time. Combining languages and locales together would be the best choice. FOr example, if user wants to see page in en_GB and app doesn't support this locale we can search in language itself, "en" in this case.
  5. From SEO point of view each URL should be unique. Same page in different language is a different page. Default language should not contain 1st URI segment or subdomain.
  6. Switching locale system (change language menu).
  7. Detecting user agent's preffered locale and redirecting if required.
  8. Detecting auth user's profile locale settings if exists and redirecting if required.
  9. Translated routes.
  10. Translated models. Probably not needed in Laravel itself.

Now about implementation:

This is codebase I am currently using. RIght now it works only with locales set as 1st URI segment and does not works with subdomains. And it does not handle translated models.

A. New config app.additional_locales which is an array of supported languages or locales (does not include default locale). For default locale app.fallback_locale is used.
B. New methods in Application class:

     /**
     * Get locale prefix for URI.
     * For additional locales will return slash and locale name, for example "/de"
     * For default locale will return an empty string ""
     * Result from this method used to easily add locale to any URL
     * If first param is passed, will check against this locale. Current app locale used by default.
     *
     * @param null $locale_to
     * @return string
     */
    public function getLocalePrefix($locale_to = null)
    {
        if ($locale_to === null) {
            $locale = self::getLocale();
        } else {
            $locale = $locale_to;
        }
        if ($locale === config('app.fallback_locale')) {
            $lang_prefix = '';
        } else {
            $lang_prefix = '/' . $locale;
        }
        return $lang_prefix;
    }

    /**
     * Get all locales supported by app (default and additional)
     *
     * @return array
     */
    public function getSupportedLocales() : array
    {
        $app_locales = config('app.additional_locales');
        $app_locales[] = config('app.fallback_locale');
        return $app_locales;
    }

    /**
     * Check if app supports $locale
     * If second param $lang is true then $locale will be set to ISO2 format, for example, "en_GB" will be "en"
     *
     * @param string $locale
     * @param bool $lang = false
     * @return bool
     */
    public function checkLocale(string $locale, $lang = false) : bool
    {
        if ($lang) {
            $locale = substr($locale, 0, 2);
        }
        return in_array($locale, $this->getSupportedLocales());
    }

    /**
     * Same as checkLocale() but instead of returning bool returns $locale if supported or default locale instead.
     *
     * @param string $locale
     * @param bool $lang = false
     * @return string
     */
    public function checkAndGetLocale(string $locale, $lang = false) : string
    {
        if ($lang) {
            $locale = substr($locale, 0, 2);
        }
        if (!in_array($locale, $this->getSupportedLocales())) {
            return $this->getDefaultLocale();
        } else {
            return $locale;
        }
    }

    /**
     * @return string
     */
    public function getDefaultLocale() : string
    {
        return config('app.fallback_locale');
    }

    /**
     * @return array
     */
    public function getAdditionalLocales() : array
    {
        return config('app.additional_locales');
    }

C. New LocaleServiceProvider (can be placed in AppServiceProvider also) which sets app locale.

    public function boot()
    {
        // set app locale
        if (in_array($s1 = Request::segment(1), config('app.additional_locales'))) {
            App::setLocale($s1);
        }
    }

D. Locale prefix added in RouteServiceProvider:

    public function map(Router $router)
    {
        $router->group(['prefix' => App::getLocalePrefix(), 'namespace' => $this->namespace], function ($router) {
            require app_path('Http/Routes/routes.php');
        });
    }

E. New lang array to store translated routes, for example for en - /lang/en/routes.php
F. New helpers:

function route_url($route)
{
    return url('/' . trans('routes.' . $route));
}

// used when swithcing language or building an URL for different locale
// for example, /about can be translated to /de/about
// or if translated route is used - /about-us to /de/uber-uns
function trans_url($locale = null)
{
    if ($locale === null) {
        $locale = config('app.fallback_locale');
    }

    $route_langs = Lang::get('routes');
    $detected_route = '';
    foreach ($route_langs as $route => $route_lang) {
        if (strpos(Request::getPathInfo(), $route_lang) !== false) {
            $detected_route = $route;
            break;
        }
    }

    $new_route_langs = Lang::get('routes', [], $locale);
    if ($detected_route !== '') {
        return App::getLocalePrefix($locale) . '/' . $new_route_langs[$detected_route];
    } else {
        $segments = Request::segments();
        if (isset($segments[0]) && '/' . $segments[0] === App::getLocalePrefix()) {
            unset($segments[0]);
            //dd(App::getLocalePrefix($locale) .'/' . implode('/', $segments));
        }
        if (App::getLocalePrefix($locale) !== '') {
            return  App::getLocalePrefix($locale) . '/' . implode('/', $segments);
        } else {
            return  App::getLocalePrefix($locale) . '/' . implode('/', $segments);
        }
    }
}

G. Since all logic can't be done in service provider, for example auth user is not initiated yet or redirect can't be used there should be also new Middleware - RedirectToLocale which detects user agent's preffered locale and logged in user's locale. Field (column) can be configured.

This approach also does not use sessions/cookies. It depends on HTTP referer header which is always sent by application. When user enters site for the first time, he can be redirected, but, for example, when user switches language from menu he should not be redirected again.

    public function handle($request, Closure $next, $guard = null)
    {
        if (App::getLocalePrefix() === '') {
            if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST']) !== false) {
                // if user was redirected from app itself, do not change locale and redirect him again
                // for example, user changed language from menu and was already redirected by this middleware
            } else {
                // if user logged in, redirect to locale from user account settings
                if (Auth::guard($guard)->check() && Auth::user()->profile_locale !== config('app.fallback_locale')) {
                    return redirect(trans_url(Auth::user()->profile_locale));
                } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
                    // if not logged in, check browser's preffered language
                    $lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
                    if (in_array($lang, config('app.additional_locales'))) {
                        return redirect($lang);
                    }
                }
            }
        }

        return $next($request);
    }

H. Extended Request::is()

    public function is()
    {
        foreach (func_get_args() as $pattern) {
            $pattern = App::getLocalePrefix() . $pattern;
            if (Str::is($pattern, urldecode($this->getPathInfo()))) {
                return true;
            }
        }

        return false;
    }

I. Extended UrlGenerator::to()

    public function to($path, $extra = [], $secure = null)
    {
        // if $path is external, do not add lang prefix
        if (strpos($path, '://') === false) {
            $path = App::getLocalePrefix() . $path;
        }

        return parent::to($path, $extra, $secure);
    }

Don't set error_reporting(-1) internally

At this time, error_reporting is set to -1 in HandleExceptions. I appreciate the fact that code should be bug-free, but this default prevents the server value from being used.

Imo error_reporting should be set from the server and this override should be controllable through the Exception Handler. This would allow for more control over this setting and allows the server (default) value to be read.

Would love some opinions on this.

User input data sanitation

Data sanitation in Laravel feels like a second class citizen, (http://www.easylaravelbook.com/blog/2015/03/31/sanitizing-input-using-laravel-5-form-requests/) unlike other frameworks:

I think it would be nice to pull something like https://github.com/daylerees/sanitizer into the core and work on a native way to include sanitation to form requests.

cc @daylerees

Synchronizing language files

The usual workflow

  • I develop a view which outputs a new message using trans('messages.my-message')
  • I then add that new message to resources/lang/en/messages.php
  • I synchronize the language file manually with other languages used in my app
  • I send the language files to translators for translation
  • Repeat that for next features/releases

The problem

In that process, there is a tedious manual step involved: synchronizing the language files

The translators should receive a file in their language that has all previously translated messages + all new messages which are not yet translated.

Currently, that can only be done manually and we can easily forget to add a message into one of the language files.

What is missing

Something rather simple, an artisan command such as php artisan lang:sync

That would take the default language as a parameter (by default 'en') and add/remove messages in other language files which are/are not in the en language.

Result is a consistent set of language files, with the same message keys. Missing messages could either be copied from the default language file OR set to be the message key (such as 'my-new-message' => 'messages.my-new-message')

PS: I am aware that there are a few packages out there dealing with that problem BUT they either offer something else (the one from Barryvdh has a full GUI) or they are not stable/production ready.

SparkPost Transaction Options

I recently began testing SparkPost for transactional emails and noticed that it was rewriting all my URLs for click tracking and inserting a small image for open tracking. While I think that is fine for marketing / campaign emails, I'd rather have those features disabled for transactional emails.

To disable these features, you need to include an options object in the JSON payload with the appropriate keys such as:

"options": {
    "open_tracking": false,
    "click_tracking": false,
    "transactional": true
}

There isn't an easy way to do this โ€” you must extend/override the send method in SparkPostTransport. I propose adding an options array to the sparkpost service configuration.

'sparkpost' => [
    'secret' => env('SPARKPOST_SECRET'),
    'options' => [
        'open_tracking' => false,
        'click_tracking' => false,
        'transactional' => true,
    ],
],

Maybe not adding this to the default services.php config, but at least supporting it? I'd be happy to make this improvement and submit a pull request. I feel like most users will send transactional email from Laravel and may want to opt-out of these features as well. Thoughts?

User Verification

Hi,
I suggest we integrate alongside with the register & auth process the verification functionality.
Here is a first draft as a package:
https://github.com/jrean/laravel-user-verification

The following specs have to be respected:

  • the verification process may not require a user to be authenticated
  • the verification process may not rely on the default User model

Cheers

Contextual binding parameters

I recently came up to a situation where I wanted to convert this

$this->app->when(Foo::class)
    ->needs(BarContract::class)
    ->give('bar.alternative1'); // Alias

$this->app->bind('bar.alternative1', function () {...});
$this->app->bind('bar.alternative2', function () {...});
$this->app->bind('bar.alternative3', function () {...});
$this->app->bind('bar.alternative4', function () {...});

into this:

$this->app->when(Foo::class)
    ->needs(BarContract::class)
    ->give(Bar::class, [$param1, $param2])

$this->bind(Bar::class, function ($app, $params) {
   return ...; // something based on $params
});

I am willing to provide a PR for this, looked into the code and it seems reasonable to implement it without breaking changes. But I will not send a PR if its going to be closed due to no interest.
That's why I'm asking here.

Allow validation rule parameters to be defined using arrays

It'd be great if we were able to specify parameters to validation rules as arrays -- for several reasons:

1.) It's tedious to append parameters with , between each item, sure this could be remedied by joining elements with the join function, but it's just more boilerplate when it doesn't necessarily need to be there.

2.) Sometimes I want to pass non-scalar types -- for example I'm using the Laravel Doctrine package and I'd like to be able to pass hydrated objects to my custom validators.

3.) I'd like to be able to retrieve my parameters in my custom validators by key/name instead of a cryptic/ambiguous numeric index

4.) If I'm subclassing a form request or simply building rules based on conditions, unless I do some preprocessing like manually construct everything (keyed parameters included) with arrays, and then flatten all the rules at the end of my rules implementation, I am forced to redefine rules that I don't necessarily need to change, because I don't have access to specific parameters in those rules since they are part of the rule definition.

Example of desired definition:

...
'user' => [
    'required',
    'exists' => [
        'table' => 'users',
        'column' => 'id',
        'exclude' => 2,
        ... // etc
    ],
    ...
],
...

The rules could be parsed as follows: rules with numeric keys would have no parameters and the element would be the rule, rules with string keys would use the key as the rule name, and the element would be the parameters. If a string key was used, and the value is not an array, the value would be parsed as a 0 indexed parameter to the rule.

Magic __get for Illuminate\Support\Collection

I would like to propose a magic __get method for the Illuminate\Support\Collection class to get the API more inline with, for example the Request class.
It also gives a somewhat nicer syntacs when you cast a database column with multiple fields to a collection.

@if( $content->has('photo') )
    <img src="{{ $content->photo }}" alt="">
@endif

Eloquent $model->fill() Relationships

With the awesome new array validation I think it would be extremely helpful if the fill() method on a model would fill relationships as well. I have been working with APIs that can create or update relationships and having to call multiple fill methods on the relationship. I also feel this would pair very well with the push() method already in models.

Currently you would have to write something like this to save attributes of related models:

$user->fill($attributes);
if (isset($attributes['address'])) {
  $user->address->fill($attributes['address']);
}
if (isset($attributes['posts']) && is_array($attributes['posts'])) {
  foreach ($attributes['posts'] as $post) {
    $user->posts->find($user->posts()->getQualifiedParentKeyName())->fill($post);
  }
}
$user->push();

I propose that this could be shortened to

$user->fill($attributes);
$user->push();

I think it would be wise for the $fillable array to be respected for relations.

It should be possible to both create an update *toMany relationships as well as long as the foreign key name/value pair is available in the item.

https://github.com/mattwells/framework/tree/recursive-fill

Addition of a combine() function to Collection class

I noticed that the laravel Collection class doesn't have a combine() function that is similar to the native php array_combine() but for collection. This is a really useful feature and its weird when one has to revert to array_combine() just for fullfil this.
I'm wondering if there is a reason as to why this was not implemented, else i would gladly help add it as a contribution to the laravel/framework code.

Would love to hear comments on why this is absent?

Eloquent Query to Get Count and Rows

Hi Is there any possible to get the row values and row count in a single query ? Some times we need to get the rows value and count of rows. So it will take two queries to get the result. Is there any possible to get it under one query like array first value will be count and second will be collection of rows?

[Request] Function to ignore relationship defined in model using $with

So there is a problem i've encountered while using polymorphic relationship, and getting related model of that relationship #6368. The only way to achieve that is by using $with in the model. But this aproach causes laravel to perform an extra query on pages where I already have that relation loaded. For example, I have a page where I load an Artist by it's slug from the url, and it's Song also by the slug from the url. If I use $with = ['artist'] in Song model, I get an extra query for the Artist I already loaded. So my proposal is a without($relations : array()) method to let me ignore some or all of the relationships defined via $with.

AuthenticatesUsers extract guard attempt to a separate method

Yesterday I was working on the project where I needed to slightly change the login method for authenticating user. It would be useful to have the Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember')) extracted to its own method, called for instance attemptToLogInUser().

This would allow any additional checks to be performed after identifying the user without necessity of overwriting the entire login() method.

Example would be:

/**
 * Handle a login request to the application.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return \Illuminate\Http\Response
 */
public function login(Request $request)
{
    $this->validateLogin($request);

    // If the class is using the ThrottlesLogins trait, we can automatically throttle
    // the login attempts for this application. We'll key this by the username and
    // the IP address of the client making these requests into this application.
    $throttles = $this->isUsingThrottlesLoginsTrait();

    if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
        $this->fireLockoutEvent($request);

        return $this->sendLockoutResponse($request);
    }

    if ($this->attemptToLogInUser($request)) {
        return $this->handleUserWasAuthenticated($request, $throttles);
    }

    // If the login attempt was unsuccessful we will increment the number of attempts
    // to login and redirect the user back to the login form. Of course, when this
    // user surpasses their maximum number of attempts they will get locked out.
    if ($throttles && ! $lockedOut) {
        $this->incrementLoginAttempts($request);
    }

    return $this->sendFailedLoginResponse($request);
}

/**
 * Attempt to log in user.
 *
 * @param  \Illuminate\Http\Response  $request
 * @return bool
 */
protected function attemptToLogInUser(Request $request)
{
    $credentials = $this->getCredentials($request);

    return Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'));
}

Scenario, which I was facing, required an additional check to disallow access for certain types of users - logic, which I could wrap with the following:

/**
 * Attempt to log in user.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return bool
 */
private function attemptToLogInUser(Request $request)
{
    $credentials = $this->getCredentials($request);
    $guard = Auth::guard($this->getGuard());
    $remember = $request->has('remember');

    $success = $guard->attempt($credentials, $remember, false);

    if ( $success && ! $guard->getLastAttempted()->isContractor() ) {

        $guard->login($guard->getLastAttempted(), $remember);
        return true;
    }

    return false;
}

A not match regex validation option

Laravel has the regex option which passes when the value matches a supplied regex.

Could we get an opposite method (similar to in & not_in) that fails if the value matches a supplied regex.

From what I can tell only two changes are needed:

Added to Validation/Validator.php

    protected function validateNotRegex($attribute, $value, $parameters)
    {
        if (! is_string($value) && ! is_numeric($value)) {
            return false;
        }

        $this->requireParameterCount(1, $parameters, 'regex');

        return !preg_match($parameters[0], $value);
    }

Added to resources/lang/en/validation.php

"not_regex"                => "The :attribute format is invalid.",

However i've never submitted a contribution before so wanted to start a discussion first, incase there were any complaints. There may also be better naming conventions than "not_regex". That's just what I used for my example.

Allow make:migration and make:model to add a Seeder

When creating a model you can add also create a migration using using artisan make:model Kitten -m. I am proposing adding a --seeder option to additionally create a Seeder class to match that model.

I also think you should be able to add a Seeder class when creating a migration:
artisan make:migration create_kittens_table --create --seeder.

I've worked up my suggested code for these two options at
laravel/framework@5.2...jwcobb:make-seeder-with-model

Is this something other people want? If so, are there any comments on the suggested code?

Default select for models

A select property would be used when calling read-style methods like find() when an explicit call to select() is not provided. The select property would exist at the base Model level with a default value and be overridden by extended Models.

By providing a default select clause, users would no longer have to explicitly call select() on relationship queries, thus allowing cleaner resulting code.

Public storage directories confusion

Our of the box on a fresh Laravel 5.2 application, you have the public disk defined in config/filesystem.php, which points to storage_path('app/public') with visibility public. Not being familiar with Flysystem, I would have expected that this directory would be configured to be publicly available via a URL, eg /storage/file.doc where the actual location is storage_path('app/public/file.doc'). But out of the box this isn't the case. What is the intended purpose of this directory? As far as I can see, in order to make the public storage directory actually public, I either need to make a controller that returns the file, or create a symlink in the public directory pointing to storage_path('app/public').

I also just noticed that the default .gitignore file has a /public/storage entry, which doesn't actually exist. So how is that directory supposed to be created?

Maybe it would make more sense for public/storage to always exist (by committing a public/storage/.gitignore), then make the public disk to point to public/storage?

Improve Typecasting

This has been discussed before in different issues raised laravel/framework.

I think it would be rather handy if Eloquent's typecasting was extendable, so that as well as being able to automatically cast to the existing:
integer, real, float, double, string, boolean, object, array, collection, date and datetime
That we could also cast to custom cast types.

For instance when using value objects this would allow the automatic casting of a dec to a Money type object.

Thoughts?

InteractsWithQueue::failed with message

I think it would be useful if jobs and the failed_jobs table could accommodate a failure message. I find more complex jobs can have multiple calls to $this->failed() but it's difficult to track which instance triggered the failure condition...

Re-use a non-expired password reset token

The behaviour from L4.2 is to delete any active (expired or non-expired) password reset tokens for a user every single time a password reset request is made. This has led us to many support calls. My solution would be to reuse (i.e. resend in the password reminder email) the current password reset token if there is one that has not expired.

The issue arises with users who have ISPs that are a little slow in delivering the email. We have tracked many issues from users who are unable to reset their passwords over the last 18 months, and believe we finally understand why. The users are usually told there is "a problem" resetting their password. We log a passwords.token status (was reminders.token in L4.2), meaning the token provided did not exist. We know it had not expired, and we don't even delete expired tokens at this point while trying to trace the user issue.

So what happens is a user tries to reset or recover their password, and waits for an email. It is a little slow arriving (and we narrow this down to certain offenders such as Southern Bell and EU outlook.com that are persistently slow). So the user enters their email address again to try to speed things up - like when we press the road crossing button twenty times to make the light change faster ;-)

Then the first email and token arrives and the user clicks the reset link. This is where they get the error, since the token that was only create a minute or two ago has now been deleted by their second reset request. So they try entering their email again, and end up in a cycle of emails that are out-of-step with the current password reset token stored on the database. Then they get frustrated, contact us, and that takes up everyone's time.

We have thousands of users in many countries around the world, mostly non-technical home users and schools and universities - including the Far East, so there are some tortuous routes for these emails to travel to get to the users. Their situation is very different to our fast links to our development and production servers and fast email servers (mine sits 3 metres away from my desk on a fibre leased line - there is no waiting around). ALL our users need to go through one password reset before they can use the system, as their accounts come from an external system, and are created for them in advance.

Log Behavior

Apologize if this is a bug, if it does, I will delete right away.

My Idea is to control the errors before the Log object is bind to the main container. For example: If there's an error in config/app.php the application will say something like:

PHP Fatal error:  Uncaught exception 'ReflectionException' with message 'Class log does not exist' in /Users/freek/dev/laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php:776
Stack trace:
#0 /Users/freek/dev/laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php(776): ReflectionClass->__construct('log')
#1 /Users/freek/dev/laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php(656): Illuminate\Container\Container->build('log', Array)
#2 /Users/freek/dev/laravel/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(644): Illuminate\Container\Container->make('log', Array)
#3 /Users/freek/dev/laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php(887): Illuminate\Foundation\Application->make('Psr\\Log\\LoggerI...')

Instead says where the error was. I am not pretty sure where to star this issue approach, but as I said, you guys can point me on the right direction.

Allow Gate to resolve interfaces?

As previously mentioned here: laravel/framework#11965
I think it would come in handy for Gate to resolve interfaces.
At the moment, the Gate is resolving the argument by get_class (see) if it's an object but there's much more we can do. If an interface can be used as the argument, we can exploit the potential of Gate: resolving based on type, multiple policies, etc. For example, we define a rule on modifying objects which implement BelongingContract of Illuminate\Contracts\Auth\Authenticatable. So we don't have to duplicate the logic in cases like: an user updates a comment or an author deletes his article.

class BelongingPolicy
{
    public function modify(Authenticatable $user, BelongingContract $thing)
    {
        return $user->id === $thing->user_id;
    }
}

We can also implement a "pipeline" to check the ability and arguments against policies, like middlewares you know. The type-check can be done by using e.g class_implements(), Reflection.
I would appreciate hearing your opinions on this. Thank you.

Decouple or allow overriding of Carbon

Correct me if I am wrong but as far as i'm aware there's no way of doing this currently.

It's certainly something i'd be interested in undertaking if it's agreed that it would be worthwhile.

Currently Carbon is used for Auth, Cache, Console Scheduling, Eloquent, the Artisan Optimize command, Queues (DB Interaction) and Session middleware.

What i'd propose is to allow any DateTime extending Class to be used as a Carbon replacement (but continue to use Carbon as the default). Perhaps this could be done through the app configuration, in the app service provider or another means - I'm not too sure what would be best suited yet as I havn't experimented.

This would be particularly useful for those who wish to:

  • Extend Carbon (fairly likely)
  • Translate Carbon (fairly likely)
  • Replace Carbon (fairly unlikely?)

i guess if this was something that was undertaken it would also affect Lumen (since it uses a number of the illuminate components which would obviously be the areas of the internals that are affected).

Thoughts?

Migration simulator

This is a 2 months old proposal posted on laravel/framework (closed since proposals are not discussed there).

As you know, wrapping database migrations in a transaction has no effect in Mysql for table operations.
Which means that if migration fails, you most likely end up with a broken database state which stinks!!!

I made a package that simulates the migrations in a testing database and report back success or failure to the user, leaving the real production database intact.

So the main idea behind this is the following:

  • We create a testing database for every connection specified by the user (or use the default one).
  • We switch the configuration to the new database at runtime, replacing the real database.
  • We refresh the connection so that Laravel can use the new configuration.
  • We run php artisan migrate against the testing database.
  • When done, we drop the testing database.
  • Any eventual errors are displayed to the user.
  • The real database stays intact.

This could be a great addition to the framework. I'm sure you can come up with a better implementation.

Working code https://github.com/shincoder/harmless-migration

Haven't experienced any issues so far.

Php artisan app:name allows special chars

Hi !

I'm pretty new to Laravel and the world of web development in general, but I feel like this is something I had to signal somewhere :

When using the php artisan app:name command, there's no restriction on the name you give to your app. For example, I used php artisan app:name laravel-people and the hyphen broke my project.

Wouldn't it be possible to prevent people from trying to use this kind of special characters in the command ?

Custom Password Resetting

While I think the scaffolding that Laravel provides for resetting passwords is great, and excellent work has been done to make it as customizable as possible, I think some tweaks could be made to give users full control over it.

There are two reason why I am bringing this up. First off, even though a lot of customization is built in, I think it's difficult or impossible to provide all of the customization an end user could want. The second reason is because most of us have a certain way of building our sites, and building our controllers, services, etc. With the built in password controller, now we have one spot in our app that behaves differently than every where else, which makes it a little harder on the developer (or future developers) to immediately know what's going on.

To reset a password, the programmers essentially cares about two things. Creating a unique token, and then checking that token. Emailing, updating the password, rendering views, redirecting, and the like are all more superfluous things that Laravel already makes it easy for us to do. So what I would propose is the PasswordBroker has 2 public methods for these things.

$broker->generateToken(CanResetPasswordContract $user); //returns a string

which would create the token and store it to the database, and

$broker->validateToken($credentials); //returns a boolean

which would validate the passed in token against the database and then delete it if valid.

While this way of handling password resets wouldn't be for everyone, it would give users who want full control these easy to use methods, and then they are required to handle everything else (emails, views, redirecting).

I just currently did basically this with a project of mine (I needed more control of the emailing), and although it was doable, it was not easy like I've grown accustomed to with Laravel. I'm assuming others may have done this as well, so looking for some feedback.

Just to be clear, I am not arguing to get rid of the current scaffolding, but rather just give tools to the users who wish to implement it themselves.

Thanks!

Post the output of a completed job to a URL

Currently, ->thenPing($url) just does a GET request to a URL you specify to let you know the scheduled command has run.

Either modifying it to support POSTs or creating a new method like ->thenPost($url) would allow you to send the output to another application for further processing.

For example, you could have your Laravel app send the POST request to Zapier which then formats it and could pass it along to any number of services (Slack, Google Docs, etc).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.