Quantcast
Channel: Laravel News
Viewing all 1744 articles
Browse latest View live

Podcast: Laravel Valet with Taylor Otwell and Adam Wathan

$
0
0

Laravel Valet is a new high-speed development environment by Taylor Otwell and Adam Wathan.

In this special edition episode of the Laravel News Podcast Eric and Jack are Joined by Taylor and Adam as they discuss everything about Valet, how it came to be and the amazingly short time from idea to completed product. They talk about the internals, how it works, how external sharing works, the driver architecture and more.

An audio copy of the Official Valet Commerical is at the end of the episode

Show Links


Podcast: Laravel Echo, Valet, and PHP-FIG implosion

Podcast: Jack reads the news

$
0
0

Jack reads the laravel related news this week. Eric is off this week.

All the news from issue 105 of the Laravel-News.com newsletter.

  • Laravel is turning 5
  • Original "Introducing Laravel" post from Taylor
  • New Spark Tutorial added this week.
  • Several new articles on dotdev.co on using git for Branching, merging and rebasing (great articles)
  • Several articles on using view Composers
  • Contract testing
  • Multiple Migrations Paths coming in Laravel 5.3
  • Cascading softdeletes with Laravel 5 (package)
  • Scaffolding with custom commands by Amo Chohan
  • Laravel API generator
  • Laravel Docusign
  • Request rate limiter middleware for Laravel 5.2+

Podcast: A look at what's coming to Laravel 5.3

Podcast: Refactoring to Collections with Adam Wathan

Podcast: Laracon, Laravel 5.3 Advanced Where, October CMS, Canvas

Podcast: The Laracon US 2016 Special With Taylor Otwell, Evan You, Chris Fidao, and Adam Wathan

DreamFactory API automation for any database (sponsor)

$
0
0

DreamFactory auto-generates a rich API platform from nearly any SQL or NoSQL database. In addition to automatically generating REST endpoints for data and schema, DreamFactory offers parameters for complex filters, virtual foreign keys, aggregation, and much more.

df-main-infographic-700px

Built on the Laravel framework, DreamFactory is feature-rich backend solution for real world application development. Instant APIs let you build and iterate fast and the Apache license allows for wide distribution.

Exploring the options for a healthcare application built with DreamFactory.
Exploring the options for a healthcare application built with DreamFactory.

The base DreamFactory code is open source and is freely deployed. DreamFactory Silver uses the same code and adds commercial database functionality and dedicated support. DreamFactory Gold is an enterprise solution for fully realized developer ecosystems offering granular user and resource management along with exceptional support direct from our engineering team.

Recent blog posts:

Try it out now on our free hosted system or dig deeper into the possibilities with robust documentation and sample apps for a wide array of front-end destinations.


Laravel Lambo – A package to quickly scaffold out a new project

$
0
0

Laravel Lambo is a new package by Tighten.co that allows you to quickly scaffold out a new Laravel application from your terminal.

It works similar to laravel new but supercharged. For example, you start a new project like this:

lambo myproject

Then behind the scenes it runs the following commands:

laravel new $PROJECTNAME
cd $PROJECTNAME
git init 
git commit -am 'Initial Commit'

Next, it modifies your local .env to add your database credentials and replaces APP_URL with the project name, then opens up the browser to your URL.

Lambo is Mac only and requires both the Laravel command line installer and Laravel Valet.

Check out the GitHub repo for complete instructions and installation.

Laravel 5.3 is now released

$
0
0

The Laravel team is proud to announce the release of Laravel 5.3 and it’s now available for everyone. The new features in 5.3 are focused on improving developer speed by adding additional out of the box improvements for common tasks.

This is a general release and comes with six months of bug fixes and security fixes are provided for one year. Laravel 5.1 is the latest LTS release which includes bug fixes for two years and security fixes for three years.

Here is a quick overview of some of the highlights of the new 5.3 release:

New Home Page

laravel-homepage

The home page received a makeover with boxes showcasing the new packages, and more community resources including links to Laracast, Laravel News, and Statamic.

Laravel Scout

Laravel Scout is a new driver based full-text search engine for Eloquent. Scout works by adding a new Searchable trait to your models, syncing your data to the index of choice, and then you can search as easily as:

Post::search('Alice')->get();

Laravel Passport

Laravel Passport is designed to give you everything you need to deploy your own OAuth2 server in a matter of minutes. It’s an optional package that comes complete with the ability to set your scopes, Vue.js components for token generation, revoking tokens, and more.

Laravel Mailable and Notifications

Laravel Mailable is a new class-based approach to sending emails that will allow you to simplify sending email by removing the need for the closure style.

Laravel Notifications allow you to send out quick updates through services like Slack, Text messages, Email, and more. The community has even started a “Laravel Notifications Channel” group where anyone can submit drivers and it already includes over twenty-six drivers.

Laravel Echo

Laravel Echo is an improvement to the existing event broadcasting system that makes it easy to work with web sockets. To utilize Echo the backend will ship with the Laravel core and then you will need to pull in an NPM package for the JavaScript side.

Migrations

The migrations system received a new feature that will allow you to rollback a single migration.

php artisan migrate:rollback --step=1

Previously, this option did not exist and you could only rollback a single batch, which could contain multiple steps.

Simple Pagination

Laravel offers two styles of pagination. An advanced style that shows a list of page numbers and a simple style that only show a previous and next link.

Starting with this release the simple pagination will now be available from a view file which makes it easier than ever to customize to your sites design and HTML structure.

Blade Loop Variable

Laravel Blade received a new $loop variable that will give you finer grain control within your loops. Now you can use the following properties:

  • index – The number of the loop.
  • remaining – How many loops remain
  • count – The total count
  • first – If it’s the first loop
  • last – If it’s the last
  • depth – How many levels deep you are.
  • parent – Allows you to call the parent in a nested loop.

For more on this see Matt Stauffer’s blog post.

Directory Changes

The “app” folder was simplified by removing all the empty folders like Events, Jobs, Listeners, and Policies. This remains fully backward compatible and if you run any Artisan “make:” command related to these features the folder will get added back.

Queued Jobs

Eloquent Collections are now cleanly serialized and re-pulled by queued jobs the same way individual models are.

This is beneficial in the cases where the data in the Eloquent Collection has changed since the job was pushed onto the queue.

Query Builder

The query builder will now return a Collection by default instead of an array. This is potentially a breaking change but it will now keep results from either the query builder or Eloquent uniform.

Cache Helper

Laravel 5.3 includes a new cache() global helper that allows you to get, put, or return an instance of the backing service. For more information check out Matt’s post on this.

Documentation Changes

The documentation received a huge overhaul for this release. It’s now divided into better sections that guides you from installation all the way through Laravel’s official packages. It is also linking to relevant free Laracasts videos on certain topics. This will cater to either people that prefer audio/video for learning and those that enjoy reading.

Upgrade Guide

The official documentation has the upgrade guide which includes all the information you need to start using 5.3 today. It estimates the total time of upgrading at two to three hours.

Thank you

I’d like to personally thank everyone that contributed to this release and for making it possible. Adding all these new features was a huge undertaking and everyone that helped out deserves a pat on the back.

Be sure and join the Laravel weekly newsletter to stay up to date with all the new packages, tips, and tutorials that is sure to come out. Also, Laracasts has a free series on all the main new features as well as Matt Stauffer.

Learn about Grant Types in Laravel Passport

$
0
0

OAuth2 is a security framework that controls access to protected areas of an application, and it’s mainly used to control how different clients consume an API ensuring they have the proper permissions to access the requested resources.

Laravel Passport is a full OAuth2 server implementation; it was built to make it easy to apply authentication over an API for laravel-based web applications.

Terminology

Before going any further, we need to understand the following definitions:

Client
This is the application trying to consume our API, creating clients in Passport is done via this console command:

php artisan passport:client

Every client will have a key, name, secret, redirect URI, and a user (Application Creator/Owner).

Resource Owner
This is the entity (User) that owns the data a client is trying to consume.

Resource Server
That’s our API; it may have public data that doesn’t require an owner permission to read, and other private data that requires an owner permission.

Public endpoints can be, for example, the endpoint for searching tweets, that doesn’t require a specific resource owner permission.

On the other hand, an endpoint that posts tweets on behalf of a user is a private endpoint, interacting with such endpoints requires permission from the resource owner.

Scope
It’s a permission to access certain data, or perform a certain action.

You may define scopes using Passport::tokensCan() method inside your AuthServiceProvider.

Passport::tokensCan([
    'read-tweets' => 'Read all tweets',
    'post-tweet' => 'Post new tweet',
]);

Grant
It’s the method used to get an access token.

Access token
That’s the token an app (client) needs to communicate with the server (API).

How to Authorize third-party apps

First, we need to create a test app using the following command:

php artisan passport:client

Laravel Passport will prompt asking you for the user ID, app name, and the redirect URI.

Now that we have the client registered we can now get an access token using the “Authorization Code Grant”.

This type of grants works by pointing the browser to the authorization server where the user can log in to his account and grant access to the app, once access is given the app shall send another request asking for an access token, using this token the app will be able to make further requests.

For most of the cases you’ll be using this grant type to allow all kind of applications to consume your laravel-based API private endpoints, this includes server-side apps, JavaScript apps, & native mobile apps.

Step 1: Asking for permission

From the client app, you’ll need to point the user to the following URL:

http://resources.dev/oauth/authorize?client_id={CLIENT_ID}&redirect_uri={URI}&response_type=code&scope={SCOPE}

Using the correct CLIENT_ID & URI as in the client created by passport.

You can list the scopes as a space separated list of permissions you’d like to get from the resource owner, for example:

read-tweets post-tweets follow-others

Now if Passport was installed correctly such that the routes are published in your AuthServiceProvider, if all is well the above request will show a nice screen asking the user to give permission to the app, the screen will list all the scopes the app is asking for.

In case the user denied access, Passport will redirect the user to the given redirect_uri with error=access_denied in the URL.

However, if the user approved access, Passport will redirect to the redirect_uri with code={authorization_code_here}.

Step 2: Getting an access token

Now that we have the Authorization Code, we need to send a POST request to http://resources.dev/oauth/token to get the access token, the body of the request should contain the following:

  • grant_type: authorization_code
  • client_id: the one created by Passport
  • client_secret
  • redirect_uri
  • code: The given Authorization Code

The response is going to be a JSON object with the following keys:

{
    "token_type": "Bearer",
    "expires_in": 3155673600,
    "access_token": "eyJ0eXAiOiJKV1QiL....",
    "refresh_token": "XslU/K6lFZShiGxF1dPyC4ztIXBx9W1g..."
}

Refreshing an access token

By default the access_token will not expire for 100 years, if you don’t mind this then you don’t need to save the refresh token, otherwise, if you’d like the access_tokens to have a short lifetime you can tell Passport:

Passport::tokensExpireIn(Carbon::now()->addDays(15));

Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));

If your tokens are short-lived, then the client needs to save the refresh_token to use it later to issue a new access token.

To refresh an access token the client needs to make a request to http://resources.dev/oauth/token with the following parameters:

  • grant_type: refresh_token
  • client_id: the one created by Passport
  • client_secret
  • refresh_token
  • scope

Authorizing first-party apps

If you’re authorizing a trusted app of your own there’s no need for such a long road to get an access token, you only need to ask the user to provide a username/email & password in order for the app to get an access token. This type of grants is called Password grant.

You need to check your database to grab the password client created by Passport.

To get an access token for a first-party app you need to make a POST request to http://your-app.com/oauth/token with the following parameters:

  • grant_type: password
  • client_id:
  • client_secret
  • username
  • password
  • scope

The response is going to be a JSON object with the following keys:

{
    "token_type": "Bearer",
    "expires_in": 3155673600,
    "access_token": "eyJ0eXAiOiJKV1QiL....",
    "refresh_token": "XslU/K6lFZShiGxF1dPyC4ztIXBx9W1g..."
}

Authorizing an app manually

Passport ships with a way to create access tokens manually, this is useful in multiple situations such as testing during development or maybe if you allow authenticating users on a third-party application via their mobile number instead of a login web form.

For example, a third party app may show a phone field for the user, when filled a service on your server sends an SMS to that number with an access code, the user will input this code upon reception in which the app will exchange with an access token from your server.

To create an access token:

$token = $user->createToken('Pizza App', ['place-orders', 'list-orders'])->accessToken;

Scratch and Win Contest

$
0
0

To have a little weekend fun I’m running a Laravel themed giveaway. How it works is you enter your name and email and then using your mouse you scratch over the elephant to see if you win. That’s all it takes.

Here is a list of prizes up for grabs:

Enter now and see if you are one of the lucky winners.


I’d like to thank Contest Kit for working with me on this and everyone behind all the cool prizes.

Upgrading your Laravel Application with Laravel Shift

$
0
0

We’ve covered Laravel Shift before and it’s a commercial project that will take a Laravel app and automatically upgrade it or shift it to the next version. This site was running Laravel 5.2 and now that 5.3 is released it was time to upgrade and I decided to give Laravel Shift a try.

The setup is easy. You signup using oAuth of where your repository is hosted. Enter your repository details, and make payment.

Within a few minutes, Laravel Shift automatically creates a pull request complete with all the changes needed and a list of notes that you need to go through to complete the upgrade.

laravel-shift-notes

By using this service it will drastically reduce the time it takes to upgrade your app and I’m amazed at how well it works. If you are dreading upgrading or short on time, give Laravel Shift a try. You will not be disappointed.

Authentication Enhancements in Laravel 5.3 – Sponsor

$
0
0

TLDR Laravel 5.3 was released at the recently concluded LaraconEU conference. Laravel 5.3 ships with a lot of new features and awesome improvements to different sections of already existing features. Authentication is one of those features that Laravel provides to developers out of the box and there have been some really good improvements to it in Laravel 5.3. In this post, I’ll walk you through these enhancements and how you can savor this goodness in your applications!

The following are the top 6 authentication enhancements in Laravel 5.3:

#1. Better authentication response handling: In Laravel 5.2, you have to write more code to handle unauthenticated users, especially when you are writing custom logic for authentication. In Laravel 5.3, all you need to use is the new authenticate method. This is a simple illustration below:

The authenticate method simply throws a global AuthenticationException that Laravel catches and handle if the user is not logged in. Check your app/Exceptions/Handler.php , there is an unauthenticated method that is fired when the AuthenticationException is thrown. You can simply customize the redirect page or json response in this single location as shown in the image below:

#2. Authenticate Middleware moved to core: In Laravel 5.2, four middleware files are shipped with the new app skeleton. In Laravel 5.3, only three middleware files are shipped with your app skeleton. The Authenticate middleware has been moved into Laravel core, thus forcing developers to make response customizations in the unauthenticated method of the app/Exceptions/Handler.php file.

#3. Multiple guard authentication in auth middleware: You already have guards in your application, e.g, the web and api guards. The auth middleware can now automagically check any of those guards passed to it — the request will be authenticated and the guard used by the admin user (can be any user) will be set as default, so that subsequent calls to auth()->user() will return the user details.

Route::get('admin', [
    'uses' =>  'AdminController@index',
    'Middleware' => 'auth:web,api'
]);

#4. Guard customization: In Laravel 5.2, you could customize the guard that is used to authenticate users by defining a guard property on your AuthController and assigning one of the guards configured in your auth.php config file like so:

Laravel 5.2

protected $guard = ‘api’;

In Laravel 5.3, you have to define a guard method on your LoginController, RegisterController and ResetPasswordController like so:

Laravel 5.3

use Illuminate\Support\Facades\Auth;

protected function guard()
{
    return Auth:guard('name-of-guard');
}

#5. Global scopes and Route Model binding: In Laravel 5.2, if you are using route model binding and you have a global scope on your model that needs access to the current user via the auth() helper method or Auth facade, the current user returns null. Why? Because the route model binding runs before the authentication middleware is invoked thus making the model impossible to resolve the current logged-in user. An illustration is shown below:

//ProjectController.php
public function show()
{
    // display the project
}

// Project.php - Model
class Project extends Model
{
    protected static function boot()
    {
        static::addGlobalScope(function ($query) {
            $query->where(‘written_by’, auth()->email);
        });
    }
}

// routes.php
Route::get('projects/{project}', [
    'uses' => 'ProjectController@show',
    'middleware' => 'auth',
]);

In Laravel 5.3, the current logged-in user can now be obtained in your global scopes because the middleware stack has been rewritten in a way that the authentication middleware will always run before the route model binding!

#6. App Authentication Skeleton ships with four controllers: In Laravel 5.2, only two authentication controllers are shipped out of the box, AuthController (handles user registration and authentication) and PasswordController (handles resetting users forgotten passwords). In Laravel 5.3, there are now four authentication controllers:

  • ForgotPasswordController – handles e-mailing links for resetting passwords,
  • LoginController – handles authentication,
  • RegisterController – handles new user registration,
  • ResetPasswordController – handles resetting user passwords

Each of these controllers has its own traits. I really like how the controllers are split right now, this encourages separation of concerns and single responsibility patterns in Object-Oriented PHP programming.

A lot of work has also gone into enhancing the already existing authorization techniques. Joseph Silber has got them covered here.

Note: If you are new to Laravel and want to get your hands dirty with creating your first app, check out https://auth0.com/blog/creating-your-first-laravel-app-and-adding-authentication/

Aside: Using Auth0 with Laravel

Auth0 issues JSON Web Tokens on every login for your users. This means that you can have a solid identity infrastructure, including single sign-on, user management, support for social identity providers (Facebook, Github, Twitter, etc.), enterprise identity providers (Active Directory, LDAP, SAML, etc.) and your own database of users with just a few lines of code.

We can easily set up authentication in our Laravel apps by using the Lock Widget. If you don’t already have an Auth0 account, you can sign up for one now. Navigate to the Auth0 management dashboard, select Applications from the navigational menu, then select the app you want to connect with Laravel.

There is a comprehensive quickstart for laravel-auth0 webapp and RESTful API integration that can walk you through setting it up in less than three minutes!

Auth0 Lock Widget

With Auth0, you can have all your users information stored without having to run your own database. You can configure the Lock UI, which provides powerful analytics about users signing up on your platform such as, the browser the user logged in with, the location, device, number of logins, and more, out of the box!

Analytics

Auth0 also offers a cool feature called password breach protection. With breached password detection, you can protect your users and services from password leaks that occur on third party sites. The feature notifies your end-user that their password has been compromised somewhere else and you can optionally require step-up authentication or prevent that login until they reset their password.

Password breach protection

Conclusion

Authentication and authorization are powerful features of every application. Not getting it right means opening yourself and your firm to potential financial and reputation loss as well as lawsuits. You can check the laravel docs and source code to get to know a lot more about how authentication and authorization work in Laravel 5.3.

Lastly, if you want to add authentication to your Laravel apps in a breeze, Try Auth0 for free. You will get a production ready account with up to 7000 active users! Instead of worrying about your authentication component’s implementation details, testing, bugs, and extensibility, you can just focus on your application’s business logic.


Many thanks to Auth0 for sponsoring this tutorial via Syndicate Ads.

Controller Construct Session Changes in Laravel 5.3

$
0
0

Back in laravel 5.2, a developer was able to interact with the session directly in a controller constructor. However, this has changed in laravel 5.3.

The difference between how the 5.3 & 5.2 handle an incoming request is that in 5.2 the request goes through 3 pipelines:

  1. The global middleware pipeline
  2. The route middleware pipeline
  3. The controller middleware pipeline

By default the global middleware only contains a check for maintenance mode, the route middleware is what you assign to a route in your routes.php file, and by default, a web group is assigned to all web routes that contains several middlewares including the middleware that starts the session.

And then finally Laravel instantiates your controller to check for controller middleware, at this point, the request is all set up during the first and second pipelines, that’s why we were able to use sessions and auth in the controller constructor because the request is ready for it.

In 5.3 the request goes through only 2 Pipelines:

  1. The global middleware pipeline
  2. The route & controller middleware in 1 stack

Laravel collects all route specific middlewares first before running the request through the pipeline, and while collecting the controller middleware an instance of the controller is created, thus the constructor is called, however at this point the request isn’t ready yet, and that’s where the change in behaviour you notice in 5.3 exists.

The reason for this change is as Taylor described:

It’s very bad to use session or auth in your constructor as no request has happened yet and session and auth are INHERENTLY tied to an HTTP request. You should receive this request in an actual controller method which you can call multiple times with multiple different requests. By forcing your controller to resolve session or auth information in the constructor you are now forcing your entire controller to ignore the actual incoming request which can cause significant problems when testing, etc.

Using sessions in your constructor in 5.3

Maybe it was a bad practice to use the constructor of the controller to access session variables. However, it looks like a good chunk of laravel developers were using this approach and considered the constructor as an inline middleware where they can check if the user can access certain methods in this controller or not.

So the core team came up with a solution for this matter, it’s described in the upgrade guide as follow:

As an alternative, you may define a Closure based middleware directly in your controller’s constructor. Before using this feature, make sure that your application is running Laravel 5.3.4 or above:

Here’s the example from the docs:

<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Controllers\Controller;

class ProjectController extends Controller
{
    public function __construct()
    {
        $this->middleware(function ($request, $next) {
            $this->projects = Auth::user()->projects;

            return $next($request);
        });
    }
}

Vue.js 2.0 RC4 is now available

$
0
0

Today Vue.js released it’s fourth V2 release candidate and this version is primarily a bugfix release with one new feature.

A new Async component function now supports returning a Promise. Note if you are using async components with vue-router you need to update vue-router too.

You can find the full changelog from their release page and they also have a starter kit available for those that want to start using V2 now.

Simple Regex Language is aiming to simplify Regular Expressions

$
0
0

Simple Regex Language is a new PHP package that aims to simplify regular expressions using a cleaner written word approach to the syntax. Here is an example of validating an email address:

begin with either of (number, letter, one of "._%+-") once or more,
literally "@",
either of (number, letter, one of ".-") once or more,
literally ".",
letter at least 2 times,
must end, case insensitive

Which parses into the following expression:

/^(?:[0-9]|[a-z]|[\._%\+-])+(?:@)(?:[0-9]|[a-z]|[\.-])+(?:\.)[a-z]{2,}$/i

Or if you prefer a PHP flavored approach:

$query = SRL::startsWith()
    ->eitherOf(function (Builder $query) {
        $query->number()
            ->letter()
            ->oneOf('._%+-');
    })->onceOrMore()
    ->literally('@')
    ->eitherOf(function (Builder $query) {
        $query->number()
            ->letter()
            ->oneOf('.-');
    })->onceOrMore()
    ->literally('.')
    ->letter()->atLeast(2)
    ->mustEnd()->caseInsensitive();

You can find more details on the SRL and find all the code on GitHub.

Easily deleting old soft-deleted records with Quicksand

$
0
0

When building applications, there are times when you would like to allow users to remove data from their view but keep the record in the database. An example could be allowing a user to delete their account, but you want to give them the opportunity to restart it later. If all their data is completely removed, then they would have to start completely over.

Laravel’s Eloquent provides this ability out of the box, and when models are soft-deleted, they are not removed from the database. Instead, a deleted_at attribute is stored. The database record remains, and Eloquent ignores it unless explicitly told otherwise by a withTrashed attribute.

One problem with this is over time your soft-deleted records can fill up your database and take up a lot of space.

Tighten Co. recently released a new package called “Quicksand” which will help you solve this problem by automating and scheduling the deleting of old soft-deleted records.

Quicksand is an Artisan command that you can run through the Laravel scheduler to force the deletion of your soft-deleted records. You can specify which classes you want to clean up, how long the records should remain, and it does the rest. Let’s take a look at this package.

Installation:

First, install Quicksand through Composer:

composer require tightenco/quicksand

Then add Quicksand Service provider in config/app.php:

'providers' => [
    ...
    Tightenco\Quicksand\QuicksandServiceProvider::class,

After that you should publish Quicksand config to edit it as you want, run the following command in your terminal:

php artisan vendor:publish --provider="Tightenco\Quicksand\QuicksandServiceProvider"

Finally, Schedule the following command by adding it in app/Http/Console/Kernel.php:

protected function schedule(Schedule $schedule)
{
    $schedule->command('quicksand:run')
        ->daily();
}

Quicksand Options

Let’s take a look at the available options in Quicksand that are available in the config/quicksand.php file

return [
    // Days before deleting soft deleted content
    'days' => 30,

    // Whether to log the number of soft deleted records per model
    'log' => false,

    // List of models to run Quicksand on
    'models' => [
        // Example::class,
        // User::class => [
        //     'days' => '30' // per-model days setting override
        // ]
    ]
];

First, you have the option to set the days before permanent removal, an option to turn logging on or off for the number of soft deleted records. Lastly, the most important option is the “models” array where you can add the list of models that you would like Quicksand to do its cleanup process on.

You can add your models simply like this:

User::class,

Or if you want more control, you can override the days for a particular model independently like this:

Post::class => [
    'days' => '60' // per-model days setting override 
]

If you are curious about how it works, here’s the core of it:

quicksand-delete

What Quicksand is doing is fetching all the soft-deleted records using the onlyTrashed method, then limits based on the deleted_at column when it’s less than the config days and finally force deletes the results.

That’s it, simple options, easy to use, and a very convenient package. If you are looking to automate the cleanup of your soft deleted records give these a try and you can check out the source code of Quicksand at Github

Another package that would make a great pairing with Quicksand is Cascading Soft-Deletes for when you want to delete all associations.

How to Create A Most Popular List with Laravel and Google Analytics

$
0
0

Here on Laravel News, I wanted to generate a list of the most popular posts for the past seven days and display the results from most popular to least popular.

To solve this problem I thought of two solutions. The first is to build my own tracking system so I could keep a count and then use it for ordering. However, that could generate a huge amount of data and it seemed like a solution that an analytics tracking service could handle.

As I was fumbling through the Google Analytics API I found a Laravel Analytics package by Spatie.be that allows you to easily retrieve data from your Google Analytics account and it seemed like the best way to solve this problem. Let’s look at how I used it to generate a list of popular posts here on Laravel News.

Installation and Setup

The installation is typical for any Laravel package, you first install the package through composer:

composer require spatie/laravel-analytics

Next, add the service provider to config/app.php

'providers' => [
   Spatie\Analytics\AnalyticsServiceProvider::class,
];

Finally, add the Facade to the same config/app.php

'aliases' => [
   'Analytics' => Spatie\Analytics\AnalyticsFacade::class,
];

Once that is setup the hardest part of the process begins and it’s no fault to the package. It’s just that Google has a crazy system in place for generating credentials. It will be best to visit this section of the readme as it steps through how to set this up complete with screenshots.

Fetching the most popular

The Analytics package makes fetching the data simple and here is an example for grabbing the most popular pages over the past seven days with a limit set:

$pages = Analytics::fetchMostVisitedPages(Period::days(7), $limit);

Then it returns a Laravel Collection of the results that look something like this:

Collection {#400 ▼
  #items: array:17 [▼
    0 => array:3 [▼
      "url" => "/"
      "pageTitle" => "Laravel News"
      "pageViews" => 10
    ]
    1 => array:3 [▼
      "url" => "/"
      "pageTitle" => "Laravel News - News and information about Laravel"
      "pageViews" => 9
    ]
    2 => array:3 [▼
      "url" => "/2016/06/look-whats-coming-laravel-5-3/"
      "pageTitle" => "A look at what’s coming to Laravel 5.3"
      "pageViews" => 8
    ]
    3 => array:3 [▼
      "url" => "/2016/06/look-whats-coming-laravel-5-3/"
      "pageTitle" => "A look at what's coming to Laravel 5.3 - Laravel News"
      "pageViews" => 7
    ]
    4 => array:3 [▼
      "url" => "/2016/08/laravel-5-3-rc1-is-now-released/"
      "pageTitle" => "Laravel 5.3 RC1 is now released"
      "pageViews" => 6
    ]
  ]
}

If you notice the top two results are of the home page, then the second two are of the same post, and the reason these show twice is because the titles are different. One set is from before I changed the titles on the site and one set after.

Another issue is that I don’t want the home page to be in the list at all. I’d prefer this to be limited to posts only.

Let’s work through cleaning these up as we complete the integration.

Building A Wrapper Class

Now that I am getting results and I know I’m going to need to parse them I decided to create a class that will handle the fetching and the processing.

I created a new file named app/Services/Trending.php and stubbed it out with the basic fetching code:

<?php

namespace App\Services;

use Analytics;
use Spatie\Analytics\Period;

class Trending
{
   public function week($limit = 15)
   {
       return $this->getResults(7);
   }

   protected function getResults($days, $limit=15)
   {
       return Analytics::fetchMostVisitedPages(Period::days($days), $limit);
   }
}

Now calling this should give us the same results as before and here is an example call:

$trending = app('App\Services\Trending')->week();

Next, it needs another method to parse the results. As mentioned earlier it needs to remove any duplicates, remove any pages that are not actual posts, and also remove the “ – Laravel News” suffix on titles that Google is reporting on.

Because the results from the fetchMostVisitedPages is a Collection this allows us to easily utilize all its methods and here is the finished method:

protected function parseResults($data)
{
   return $data->reject(function($item){
       return $item['url'] == '/' or
       $item['url'] == '/blog' or
       starts_with($item['url'], '/category');
   })->unique('url')->transform(function($item){
       $item['pageTitle'] = str_replace(' - Laravel News', '', $item['pageTitle']);
       return $item;
   });
}

If we step through this it first rejects any items with the url of “/“, or “/blog”, or if the url starts with “/category”. These are my three primary sections that generate enough traffic where they would show in the list.

Next, it calls, ->unique('url') to prevent any duplicate url’s from passing through.

Finally, a ->transform() call to strip the “ – Laravel News” suffix.

Next, modify the getResults so it uses the parser:

protected function getResults($days, $limit=15)
{
   $data = Analytics::fetchMostVisitedPages(Period::days($days), $limit);
   return $this->parseResults($data);
}

Now if we run it again all the returned data should be correct:

Collection {#396 ▼
  #items: array:11 [▼
    2 => array:3 [▼
      "url" => "/2016/06/look-whats-coming-laravel-5-3/"
      "pageTitle" => "A look at what’s coming to Laravel 5.3"
      "pageViews" => 10
    ]
    4 => array:3 [▼
      "url" => "/2016/08/laravel-5-3-rc1-is-now-released/"
      "pageTitle" => "Laravel 5.3 RC1 is now released"
      "pageViews" => 9
    ]
    5 => array:3 [▼
      "url" => "/2016/07/laravel-5-3-recap/"
      "pageTitle" => "Laracon: Laravel 5.3 Recap"
      "pageViews" => 8
    ]
    6 => array:3 [▶]
    7 => array:3 [▶]
    8 => array:3 [▶]
    9 => array:3 [▶]
    12 => array:3 [▶]
    13 => array:3 [▶]
    14 => array:3 [▶]
    15 => array:3 [▶]
  ]
}

It appears to be working, but notice that instead of the desired 15 items, these results only have 11. That’s because we are originally fetching the 15 top items, then rejected any duplicates. That causes us to get less than the fifteen we wanted.

The solution I came up with is to request more than I’m going to need and then splice off the number we really want. First, change getResults to grab more than needed:

protected function getResults($days, $limit=15)
{
   $data = Analytics::fetchMostVisitedPages(Period::days($days), $limit + 10);
   return $this->parseResults($data, $limit);
}

Notice that instead of calling fetchMostVisitedPages with the limit passed it’s now adding ten to it. That way we have a buffer of extras.

Next modify the parseResults to splice off the limit at the end of all the parsing:

protected function parseResults($data, $limit)
{
    return $data->reject(function($item){
        return $item['url'] == '/' or
        $item['url'] == '/blog' or
        starts_with($item['url'], '/category');
    })->unique('url')->transform(function($item){
        $item['pageTitle'] = str_replace(' - Laravel News', '', $item['pageTitle']);
        return $item;
    })->splice(0, $limit);
}

This now gives the proper results:

Collection {#353 ▼
  #items: array:15 [▶]
}

With that all working it’s time to implement it into the view and I believe this would make a great candidate for a view composer.

Creating the View Composer

If you are not familiar with View Composers here is how the documentation describes them:

View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location.

Because this data is only going to show in the sidebar and it could be called from any controller it’s a prime candidate for a view composer.

To setup this View Composer create app/Http/ViewComposers/PopularityComposer.php and add the following class:

<?php

namespace App\Http\ViewComposers;

use App\Services\Trending;
use Illuminate\View\View;

class PopularityComposer
{
    private $trending;

    public function __construct(Trending $trending)
    {
        $this->trending = $trending;
    }

    public function compose(View $view)
    {
        $view->with('popular', $this->trending->week());
    }
}

This is setting up our previous Trending class as a dependency and then in the compose method adding a view variable named “popular” that will hold our Collection of results.

Next, open app/Providers/ComposerServiceProvider.php and register our new composer:

view()->composer(
   'sidebar', PopularityComposer::class
);

This is registering the PopularityComposer class that we just created to the sidebar view.

Adding the list to the view

The final part is adding the actual list to the sidebar. Create resources/views/sidebar.blade.php and add a simple list like this:

<ol>
   @foreach ($popular as $post)
       <li><a href="{{ $post['url'] }}">{{ $post['pageTitle'] }}</a></li>
   @endforeach
</ol>

That’s it. You should now see a nice trending list of your posts in a list.

Wrap Up

As you can see from this short tutorial utilizing by utilizing a community package, Laravel Collections, and View Composers I was able to quickly and easily setup a most popular list.

Improved model generation with Laracademy Generators

$
0
0

Laravel provides the Artisan command line tool that allows you to save time by including several generators. Some examples include make:controller, make:model, and make:migration.

Building on top of this idea is a third party package named Laracademy Generators that will automatically generate your models based on your database structure.

Installation:

Let’s explore the workflow when using Laracademy Generators:

First, create your migration as always:

php artisan make:migration create_posts_table —create=posts

Then add your fields to the generated migration file. For example, your field might look like:

public function up()
{
    Schema::create(‘posts’, function (Blueprint $table) {
        $table->increments(‘id’);
        $table->string(‘title’);
        $table->text(‘body’);
        $table->boolean(‘featured’);
        $table->datetime(‘publish_date’);
        $table->timestamps();
    });
}

After that, you will migrate your tables by execution the following command in your terminal:

php artisan migrate
Migrated: 2016_08_26_145636_create_posts_table

Now let’s install Laracademy Generators:

composer require "laracademy/generators"

Then add Laracademy Generators into your config/app.php file:

Laracademy\Generators\GeneratorsServiceProvider::class

Alternatively, you can add the provider to your ‘app/Providers/AppServiceProvider.php’ if you only want to use this provider for local development:

public function register()
{
    if($this->app->environment() == 'local') {
        $this->app->register('\Laracademy\Generators\GeneratorsServiceProvider');
    }
}

Now you have everything you need to start using the Laracademy Generators. Let’s explore how to use it and what are the available options.If you check your Artisan cli, a new command will appear in the list:

generate:modelfromtable

First, you can pass –all flag to tell Laracademy Generators to generate models for all tables existed in your database:

php artisan generate:modelfromtable --all

Another option is –table which makes you be able to specify the tables that you want Laracademy Generators to generate models for, like this:

php artisan generate:modelfromtable --table=posts

Or multiple tables at once:

php artisan generate:modelfromtable --table=users,posts

There are another two options; one is for choosing your database connection (–connection=example) and the second is for specifying you where the generated models goes (–folder=app\Models).

Take a look at what the generated model looks like, if you are following along with me in the posts table example, the generated app/Post.php content will look like this:

laracademy-generators

Just note that the generated code will often require some edits but it gives you a great starting point.

Give Laracademy Generators a try if you are looking for away to speed up your development process. You can check out the source code of Laracademy Generators at Github.

Viewing all 1744 articles
Browse latest View live