Content Source:
What’s new in Laravel 7
On release of Laravel 7, in our previous post we covered some of the fantastic features such as Laravel Airlock, Custom Eloquent Casts and few more. This post covers the rest of them.
Multiple Mail Drivers
Laravel 7 allows the configuration of multiple “mailers” for a single application. Each mailer configured within the mail configuration file may have its own options and even its own unique “transport”, allowing your application to use different email services to send certain email messages. For example, your application might use Postmark to send transactional mail while using Amazon SES to send bulk mail.
Mail::mailer('postmark') ->to($request->user()) ->send(new OrderShipped($order));
By default, Laravel will use the mailer configured as the default mailer in your mail configuration file. However, you may use the mailer method to send a message using a specific mailer
configuration:
Route Caching Speed Improvements
Laravel 7 includes a new method of matching compiled, cached routes that have been cached using the route:cache
Artisan command. On large applications (for example, applications with 800 or more routes), these improvements can result in a 2x speed improvement in requests per second on a simple “Hello World” benchmark. No changes to your application are required.
CORS Support
Laravel 7 includes first-party support for configuring Cross-Origin Resource Sharing (CORS) OPTIONS
request responses by integrating the popular Laravel CORS package written by Barry vd. Heuvel. A new cors
configuration is included in the default Laravel application skeleton.
Query Time Casts
Sometimes you may need to apply casts while executing a query, such as when selecting a raw value from a table. For example, consider the following query:
use App\Post; use App\User; $users = User::select([ 'users.*', 'last_posted_at' => Post::selectRaw('MAX(created_at)') ->whereColumn('user_id', 'users.id') ])->get();
The last_posted_at
attribute on the results of this query will be a raw string. It would be convenient if we could apply a date
cast to this attribute when executing the query. To accomplish this, we may use the withCasts
method provided by Laravel 7:
$users = User::select([ 'users.*', 'last_posted_at' => Post::selectRaw('MAX(created_at)') ->whereColumn('user_id', 'users.id') ])->withCasts([ 'last_posted_at' => 'date' ])->get();
MySQL 8+ Database Queue Improvements
In previous releases of Laravel, the database
queue was not considered robust enough for production usage, due to deadlocks. However, Laravel 7 provides improvements to applications using MySQL 8+ as their database backed queue. By using the FOR UPDATE SKIP LOCKED clause and other SQL enhancements, the database
driver may now safely be used in higher volume production applications.
Artisan test Command
The test
command was contributed by Nuno Maduro.
In addition to the phpunit
command, you may now use the test Artisan command to run your tests. The Artisan test runner provides beautiful console UX and more information regarding the test that is currently running. In addition, the runner will automatically stop on the first test failure:
php artisan test

pic courtesy: res.cloudinary.com
Any arguments that can be passed to the phpunit
command may also be passed to the Artisan test
command:
php artisan test --group=feature
Markdown Mail Template Improvements
The default Markdown mail template has received a fresh, more modern design based on the Tailwind CSS color palette. Of course, this template can be published and customized according to your application’s needs:

pic courtesy: res.cloudinary.com
Stub Customization
The Artisan console’s make
commands are used to create a variety of classes, such as controllers, jobs, migrations, and tests. These classes are generated using “stub” files that are populated with values based on your input. However, you may sometimes wish to make small changes to files generated by Artisan. To accomplish this, Laravel 7 provides the stub:publish
command to publish the most common stubs for customization:
php artisan stub:publish
The published stubs will be located within a stubs
directory in the root of your application. Any changes you make to these stubs will be reflected when you generate their corresponding classes using Artisan make
commands.
Queue maxExceptions Configuration
Sometimes you may wish to specify that a job may be attempted many times, but should fail if the retries are triggered by a given number of exceptions. In Laravel 7, you may define a maxExceptions
property on your job class:
<?php namespace App\Jobs; class ProcessPodcast implements ShouldQueue { /** * The number of times the job may be attempted. * * @var int */ public $tries = 25; /** * The maximum number of exceptions to allow before failing. * * @var int */ public $maxExceptions = 3; /** * Execute the job. * * @return void */ public function handle() { Redis::throttle('key')->allow(10)->every(60)->then(function () { // Lock obtained, process the podcast... }, function () { // Unable to obtain lock... return $this->release(10); }); } }
In this example, the job is released for ten seconds if the application is unable to obtain a Redis lock and will continue to be retried up to 25 times. However, the job will fail if three unhandled exceptions are thrown by the job.
Laravel 7 is just released!
Laravel 7 continues the improvements made in Laravel 6.x by introducing Laravel Airlock, routing speed improvements, custom Eloquent casts, Blade component tags, fluent string operations, a developer focused HTTP client, first-party CORS support, improved scoping for route model binding, stub customization, database queue improvements, multiple mail drivers, query-time casts, a new artisan test
command, and a variety of other bug fixes and usability improvements.
Laravel Airlock
Laravel Airlock provides a featherweight authentication system for SPAs (single page applications), mobile applications, and simple, token based APIs. Airlock allows each user of your application to generate multiple API tokens for their account. These tokens may be granted abilities / scopes which specify which actions the tokens are allowed to perform.
Custom Eloquent Casts
Laravel has a variety of built-in, helpful cast types; however, you may occasionally need to define your own cast types. You may now accomplish this by defining a class that implements the CastsAttributes
interface.
Classes that implement this interface must define a get
and set
methods. The get
method is responsible for transforming a raw value from the database into a cast value, while the set
method should transform a cast value into a raw value that can be stored in the database. As an example, we will re-implement the built-in json
cast type as a custom cast type:
<?php namespace App\Casts; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; class Json implements CastsAttributes { /** * Cast the given value. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param mixed $value * @param array $attributes * @return array */ public function get($model, $key, $value, $attributes) { return json_decode($value, true); } /** * Prepare the given value for storage. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param array $value * @param array $attributes * @return string */ public function set($model, $key, $value, $attributes) { return json_encode($value); } }
Once you have defined a custom cast type, you may attach it to a model attribute using its class name:
<?php namespace App\View\Components; use Illuminate\View\Component; class Alert extends Component { /** * The alert type. * * @var string */ public $type; /** * Create the component instance. * * @param string $type * @return void */ public function __construct($type) { $this->type = $type; } /** * Get the class for the given alert type. * * @return string */ public function classForType() { return $this->type == 'danger' ? 'alert-danger' : 'alert-warning'; } /** * Get the view / contents that represent the component. * * @return \Illuminate\View\View|string */ public function render() { return view('components.alert'); } }
To learn how to write custom Eloquent casts, including custom casts that cast to value objects, please consult the Eloquent documentation.
Blade Component Tags & Improvements
Blade components have been overhauled to allow tag based rendering, attribute management, component classes, inline view components, and more. Since the overhaul of Blade components is so extensive, please consult the full Blade component documentation to learn about this feature.
In summary, a component may now have an associated class which specifies the data it accepts. All public properties and methods defined on the component class will automatically be made available to the component view. Any additional HTML attributes specified on the component may be managed using the automatically included $attribute
variable, which is an attribute bag instance.
In this example, we will assume that an App\View\Components\Alert
component has been defined like so:
<?php namespace App\View\Components; use Illuminate\View\Component; class Alert extends Component { /** * The alert type. * * @var string */ public $type; /** * Create the component instance. * * @param string $type * @return void */ public function __construct($type) { $this->type = $type; } /** * Get the class for the given alert type. * * @return string */ public function classForType() { return $this->type == 'danger' ? 'alert-danger' : 'alert-warning'; } /** * Get the view / contents that represent the component. * * @return \Illuminate\View\View|string */ public function render() { return view('components.alert'); } }
And, assuming the component’s Blade template has been defined like so:
<!-- /resources/views/components/alert.blade.php --> <div class="alert {{ $classForType }}" {{ $attributes }}> {{ $heading }} {{ $slot }} </div>
The component may be rendered in another Blade view using the component’s tag:
<x-alert type="error" class="mb-4"> <x-slot name="heading"> Alert content... </x-slot> Default slot content... </x-alert>
As mentioned, this is just a very small sample of the functionality of the Blade component overhaul in Laravel 7 and does not demonstrate anonymous components, inline view components, and a variety of other features. Please consult the full Blade component documentation to learn about this feature.
HTTP Client
Laravel now provides an expressive, minimal API around the Guzzle HTTP client, allowing you to quickly make outgoing HTTP requests to communicate with other web applications. Laravel’s wrapper around Guzzle is focused on its most common use cases and a wonderful developer experience. For example, the client makes it a breeze to POST and interface with JSON data:
use Illuminate\Support\Facades\Http; $response = Http::withHeaders([ 'X-First' => 'foo', 'X-Second' => 'bar' ])->post('http://test.com/users', [ 'name' => 'Taylor', ]); return $response['id'];
In addition, the HTTP client provides fantastic, ergonomic testing functionality:
Http::fake([ // Stub a JSON response for GitHub endpoints... 'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']), // Stub a string response for Google endpoints... 'google.com/*' => Http::response('Hello World', 200, ['Headers']), // Stub a series of responses for Facebook endpoints... 'facebook.com/*' => Http::sequence() ->push('Hello World', 200) ->push(['foo' => 'bar'], 200) ->pushStatus(404), ]);
Fluent String Operations
You are likely familiar with Laravel’s existing Illuminate\Support\Str
class, which provides a variety of helpful string manipulation functions. Laravel 7 now offers a more object-oriented, fluent string manipulation library built on top of these functions. You may create a fluent Illuminate\Support\Stringable
object using the Str::of
method. A variety of methods may then be chained onto the object to manipulate the string:
return (string) Str::of(' Laravel Framework 6.x ') ->trim() ->replace('6.x', '7.x') ->slug();
Route Model Binding Improvements
Key Customization
Sometimes you may wish to resolve Eloquent models using a column other than id
. To do so, Laravel 7 allows you to specify the column in the route parameter definition:
Route::get('api/posts/{post:slug}', function (App\Post $post) { return $post; });
Automatic Scoping
Sometimes, when implicitly binding multiple Eloquent models in a single route definition, you may wish to scope the second Eloquent model such that it must be a child of the first Eloquent model. For example, consider this situation that retrieves a blog post by slug for a specific user:
use App\Post; use App\User; Route::get('api/users/{user}/posts/{post:slug}', function (User $user, Post $post) { return $post; });
When using a custom keyed implicit binding as a nested route parameter, Laravel 7 will automatically scope the query to retrieve the nested model by its parent using conventions to guess the relationship name on the parent. In this case, it will be assumed that the User
model has a relationship named posts
(the plural of the route parameter name) which can be used to retrieve the Post
model.
For more information and to develop your web apps using Laravel, Hire Laravel Developer from us as we provide you high-quality solution by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.
To develop the custom web app using Laravel, please visit our technology page.
Content Source:
- laravel.com
How to develop multi tenant application using Laravel
If you want to run multiple websites using the same Laravel installation while keeping tenant specific data separated for fully independent multi-domain setups then it is pretty easily possible with this multi-tenant Laravel package.
With this package, you can serve multiple websites each with one or more hostnames from the same codebase. It has clear separation of database, assets & it also provides the ability to override logic per tenant.
This is suitable for marketing companies or startups which are building Software as a Service(SaaS).
I know this architecture is opposite to famous micro-service architecture, but just posting it in case someone is in the need to do so.
This package offers following features under the hood:
- Integration with the awesome Laravel framework.
- Event driven, extensible architecture.
- Close – optional – integration into the web server.
- The ability to add tenant specific configs, code, routes etc.
Database separation methods:
- One system database and separated tenant databases (default).
- Table prefixed in the system database.
- Or manually, the way you want, by listening to an event.
Requirements, recommended environment:
- Latest stable and LTS Laravel versions.
- PHP 7+.
- Apache or Nginx.
- MySQL, MariaDB or PostgreSQL.
Installation
composer require hyn/multi-tenant
Automatic service registration
Using auto discovery, the tenancy package will be auto detected by Laravel automatically.
Manual service registration
In case you want to disable webserver integration or prefer manual integration, set the dont-discover
in your application composer.json, like so:
{ "extra": { "laravel": { "dont-discover": [ "hyn/multi-tenant" ] } } }
If you disable auto-discovery you are able to configure the providers by yourself.
Register the service provider in your config/app.php:
'providers' => [ // [..] // Hyn multi tenancy. Hyn\Tenancy\Providers\TenancyProvider::class, // Hyn multi tenancy webserver integration. Hyn\Tenancy\Providers\WebserverProvider::class, ],
Deploy configuration
First publish the configuration and migration files so you can modify it to your needs:
php artisan vendor:publish --tag tenancy
Open the config/tenancy.php
and config/webserver.php
file and modify to your needs.
Make sure your system connection has been configured in database.php
. In case you didn’t override the system connection name the default
connection is used.
Now run:
php artisan migrate --database=system
This will run the required system database migrations.
Testing
Run tests using:
vendor/bin/phpunit
If using MySQL, use:
LIMIT_UUID_LENGTH_32=1 vendor/bin/phpunit
Please be warned running tests will reset your current application completely, dropping tenant and system databases and removing the tenancy.json file inside the Laravel directory.
For more Information and to build a website using Laravel, Hire Laravel Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.To develop the custom website using Laravel, please visit our technology page
- fullstackworld.com/
- github.com/tenancy/multi-tenant
Automate Future Notifications and Reminders with Laravel Snooze
Laravel Snooze is a package, which simplifies automating future notifications and reminders in Laravel.
The package’s readme has some typical use-cases for this package:
- Reminder system (1 week before appt, 1 day before, 1 hour before, etc)
- Follow-up surveys (2 days after purchase)
- On-boarding Email Drips (Welcome email after sign-up, additional tips after 3 days, upsell offer after 7 days)
- Short-Term Recurring reports (send every week for the next 4 weeks)
Why use this package?
- Ever wanted to schedule a future notification to go out at a specific time? (was the delayed queue option not enough?)
- Want a simple on-boarding email drip?
- How about happy birthday emails?
Common use cases
- Reminder system (1 week before appt, 1 day before, 1 hour before, etc)
- Follow-up surveys (2 days after purchase)
- On-boarding Email Drips (Welcome email after sign-up, additional tips after 3 days, upsell offer after 7 days)
Short-Term Recurring reports (send every week for the next 4 weeks)
Installation
- Install via composer
- composer require thomasjohnkane/snooze
- php artisan migrate
Publish Configuration File
php artisan vendor:publish --provider="Thomasjohnkane\Snooze\ServiceProvider" --tag="config"
Usage
Using the model trait
Snooze provides a trait for your model, similar to the standard Notifiable trait. It adds a notifyAt()
method to your model to schedule notifications.
use Thomasjohnkane\Snooze\Traits\SnoozeNotifiable; class User extends Model { use SnoozeNotifiable; // ... } // Schedule a birthday notification $user->notifyAt(new BirthdayNotification, Carbon::parse($user->birthday)); // Schedule for a week from now $user->notifyAt(new NextWeekNotification, Carbon::now()->addDays(7)); // Schedule for new years eve $user->notifyAt(new NewYearNotification, Carbon::parse('last day of this year'));
Using the ScheduledNotification::create helper
You can also use the create method on the ScheduledNotification.
ScheduledNotification::create( Auth::user(), // Target new ScheduledNotificationExample($order), // Notification Carbon::now()->addHour() // Send At ); This is also useful for scheduling anonymous notifications (routed direct, rather than on a model). $target = (new AnonymousNotifiable) ->route('mail', 'hello@example.com') ->route('sms', '56546456566'); ScheduledNotification::create( $target, // Target new ScheduledNotificationExample($order), // Notification Carbon::now()->addDay() // Send At );
An important note about scheduling the snooze:send command
Creating a scheduled notification will add the notification to the database. It will be sent by running snooze:send
command at (or after) the stored sendAt
time.
The snooze:send
command is scheduled to run every minute by default. You can change this value (sendFrequency)
in the published config file. Available options are everyMinute
, everyFiveMinutes
, everyTenMinutes
, everyFifteenMinutes
, everyThirtyMinutes
, hourly
, and daily
.
The only thing you need to do is make sure schedule:run
is also running. You can test this by running php artisan schedule:run
in the console.
Setting the send tolerance
If your scheduler stops working, a backlog of scheduled notifications will build up. To prevent users receiving all of the old scheduled notifications at once, the command will only send mail within the configured tolerance. By default this is set to 24 hours, so only mail scheduled to be sent within that window will be sent. This can be configured in the snooze.php
config file.
Cancelling Scheduled Notifications
$notification->cancel();
Note: you cannot cancel a notification that has already been sent.
Rescheduling Scheduled Notifications
$rescheduleAt = Carbon::now()->addDay(1)
$notification->reschedule($rescheduleAt)
Note: you cannot reschedule a notification that has already been sent or cancelled. If you want to duplicate a notification that has already been sent or cancelled, pass a truthy second parameter along with the new send date; reschedule($date, true)
, or use the scheduleAgainAt($date)
method shown below
Duplicate a Scheduled Notification to be sent again
$notification->scheduleAgainAt($newDate);
Check a scheduled notification’s status
// Check if a notification is already cancelled $result = $notification->isCancelled(); // returns a bool // Check if a notification is already sent $result = $notification->isSent(); // returns a bool
Conditionally interrupt a scheduled notification
If you’d like to stop an email from being sent conditionally, you can add the shouldInterrupt()
method to any notification. This method will be checked immediately before the notification is sent.
For example, you might not send a future drip notification if a user has become inactive, or the order the notification was for has been canceled.
public function shouldInterrupt($notifiable) { return $notifiable->isInactive() || $this->order->isCanceled(); }
If this method is not present on your notification, the notification will not be interrupted. Consider creating a shouldInterupt trait if you’d like to repeat conditional logic on groups of notifications.
Running the Tests
composer test
To develop the custom website using Laravel, please visit our technology page
Content Source:
- laravel-news.com
Laravel: Fail, Retry, or Delay a queued job from itself
When creating jobs, listeners, or subscribers to push into the queue, you may start thinking that, once dispatched, you’re all on your own with what the queue worker decides to do with your logic.
Well, it’s not that you can’t interact with the queue worker from inside the job, but you usually don’t need to… until you do.
The magic happens because of the InteractsWithQueue
trait. When the queued job is being pulled out from the queue, the CallQueuedListener
will check if it’s using the InteractsWithQueue
trait, and if it is, the framework will inject the underlying “job” instance inside.
This “job” instance is like the driver that wraps your real Job
class, which contains information about the connection and attempts, among other things.
Context
We will use a transcoding Job
as an example. This is a job that transcodes a podcast audio file into an MP3 of 192kbps. Because this is set in the free transcoding queue, it has limited availability.
Checking the Attempts
The first method is called attempts()
, and as its name implies, it returns the number of attempts. A Job
always starts with one attempt.
This method is meant to be used with others, like fail()
or release()
(delay). For illustration purposes, we will notify the user of the nth retrying: each time we try to transcode a podcast in the free queue, we will notify the user we’re retrying for the nth time, giving him the option to cancel future transcodes.
<?php namespace App\Jobs; use App\Podcast; use Transcoder\Transcoder; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use App\Notifications\PodcastTranscoded; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Foundation\Bus\Dispatchable; use App\Notifications\RetyingPodcastTranscode; class TranscodePodcast { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Transcoder Instance * * @var \App\Podcast */ protected $podcast; /** * Create a new Transcode Podcast instance. * * @param \App\Podcast $podcast * @return void */ public function __construct(Podcast $podcast) { $this->podcast = $podcast; } /** * Execute the job. * * @param \Transcoder\Transcoder $podcast * @return void */ public function handle(Transcoder $transcoder) { // Tell the user we're retrying for the nth time if ($this->attempts() > 1) { $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast, $this->attempts()); } $transcoded = $this->transcoder->setFile($event->podcast) ->format('mp3') ->bitrate(192) ->start(); // Associate the transcoded podcast to the original podcast. $this->podcast->transcode()->associate($transcoded); // Notify the publisher of the podcast that his podcast is ready $this->publisher->notify(new PodcastTranscoded($this->podcast)); } }
Telling the user that we’re retrying something for the nth time is useful when the logic has failed beforehand, letting the user (or developer) check what went wrong, but of course you can do more than that.
Personally, we like to do that after the Job
failed, and if it has retries left, tell him that we’re going to retry later.
Deleting the Job
The second method is delete()
. As you can guess, you can delete the current Job
from the queue.
This can be handy when you shouldn’t process the job or listener after it was queued for several reasons. For example, think about this scenario: the publisher that uploaded the podcast has been deactivated for any reason (like a TOS violation) before the transcoding occurs, and we should not process the podcast.
We will add that code to the example from before:
<?php namespace App\Jobs; use App\Podcast; use Transcoder\Transcoder; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use App\Notifications\PodcastTranscoded; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Foundation\Bus\Dispatchable; use App\Notifications\RetyingPodcastTranscode; class TranscodePodcast { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Transcoder Instance * * @var \App\Podcast */ protected $podcast; /** * Create a new Transcode Podcast instance. * * @param \App\Podcast $podcast * @return void */ public function __construct(Podcast $podcast) { $this->podcast = $podcast; } /** * Execute the job. * * @param \Transcoder\Transcoder $podcast * @return void */ public function handle(Transcoder $transcoder) { // If the publisher has been deactivated, take this job out if ($this->podcast->publisher->isDeactivated()) { $this->delete(); } // Tell the user we're retrying for the nth time if ($this->attempts() > 1) { $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast, $this->attempts()); } $transcoded = $this->transcoder->setFile($event->podcast) ->format('mp3') ->bitrate(192) ->start(); // Associate the transcoded podcast to the original podcast. $this->podcast->transcode()->associate($transcoded); // Notify the publisher of the podcast that his podcast is ready $this->publisher->notify(new PodcastTranscoded($this->podcast)); } }
If you need to delete the job on models that may have been deleted, you may want to set $deleteWhenMissingModels
to true to avoid processing something that is not there.
Failing the Job
This is very, very handy when you need control over artificially failing the logic, because using an empty return
statement will mark the Job as done successfully. You can forcefully fail the queued job
, hopefully with an exception, allowing the handler to retry it later if possible.
This gives you finer control when the job fails. In any case, you can also use the failed()
method, which allows you to perform any cleaning after it fails, like notifying the user or deleting something.
In this example, we will fail the job if the podcast cannot be retrieved from storage for whatever reason, like when the CDN goes down, throwing a custom exception.
<?php namespace App\Jobs; use App\Podcast; use Transcoder\Transcoder; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use App\Exceptions\PodcastUnretrievable; use App\Notifications\PodcastTranscoded; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Foundation\Bus\Dispatchable; use App\Notifications\RetyingPodcastTranscode; class TranscodePodcast { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Transcoder Instance * * @var \App\Podcast */ protected $podcast; /** * Create a new Transcode Podcast instance. * * @param \App\Podcast $podcast * @return void */ public function __construct(Podcast $podcast) { $this->podcast = $podcast; } /** * Execute the job. * * @param \Transcoder\Transcoder $podcast * @return void */ public function handle(Transcoder $transcoder) { // If the publisher has been deactivated, take this job out if ($this->podcast->publisher->isDeactivated()) { $this->delete(); } // If the podcast cannot be retrieved from the storage, we will fail miserably. if ($this->podcast->fileDoesntExists()) { $this->fail(new PodcastUnretrievable($this->podcast)); } // Tell the user we're retrying for the nth time if ($this->attempts() > 1) { $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast, $this->attempts()); } $transcoded = $this->transcoder->setFile($event->podcast) ->format('mp3') ->bitrate(192) ->start(); // Associate the transcoded podcast to the original podcast. $this->podcast->transcode()->associate($transcoded); // Notify the publisher of the podcast that his podcast is ready $this->publisher->notify(new PodcastTranscoded($this->podcast)); } }
Releasing (Delaying) a Job
This is probably the most useful method of the trait, as it allows you to push the job further into the future. This method is used for rate limiting your job.
Apart from rate limiting, you can also use this when something is not available but you expect it to be in the near future. Also, to avoid failing preemptively.
In this last example, we will delay the transcoding for later: if the transcoder is under heavy usage, we will delay the transcoding for five minutes until the load lowers.
<?php namespace App\Jobs; use App\Podcast; use Transcoder\Transcoder; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use App\Exceptions\PodcastUnretrievable; use App\Notifications\PodcastTranscoded; use Illuminate\Queue\InteractsWithQueue; use App\Notifications\TranscoderHighUsage; use Illuminate\Foundation\Bus\Dispatchable; use App\Notifications\RetyingPodcastTranscode; class TranscodePodcast { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Transcoder Instance * * @var \App\Podcast */ protected $podcast; /** * Create a new Transcode Podcast instance. * * @param \App\Podcast $podcast * @return void */ public function __construct(Podcast $podcast) { $this->podcast = $podcast; } /** * Execute the job. * * @param \Transcoder\Transcoder $podcast * @return void */ public function handle(Transcoder $transcoder) { // If the publisher has been deactivated, take this job out if ($this->podcast->publisher->isDeactivated()) { $this->delete(); } // If the podcast cannot be retrieved from the storage, we will fail miserably. if ($this->podcast->fileDoesntExists()) { $this->fail(new PodcastUnretrievable($this->podcast)); } // If the Transcoder usage is high, we will avoid choking it by delaying the // transcoding by 5 minutes. Otherwise we may risk stalling the transcoder // process, which will take down all transcoding sub-processes with him. if ($transcoder->getLoad()->isHigh()) { $delay = 60 * 5; $this->podcast->publisher->notify(new TranscoderHighUsage($this->podcast, $delay)); $this->release($delay); } // Tell the user we're retrying for the nth time if ($this->attempts() > 1) { $this->podcast->publisher->notify(new RetryingPodcastTranscode($this->podcast, $this->attempts()); } $transcoded = $this->transcoder->setFile($event->podcast) ->format('mp3') ->bitrate(192) ->start(); // Associate the transcoded podcast to the original podcast. $this->podcast->transcode()->associate($transcoded); // Notify the publisher of the podcast that his podcast is ready $this->publisher->notify(new PodcastTranscoded($this->podcast)); } }
We could use some magic, for example, getting assign some slots to the transcoder, and delay the job if the transcoder slots are full.
And that’s pretty much all you can do from inside the queued job.
For more Information and to build a website using Laravel, Hire Laravel Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.
To develop the custom website using Laravel, please visit our technology page
Content Source:
- medium.com
Amazing Features and Updates of Laravel 6
Laravel 6 release includes compatibility with Laravel Vapor, improved authorization responses, job middleware, lazy collections, sub-query improvements, semantic versioning, among many other improvements.
Here are some of the new features included in Laravel 6:
Semantic Versioning
The Laravel framework (laravel/framework) package now follows the semantic versioning standard. This makes the framework consistent with the other first-party Laravel packages which already followed this versioning standard. The Laravel release cycle will remain unchanged.
Laravel Vapor Compatibility
Laravel 6.0 provides compatibility with Laravel Vapor, an auto-scaling serverless deployment platform for Laravel. Vapor abstracts the complexity of managing Laravel applications on AWS Lambda, as well as interfacing those applications with SQS queues, databases, Redis clusters, networks, CloudFront CDN, and more.
Improved Exceptions Via Ignition
Laravel 6.0 ships with Ignition, a new open source exception detail page created by Freek Van der Herten and Marcel Pociot. Ignition offers many benefits over previous releases, such as improved Blade error file and line number handling, runnable solutions for common problems, code editing, exception sharing, and an improved UX.
Improved Authorization Responses
In previous releases of Laravel, it was difficult to retrieve and expose custom authorization messages to end users. This made it difficult to explain to end-users exactly why a particular request was denied. In Laravel 6.0, this is now much easier using authorization response messages and the new Gate::inspect
method. For example, given the following policy method:
/** * Determine if the user can view the given flight. * * @param \App\User $user * @param \App\Flight $flight * @return mixed */ public function view(User $user, Flight $flight) { return $this->deny('Explanation of denial.'); }
The authorization policy’s response and message may be easily retrieved using the Gate::inspect
method:
$response = Gate::inspect('view', $flight); if ($response->allowed()) { // User is authorized to view the flight... } if ($response->denied()) { echo $response->message(); }
In addition, these custom messages will automatically be returned to your frontend when using helper methods such as $this->authorize
or Gate::authorize
from your routes or controllers.
Job Middleware
Job middleware allow you wrap custom logic around the execution of queued jobs, reducing boilerplate in the jobs themselves. For example, in previous releases of Laravel, you may have wrapped the logic of a job’s handle
method within a rate-limited responsibilities.
You define middleware by specifying a middleware()
method on the job class which returns an array of middleware objects. From the pull request, here’s an example:
public function middleware() { return [new SomeMiddleware]; }
And here’s an example of the middleware class:
class SomeMiddleware { public function handle($command, $next) { // Do something... return $next($command); } }
You can also specify middleware when dispatching a job:
SomeJob::dispatch()->through([new SomeMiddleware]);
Lazy Collections
Lazy collections are a game-changer for working with extensive collections of data, including Eloquent model collections. A new Illuminate\Support\LazyCollection
class leverages PHP’s generators to keep memory low while working with large datasets.
For example, imagine your application needs to process a multi-gigabyte log file while taking advantage of Laravel’s collection methods to parse the logs. Instead of reading the entire file into memory at once, lazy collections may be used to keep only a small part of the file in memory at a given time:
use App\LogEntry; use Illuminate\Support\LazyCollection; LazyCollection::make(function () { $handle = fopen('log.txt', 'r'); while (($line = fgets($handle)) !== false) { yield $line; } }) ->chunk(4) ->map(function ($lines) { return LogEntry::fromLines($lines); }) ->each(function (LogEntry $logEntry) { // Process the log entry... });
Or, imagine you need to iterate through 10,000 Eloquent models. When using traditional Laravel collections, all 10,000 Eloquent models must be loaded into memory at the same time:
$users = App\User::all()->filter(function ($user) { return $user->id > 500; });
However, beginning in Laravel 6.0, the query builder’s cursor
method has been updated to return a LazyCollection
instance. This allows you to still only run a single query against the database but also only keep one Eloquent model loaded in memory at a time. In this example, the filter
callback is not executed until we actually iterate over each user individually, allowing for a drastic reduction in memory usage:
$users = App\User::cursor()->filter(function ($user) { return $user->id > 500; }); foreach ($users as $user) { echo $user->id; }
Eloquent Subquery Enhancements
Laravel 6.0 introduces several new enhancements and improvements to database subquery support. For example, let’s imagine that we have a table of flight destinations
and a table of flights
to destinations. The flights
table contains an arrived_at
column which indicates when the flight arrived at the destination.
Using the new subquery select functionality in Laravel 6.0, we can select all of the destinations
and the name of the flight that most recently arrived at that destination using a single query:
return Destination::addSelect(['last_flight' => Flight::select('name') ->whereColumn('destination_id', 'destinations.id') ->orderBy('arrived_at', 'desc') ->limit(1) ])->get();
In addition, we can use new subquery features added to the query builder’s orderBy
function to sort all destinations based on when the last flight arrived at that destination. Again, this may be done while executing a single query against the database:
return Destination::orderByDesc( Flight::select('arrived_at') ->whereColumn('destination_id', 'destinations.id') ->orderBy('arrived_at', 'desc') ->limit(1) )->get();
Laravel UI
The frontend scaffolding typically provided with previous releases of Laravel has been extracted into a laravel/ui
Composer package. This allows the first-party UI scaffolding to be developed and versioned separately from the primary framework. As a result of this change, no Bootstrap or Vue code is present in default framework scaffolding, and the make:auth
command has been extracted from the framework as well.
In order to restore the traditional Vue / Bootstrap scaffolding present in previous releases of Laravel, you may install the laravel/ui
package and use the ui
Artisan command to install the frontend scaffolding:
composer require laravel/ui php artisan ui vue --auth
For more Information and to build a website using Laravel, Hire Laravel Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.
To develop the custom website using Laravel, please visit our technology page
Content Source:
- medium.com
Building Progressive Web App using Laravel
Progressive Web App or PWA are the important thing in web development at the moment. Why wouldn't it be? The promise of a website behaving like a native app, without all the hassles.
PWA allow you to install your website on the user’s home screen, work without an internet connection and even send push notifications to users. You can also cache everything to your heart’s content, including API calls with IndexedDB. I’ll run you through the simple setup I used to get things going rather quickly with Laravel 5.8.
To view service worker information in browser when testing, open up devtools and hit the application tab in Chrome.
What do I need for a PWA?
To make sure your website behaves like a PWA, please read the checklist. Here’s the quick and easy summary:
- HTTPS
- manifest.json
- Service Worker
- Responsive Design
Setting things up
Firstly you’re going to want to run npm install –save-dev sw-precache-webpack-plugin. This package uses sw-precache to generate our service worker. If you’re worried about losing control, don’t worry – you can use the importScripts option to include any custom logic that you need.
Service Workers provide us with the black magic that we want. You can read more about them here.
To store information from API calls, I used localforage. It’s a nice little library to interact with IndexedDB or WebSQL. So once you’ve got sw-precache-webpack-plugin installed, it’s time to customize our Laravel project.
Step 1: Update Laravel Mix
You’re going to have to copy webpack’s config file and place it at the root of your project directory. You should be able to find it at:
node_modules/laravel-mix/setup/webpack.config.js.
Once that’s done, you’ll need to update your package.json file to reference the new location. Otherwise our changes won’t affect anything. It’s up to you to decide which build step to include it in. You’ll see the development, watch and production scripts currently have the location set to:
--config=node_modules/laravel-mix/setup/webpack.config.js.
Change that to look like this:
--config=webpack.config.js.
Diving into webpack.config.js
At the top of the file you’ll find all the packages that are being imported. Add the sw-precache plugin here. It should look something like this now:
let path = require('path'); let glob = require('glob'); let webpack = require('webpack'); let Mix = require('laravel-mix').config; let webpackPlugins = require('laravel-mix').plugins; let dotenv = require('dotenv'); let SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin'); //Our magic
Then above this line module.exports.plugins = plugins;, I’ve added the plugin:
plugins.push( new SWPrecacheWebpackPlugin({ cacheId: 'pwa', filename: 'service-worker.js', staticFileGlobs: ['public/**/*.{css,eot,svg,ttf,woff,woff2,js,html}'], minify: true, stripPrefix: 'public/', handleFetch: true, dynamicUrlToDependencies: { '/': ['resources/views/welcome.blade.php'], '/articles': ['resources/views/articles.blade.php'] }, staticFileGlobsIgnorePatterns: [/\.map$/, /mix-manifest\.json$/, /manifest\.json$/, /service-worker\.js$/], runtimeCaching: [ { urlPattern: /^https:\/\/fonts\.googleapis\.com\//, handler: 'cacheFirst' }, { urlPattern: /^https:\/\/www\.thecocktaildb\.com\/images\/media\/drink\/(\w+)\.jpg/, handler: 'cacheFirst' } ], importScripts: ['./js/push_message.js'] }) );
The sw-precache package is pretty well documented, so I won’t go into too much depth. I will give a quick rundown of some of the options seen above.
- staticFileGlobs: The files that we want cached.
- dynamicUrlToDependencies: Map the routes to the absolute path of our files. Don’t forget this
- runtimeCaching: Allows us to save 3rd party libraries in cache.
- importScripts: This includes our custom logic to the generated service worker.
That’s it! When compiling your assets, the service-worker.js should show up in your public folder.
Step 2: The manifest file
The manifest file also sits in your public folder as manifest.json. This file gives you a bit more control on the behaviour of your app. You can read more about it here. But as a quick overview, here’s an example:
{ "short_name": "Shots", "name": "Shots App", "background_color": "#2196F3", "orientation": "portrait", "icons": [ { "src": "icons/icon-36.png", "sizes": "36x36", "type": "image/png" }, { "src": "icons/icon-48.png", "sizes": "48x48", "type": "image/png" }, { "src": "icons/icon-72.png", "sizes": "72x72", "type": "image/png" }, { "src": "icons/icon-96.png", "sizes": "96x96", "type": "image/png" }, { "src": "icons/icon-144.png", "sizes": "144x144", "type": "image/png" }, { "src": "icons/icon-168.png", "sizes": "168x168", "type": "image/png" }, { "src": "icons/icon-192.png", "sizes": "192x192", "type": "image/png" }, { "src": "icons/icon-256.png", "sizes": "256x256", "type": "image/png" } ], "start_url": "/?launcher=true", "display": "standalone" }
- short_name: The name shown on the homescreen of the mobile device.
- name: The name shown on the install banner/popup.
- background_color: The color that is shown just before you app launches.
- orientation: Enforces the orientation to be used.
- start_url: The default page to load when our app launches.
- display: ‘standalone’ or ‘browser’, where browser adds an address bar.
- icons: These are the images for our apps icon on the homescreen. Catering for most screen sizes.
These are just a few of the options that are available to you.
Step 3: Check for PWA support
In the page that you define your layout, include the following:
if ('serviceWorker' in navigator &amp;&amp; 'PushManager' in window) { window.addEventListener('load', function() { navigator.serviceWorker.register('/service-worker.js').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); }, function(err) { // registration failed. console.log('ServiceWorker registration failed: ', err); }); }); }
This snippet will check for service worker and push notification support and if true, it will load our service worker file.
Done
This is basically all you need to get the PWA behavior. The rest is up to you to customize and configure based on requirements.
The documentation will provide you with all the finer details that you’ll need.
Demo Web App Developed with PWA
Pet Trainer
Pet trainer app developed in Laravel and integrated PWA.
Technology: Laravel 5.8, Service Worker, Manifest.
Conclusion
This is the quickest way to get started and seeing PWA behavior in action with Laravel. I didn’t want to go through the finer details as it’ll be cumbersome writing about all the possible issues you might encounter. If you do find yourself stuck on something, refer to the documentation, it really is your best friend. 🙂
Good luck!
For more Information and to build a website using Laravel, Hire Laravel Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.
To develop the custom website using Laravel, please visit our technology page
Content Source:
- medium.com
Laravel 5.8.12 released with duplicates collection and other new features
The Laravel team released the 400th release of Laravel (v5.8.12) recently with a new duplicates() collection method and other new features, fixes, and changes to the framework.
First, a new duplicates() method was added to the Illuminate\Support\Collection class:
collect([1,2,1,1,1])->duplicates(); => Illuminate\Support\Collection {#2938 all: [ 2 => 1, 3 => 1, 4 => 1, ], }
It works by returning the indexes of the duplicate values from the original collection object:
$item[0] = 1 is not a duplicate $item[1] = 2 is not a duplicate $item[2] = 1 is a duplicate $item[3] = 1 is a duplicate $item[4] = 1 is a duplicate
Similarly, a new duplicates() method was added to the Eloquent collection class, using the $model->is($another) to check for duplicates. Here’s an example from PR #28194:
use App\User; $one = User::find(1); $two = User::find(1); $three = User::find(1); $users = (new User)->newCollection([$one, $two, $three]); => Illuminate\Database\Eloquent\Collection {#2936 all: [ 1 => App\User {#2929 id: "1", name: "Admin", email: "admin@example.com", email_verified_at: null, created_at: "2019-04-16 23:33:30", updated_at: "2019-04-16 23:33:30", }, 2 => App\User {#2927 id: "1", name: "Admin", email: "admin@example.com", email_verified_at: null, created_at: "2019-04-16 23:33:30", updated_at: "2019-04-16 23:33:30", }, ], }
Next, a new getViews() method was added to the FileViewFinder class, which allows you to retrieve all the view information from currently loaded views. Nothing is new here except the ability to access the $views property via the getViews() method.
As of Laravel 5.8.11, the exit code is captured in scheduled command events, which lead to a new PR providing some helpers available to the scheduler:
$schedule->command('my:command') ->onSuccess(function () { // do something when scheduled command ran successfully }) ->onFailure(function () { // do something when scheduled command failed }) ->pingOnSuccess('https://example.com') ->pingOnFailure('https://example.com') ->emailOnFailure('johndoe@example.com') ;
The emailOnFailure() method is useful when you only want to receive an email for failed scheduled commands as opposed to the emailOutputTo method which is sent no matter what the outcome of the scheduled task. The new scheduler methods have already been added to the scheduling documentation.
Next, the SET datatype was added to the MySQL grammar (learn more about The SET Type):
Schema::create('table_name', function (Blueprint $table) { $table->bigIncrements('id'); $table->set("field_name", [ "Possible", "Values" ]); $table->timestamps(); });
The last new feature in this release is the addition of the in and not in operators, which can be passed as strings to the query builder:
// these two calls produce the same query $query->where('foo', 'in', [1, 2]); $query->whereIn('foo', [1, 2]); // these two calls produce the same query $query->where('foo', 'not in', [1, 2]); $query->whereNotIn('foo', [1, 2]);
You can see the full list of fixes below, and the whole diff between 5.8.11 and 5.8.12 on GitHub. The full release notes for Laravel 5.8 are available in the GitHub 5.8 changelog:
v5.8.12
Added
- Added Illuminate\Support\Collection::duplicates()
- Added Illuminate\Database\Eloquent\Collection::duplicates()
- Added Illuminate\View\FileViewFinder::getViews()
- Added helper methods onSuccess() \ onFailure() \ pingOnSuccess() \ pingOnFailure() \ emailOnFailure() to Illuminate\Console\Scheduling\Event
- Added SET datatype on MySQL Grammar
- Added possibility for use in / not in operators in the query builder
Fixed
- Fixed memory leak in JOIN queries
- Fixed circular dependency in Support\Testing\Fakes\QueueFake for undefined methods
- Fixed exception in lt \ lte \ gt \ gte validations with different types
- Fixed string quoting for SQL Server
- Fixed whereDay and whereMonth when passing int values
Changed
- Added autocomplete attributes to the html stubs
- Improved event:list command
- Updated Illuminate\Database\Console\Factories\FactoryMakeCommand to generate more IDE friendly code
- Added missing LockProvider interface on DynamoDbStore
- Change session’s user_id to unsigned big integer in the stub
For more Information and to build a website using Laravel, Hire Laravel Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.
To develop the custom website using Laravel, please visit our technology page
Content Source:
- laravel-news.com
Laravel Dusk: browser automation & PHP to programmatically surf the web
Laravel Dusk provides an expressive, easy-to-use browser automation and testing API. By default, Dusk does not require you to install JDK or Selenium on your machine. Instead, Dusk uses a standalone ChromeDriver installation. However, you are free to utilize any other Selenium compatible driver you wish.
Installation
To get started, you should add the laravel/dusk
Composer dependency to your project:
composer require --dev laravel/dusk
Once Dusk is installed, you should register the Laravel\Dusk\DuskServiceProvider
service provider. Typically, this will be done automatically via Laravel’s automatic service provider registration.
After installing the Dusk package, run the dusk:install
Artisan command:
php artisan dusk:install
A Browser directory will be created within your tests directory and will contain an example test. Next, set the APP_URL environment variable in your .env file. This value should match the URL you use to access your application in a browser.
To run your tests, use the dusk Artisan command. The dusk command accepts any argument that is also accepted by the phpunit
command:
php artisan dusk
Programmatically test applications
Laravel Dusk is a powerful browser automation tool for Laravel. With Dusk you can programmatically test your own applications or visit any website on the internet using a real Chrome browser. Using Dusk you can automate repetitive tasks, scrape information from other sites or test to make sure your app always works in the browser. In this tutorial we’ll go through how to create a job, login to a mythical website and click around.
Create a new Laravel app:
$ laravel new dusk-scraper $ composer require --dev laravel/dusk $ php artisan dusk:install Dusk scaffolding installed successfully.
In the tests/DuskTestCase.php file that Laravel generated you will have a call to startChromeDriver
in the prepare function (below). The prepare function gets called before the Dusk test is executed. It’s an abstract class so probably not a good place for us to put our code. We can make a new fresh dusk test case that extends the DuskTestCase with an Artisan command:
$ php artisan dusk:make ScrapeTheWebTest
This file (ScrapeTheWeb.php) will appear in tests/Browser directory. You can run the test with another Artisan command:
$ php artisan dusk-scraper
Right now it does not do anything. Here is the code to login to a website and click some buttons:
namespace Tests\Browser; use Tests\DuskTestCase; use Laravel\Dusk\Browser; use Illuminate\Foundation\Testing\DatabaseMigrations; class ScrapeTheWebTest extends DuskTestCase { private $order_ids; public function __construct($name = null, array $data = [], $dataName = '') { parent::__construct($name, $data, $dataName); $this->user_ids = [ 1, 2, 3, ]; } /** @test */ public function loginAndClickButton() { $this->browse(function (Browser $browser) { $browser->visit('https://website.com/login') ->type('input .usernameField', env('USERNAME')) ->type('input .passwordField', env('PASSWORD')) ->click('#login') ->waitForText('Orders'); @foreach($this->user_ids as $user_id) { $browser->visit('https://website.com/users/' . $user_id) ->waitForText('This is protected page') ->click('button .button-im-looking-4') ->waitForText('Page after the button') ->click('.another #button') ->pause(4000); } }); } }
We’m using environment variables to store the values for username and password so in case they are sensitive you don’t have to check them in to version control. To find elements on the page use CSS selectors and browser devtools to target specific elements. We filter through some custom numbers and visit websites dynamically based on this data.
Your tests will run in the terminal with the php artisan dusk command
. The fun really comes in when you see the browser perform the actions you specify. By default Laravel Dusk runs what’s called a headless browser that you won’t be able to watch. To watch the browser perform actions head to DuskTestCase.php that our ScrapeTheWebTest inherits from. Once there remove the --headless
option:
/** * Create the RemoteWebDriver instance. * * @return \Facebook\WebDriver\Remote\RemoteWebDriver */ protected function driver() { $options = (new ChromeOptions)->addArguments([ '--disable-gpu', //'--headless' ]); return RemoteWebDriver::create( 'http://localhost:9515', DesiredCapabilities::chrome()->setCapability( ChromeOptions::CAPABILITY, $options ) ); }
With the headless option removed you can run the tests and watch the browser perform the actions that you specified! From this command you can use the full power of Laravel to create database records, trigger jobs, update data or anything else you can think of.
For more Information and to build a website using Laravel, Hire Laravel Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.
To develop the custom website using Laravel, please visit our technology page
Content Source:
- medium.com
- laravel.com
Getting started with Laravel Nova
Laravel Nova, the latest addition to the Laravel ecosystem has arrived. So, what exactly is it?
Well, straight from the marketing website it’s defined as, “a beautifully designed administration panel for Laravel. Carefully crafted by the creators of Laravel to make you the most productive developer in the galaxy.” It can be everything from an admin panel to a CMS to a CRM, and I’m just scratching the surface. It’s rocket fuel for your Laravel projects that lets you focus on the features that matter to your users.
Features of Nova
- Resource Management: Allows for quick integration of your models to your dashboard. It supports all Eloquent relationships including pivot tables.
- Actions: Actions are PHP tasks that you can run against a resource or batch of resources. Have an action that takes a while? No problem, Nova’s queued actions will keep your administration panel feeling snappy.
- Filters: Write custom filters for your resource indexes to offer your users quick glances at different segments of your data. To get you started, we’ve included built-in filters for “soft deleted” resources.
- Lenses: Need to customize a resource list a little more than a filter can provide? No problem. Add lenses to your resource to take full control over the entire Eloquent query.
- Metrics: Nova makes it painless to quickly display custom metrics for your application, allowing you to generate three types of graphs in seconds. To put the cherry on top, we’ve included query helpers to make it all easy as pie.
- Authorization: Nova is beautifully integrated with Laravel’s existing authorization policies. Let your Nova resources automatically leverage your existing application policies to determine a user’s abilities. Fine-grained authorization support is even provided for relationships, tools, actions, lenses, and fields.
- Custom Fields: Need a field type that isn’t included with Nova? No problem – use the Nova CLI to generate a custom field and take total control over its implementation and design.
- Scout search integration: Feel the power of the Laravel ecosystem by linking your Nova administration panel with Laravel Scout. Once you do, you’ll get blazing fast search results powered by Algolia and the cloud.
- Custom Tools: Nova offers CLI generators for scaffolding your own custom tools. We’ll give you a Vue component and infinite possibilities. Build the custom tools your business requires, or build the next great Nova add-on and share it with the world.
Getting Started
First things first, you’ll need to head over to the Nova website and register for an account. Once you’re in, you’ll need to purchase a license to get access to the code.
Once you have a license, you can download the Nova files to your machine. Next, create a new Laravel project using laravel new <your-project-name>
or you can add it to an existing project. From the command line, I used mv <path-to-nova-download> <path-to-my-project-nova-directory>
to add it. This way, I was sure to include all of the hidden files like the .gitignore
Project Installation
With the source code in place, you can configure your composer.json to recognize Nova by adding this snippet:
"repositories": [ { "type": "path", "url": "./nova" } ],
Then, you’ll add Nova to the require section of composer.json like this:
"require": { "php": "^7.1.3", "fideloper/proxy": "^4.0", "laravel/framework": "5.6.*", "laravel/nova": "*" },
Before running the installation commands, make sure you configure your DB in your .env
.
With that setup, you can run the following commands from your terminal to install Nova:
composer update php artisan nova:install php artisan migrate
Bada bing bada boom, Nova is now installed in our project! We can now navigate to the /nova
route and see the login screen.

pics courtesy: medium.com
Add Your First User
To log in, we need to create a user. Nova includes an out-of-the-box command so we can register anyone on the fly. We can run php artisan nova:user
in our terminal and follow the prompts to add our first user. Now, we’re ready to log in and start our blog!

pics courtesy: medium.com
For more Information and to build a website using Laravel, Hire Laravel Developer from us as we give you a high-quality product by utilizing all the latest tools and advanced technology. E-mail us any clock at – hello@hkinfosoft.com or Skype us: “hkinfosoft“.
To develop the custom website using Laravel, please visit our technology page
Content Source:
- medium.com