Content Source:
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
- medium.com
AdonisJS: Templating, Authentication and Validators
In our previous post about AdonisJS we had covered introduction, installation, modeling, creating and displaying content, creating and deleting task. Let’s move on remaining part of it with this post.
A bit of templating
Our application is going to grow. In order to reuse some parts of the html, we are going to define a main layout, and include the specific code of each page into it.
Create a “layout_main.edge” file into “resources/views”. This file will include the base of our page, and will be used by each page we create.
<!DOCTYPE html> <html> <title>Task list</title> {{style('style')}} </head> <body> @!section('content') </body> </html>
Now you can refactor tasklist.edge
@layout('layout_main') @section('content') @if(flashMessage('taskHandling')) <span>{{ flashMessage('taskHandling') }}</span> @endif <form action="{{ route('TaskController.create') }}" method="POST"> {{ csrfField() }} <input type="text" name="title" placeholder="title" /> <input type="text" name="description" placeholder="description" /> <button type="submit">Create the task</button> </form> <section> <h1>Tasks</h1> @each(task in tasks) <div class="task"> <h2> @if(task.done) <input type="checkbox" disabled checked /> @else <input type="checkbox" disabled /> @endif {{task.title}} </h2> <form action="/task/delete/{{task.id}}" method="DELETE"> <button type="submit">Delete</button> </form> <p>{{task.description}}</p> </div> @endeach </section> @endsection
Authentication
You have probably already seen that there are some files to manage users in your project (“app/Models/User.js”)
First, let’s add a UserController :
#Choose "For HTTP requests" adonis make:controller UserController
Go to the router (“start/routes.js”) and some routes :
- two routes for the login and register process, displaying the templates with the forms
- two routes for receiving login and register data and handling user creation and login
- One route for the logout process
Route.on('/register').render('register') Route.on('/login').render('login') Route.post('/register', 'UserController.create') Route.post('/login', 'UserController.login') Route.get('/logout', 'UserController.logout')
Then, add the templates :
“resources/views/login.edge”
@layout('layout_main') @section('content') <form action="{{ route('UserController.login') }}" method="POST"> {{ csrfField() }} <input type="text" name="email" placeholder="email" /> <input type="password" name="password" placeholder="" /> <button type="submit">Login</button> </form> @endsection
“resources/views/register.edge”
@layout('layout_main') @section('content') <form action="{{ route('UserController.create') }}" method="POST"> {{ csrfField() }} <input type="text" name="email" placeholder="email" /> <input type="password" name="password" placeholder="" /> <button type="submit">Create new user</button> </form> @endsection
“Controllers/http/UserController.js”
'use strict' const User = use('App/Models/User') class UserController { async create({ request, response, auth }) { const userPayload = request.all(); const user = new User; user.email = userPayload.email; //We will also use the mail as username to simplify things here user.username = userPayload.email; user.password = userPayload.password; await user.save(); await auth.login(user); return response.redirect('/'); } async login({ request, response, auth, session }) { const userPayload = request.all(); try { await auth.attempt(userPayload.email, userPayload.password) } catch (e) { console.log(e); session.flash({ loginError: e }); } return response.redirect('/'); } async logout ({ auth, response }) { await auth.logout(); return response.redirect('/'); } } module.exports = UserController
You can also modify the tasklist template to add the register and login links, and a logout link if the user is logged in.
You can also include the create task form into the loggedIn conditionnal, in order to prevent anonymous users to create tasks.
... @section('content') @loggedIn <a href="logout">Log out</a> @else <a href="login">Log in</a> <a href="register">Register</a> @endloggedIn ...
More features
We now have seen what a basic and naive approach to build a web app can look like. You might have thought about a lot of other features to include in the project. Here is a quick list of other things Adonis can provide to you :
Relations between models
You want the tasks to be owned by users, you can create relations between models with the following syntax :
class User { tasks () { return this.hasMany('App/Model/Task'[, primaryKey, foreignKey]) } }
You can also use hasOne, belongsTo, belongsToMany and manyThrough.
Validators
You can use validators to check is the data flowing into your controllers has the right format, and emit messages (via session.flash for instance) when some errors occurs.
Validators are a 3rd party npm module : https://www.npmjs.com/package/adonis-validator
Using websocket instead of HTTP requests
As you might have seen when creating controllers, you can also generate controllers that are designed to use websockets.
Internationalization
A full guide to make you app multilanguage is available on the Adonis docs as well :
Conclusion
Adonis is a great choice for those who need a full-featured web server framework, and who need to keep control over your implementation.
This framework could be of a great use if you want to kickstart a project, if you want to follow usual guidelines and concepts. It will help you to implement data migrations, keep your code clean, handle data validation…
However, integrating exotic libraries can be painful. Adonis extensions need to be specifically built for this framework. This would be perfect for Adonis and it’s users if the framework would be in a monopoly situation, which is not the case.
Hire Node.js Developer from us, as we give you 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 web app using Node.js, please visit our technology page.
Content Source:
- blog.sourcerer.io
AdonisJS: A full featured node framework for modern web servers
Node is becoming one of the most elected choices by developers for modern web servers. You can build web servers in various elegant ways, using up-to-date tools such as ExpressJS.
However, a lot of developers had a hard time to stick on a high level framework to build web servers for their applications, sticking with tools that will stay light but will require a lot of configuration and wiring to produce a complete setup for a large project.
we are going to focus on a higher-level framework that comes with batteries included, and that will allow you to implement advanced features easily.
pic courtesy: blog.sourcerer.io
Meet AdonisJS
AdonisJS is a node framework inspired by the well-known Php framework Laravel. It relies on concepts such as dependency injection and service providers to make you design beautiful, reliable and easily testable code.
Get prepared to leave spaghetti code in favor of reusable OO structure.
Installation
First things first, to create a new AdonisJS server, you will need to install Adonis CLI, the command line tool that will help you manage your projects :
npm i -g @adonisjs/cli
This will provide you a “adonis” command to use in your terminal
To create a new adonis application, use the subcommand “new” :
adonis new my-adonis-server
As explained in the log, is uses the default fullstack-app template (adonisjs/adonis-fullstack-app), to create your project in a “my-adonis-server” folder.
You can now go to this folder and start serving your app in development mode :
cd my-adonis-server adonis serve --dev
Your app is now served from your machine, you can now dive into your project !
Keep the server running for the rest of the introduction.
pic courtesy: blog.sourcerer.io
A bit of modeling
Let’s now create one API to manage a resource. In the following chapter, we will create an endpoint to manage tasks.
First, let’s setup the project so it uses sqlite :
adonis install sqlite3
Then create the Task SQL table :
adonis make:migration tasks # select "create table" adonis migration:run
Note that every time you want to edit your database, you will have to create a migration.
Migrations will allow you to save every modification you are doing to your models, and will update data to follow the new formats and rules you are implementing. It is possible to define a "up" method, and a "down" method, depending if you want to switch to go to a newer or older version.
Then, create the model and controller related to this table :
adonis make:model Task adonis make:controller TaskController # select "For HTTP requests"
You now have set up you database, created a table, a model, and a controller. The source code for the model and the controller is present on the app folder.
pic courtesy: blog.sourcerer.io
You might have noticed that as you entered the last commands, the server automatically detected that your project changed, and took care of reloading the new setup.
Now we can add some content to our model. By creating another migration.
adonis make:migration tasks
Now edit the new file under database/migrations
'use strict' const Schema = use('Schema') class TasksSchema extends Schema { up () { this.table('tasks', (table) => { // alter table table.string('title') table.string('description') table.boolean('done') }) } down () { this.table('tasks', (table) => { // reverse alternations }) } } module.exports = TasksSchema
And run this migration
adonis migration:run
Now, you tasks models have a title, description, and done properties.
Creating a page displaying content
Now let’s create a page that displays a list of tasks.
//Route.on('/').render('welcome') Route.get('/', 'TaskController.home')
Then, on your TaskController, add the code handling the “/” route.
'use strict' const Task = use('App/Models/Task') class TaskController { async home({view}) { // Fetch tasks const tasks = await Task.all() return view.render('tasklist', { tasks: tasks.toJSON() }) } } module.exports = TaskController
And add the template of the page in “resources/views/tasklist.edge”
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <title>Task list</title> {{ style('style') }} </head> <body> <section> <h1>Tasks</h1> @each(task in tasks) <div class="task"> <h2> @if(task.done) <input type="checkbox" disabled checked /> @else <input type="checkbox" disabled /> @endif {{task.title}} </h2> <p>{{task.description}}</p> </div> </div> @endeach </section> </body> </html>
In the “public/style.css”, delete all the css rules, to put :
.task { border: 1px solid darkgrey; border-radius: 6px; background: lightgrey; margin: 10px; padding-left: 10px; padding-right: 10px; }
This will display an empty list of tasks on “localhost:3000/” (so basically, nothing at the moment !)
It is currently empty because there is no tasks at the moment on the database. Let’s fix this!
Creating tasks in your database
For the sake of this tutorial, we will create our first tasks on the TaskController method we already defined:
/* ... */ async home({view}) { // Fetch tasks const task1 = new Task task1.title = 'Walk the dog' task1.description = 'Go and walk for half an hour' task1.done = false const task2 = new Task task2.title = 'Feed the cat' task2.description = 'The food is on the fridge' task2.done = false const task3 = new Task task3.title = 'Buy some pizza' task3.description = 'Go at the shop before 7pm' task3.done = true await task1.save() await task2.save() await task3.save() const tasks = await Task.all() return view.render('tasklist', { tasks: tasks.toJSON() }) } /* ... */
Load the tasklist once to insert your tasks in the database, then erase or comment those methods.
You should now see your tasks on the page.
Creating new tasks
Once this working, we would like to add new content via a new task form.
On your task controller, enter the task creation logic :
class TaskController { /* ... */ async create({ request, response, session, auth}) { const taskPayload = request.all() const task = new Task task.title = taskPayload.title task.description = taskPayload.description task.done = false await task.save() session.flash({ message: 'Task created!' }) return response.redirect('back') } }
The task creation form in your tasklist template :
@if(flashMessage('message')) <span>{{ flashMessage('message') }}</span> @endif <form action="{{ route('TaskController.create') }}" method="POST"> <input type="text" name="title" placeholder="title" /> <input type="text" name="description" placeholder="description" /> <button type="submit">Create task</button> </form> ...
And the post route in “start/routes.js”
Route.post('/task/create', 'TaskController.create')
Now you can add tasks from the form displayed in your task list.
Deleting Tasks
To delete tasks, the implementation is pretty much the same as the one we did to create tasks :
- Add a delete method in the controller
- Adapt the template
- Create the DELETE route
TaskController :
/* ... */ class TaskController { /* ... */ async delete({ request, response, session, params}) { const task = await Task.find(params.id) await task.delete() session.flash({ taskHandling: 'Task deleted!'}) return response.redirect('back') } }
“resources/views/tasklist.edge”
... <section> <h1>Tasks</h1> @each(task in tasks) <div class="task"> <h2> @if(task.done) <input type="checkbox" disabled checked /> @else <input type="checkbox" disabled /> @endif {{task.title}} </h2> <a href="/task/delete/{{task.id}}">Delete</a> <p>{{task.description}}</p> </div> </div> @endeach </section> ...
“start/routes.js”
Route.get('/task/delete/:id', 'TaskController.delete')
In this blog we have covered the basics of Adonis JS. If you really enjoyed reading it, please checkout our next blog in series to learn more about ‘Templating’, ‘Authentication’ and many more Adonis JS features.
Hire Node.js Developer from us, as we give you 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 web app using Node.js, please visit our technology page.
Content Source:
- blog.sourcerer.io
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 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
Vue JS and Laravel – The best performative combination for front-end and back-end
“Vue.js is a dynamic structure for building UIs”. Vue.js at its core is centered on the view layer just of an application, so integrating with different stages or existing applications is extremely simple. You can likewise utilize Vue.js all alone to manufacture modern single page applications.
Uses and Features of Vue.js
- Vue.js is extremely simple to use and has a substantially little learning curve than other frameworks.
- It has impacting features compared to others. Vue.js utilizes virtual DOM and that makes it extremely quick.
- On the off chance that you are working in a group with various engineers at that point don’t stress. Since Vue.js can without much of a stretch incorporate with other mainstream structures.
- Vue.js has many Built-in parts while it’s extremely lightweight.
Vue.js has got prominent reception, with many open source frameworks and enormous organizations embracing it for building up the front-end. Laravel, the leading PHP web framework, now comes with Vue.js integrated as the default front-end
Features of Laravel in a glimpse
- Caching
- Laravel Scout
- Composer
- Templates
- Libraries
- Direct Testing Option
Why should we use Vue.js with Laravel?
Event Driven Application on the Front-End
Applications on the web today are event-driven. Vue.js gives you a chance to assemble a full-scale application that is event-driven and has all activity totally handle on the frontend. They are built to guarantee clients have a consistent experience like they would if they utilized an application introduced on their PC.
Everything happens in front-end due to which the pages are not loaded again and again for any process to take place. This event-driven concept is a feature of Vue.js.
Reactive components constitute for an event-driven app
Given that it couples pleasantly with Laravel, you will just need to make a couple of requests for information from your Laravel application and roll out UI improvements by exchanging components without reloading the page.
One can trigger UI changes that are seamless with your Vue.js frontend, which in turn gives users an incredible experience. Given Vue.js speed and execution, this happens quick and easily without taking up such a large amount of your PC resources.
Build complex frontend pages
When you make your application with Vue.js components, every component’s conditions are consequently tracked amid its render, so the framework knows decisively which part is to be updated. This makes all updates to the DOM utilize negligible assets, along these lines enhancing the general application proficiency.
Vue.js utilization of a one-way data binding model also makes state management easier in complex applications.
Single-Page Apps
Single Page Applications are the best in the most recent decade. It opens up an application to a more extensive group of users than previously.
The whole application resources get stacked once everything that your application does as the client connects with it is asking for information which commonly requires low data transmission to fulfill a request.
Easy to learn and use
Vue.js is not at all hard to get into. You feel that you are composing plain JavaScript when you utilize Vue.js and you can make a basic application with plain JavaScript and it stays legitimate in Vue.js.
Another awesome thing about Vue.js is that your substantial HTML is additionally a legitimate Vue.js layout. You can keep your CSS outside or you can process it with JavaScript relying upon your application needs. You can likewise exploit checked styling, to apply style changes to a solitary segment on the fly without the change influencing different parts.
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 Vue.js, please visit our technology page
Eventy: WordPress-like Actions and Filters for Laravel
Eventy is a Laravel package by Tor Morten Jensen that brings WordPress-style actions and filters to your Laravel app.
This package has a lightweight API and makes it easy to build an action and filter system as found in WordPress. The action and filter system in WordPress is a powerful way to customize WordPress themes without modifying the template. For example, your users could easily tap into the <title></title>
tag (think wp_title
) to modify the way that title tags work without modifying the template.
Actions
Actions are code that you want to enable the ability to tap into code execution at a given point in your code.
Here’s the basic API for creating actions:
Eventy::action('my.hook', 'awesome');
The best place to add action listeners is in a service provider boot()
method:
public function boot() { Eventy::addAction('my.hook', function($what) { echo 'You are '. $what; }, 20, 1); }
The Eventy::addAction()
method accepts the action name, the callback, the priority, and the number of expected args. The lower the priority number, the earlier the execution.
Filters
Like WordPress filters, the Eventy library provides a filter method to modify passed values. Every time a filter is called it returns it’s value after running through various callbacks:
$value = Eventy::filter('my.hook', 'awesome');
The first argument is the filter name, and the second is the value. If no filter listeners are attached, the return value would be awesome
.
The method siguature is the same as actions, including the priority and number of expected arguments:
Eventy::addFilter('my.hook', function($what) { $what = 'not '. $what; return $what; }, 20, 1); // returns `not awesome`
You can even combine actions and filters together:
Eventy::addAction('my.hook', function($what) { $what = Eventy::filter('my.hook', 'awesome'); echo 'You are '. $what; });
Templates
Using the same examples from the project’s readme, here’s what the template syntax looks like for this package:
{{-- for example, `echo "awesome"` --}} @action('my.hook', 'awesome') You are @filter('my.hook', 'awesome')
For more Information and to build website using Laravel, Hire Laravel Developer from us as we give you 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 custom website using Laravel, please visit our technology page.
Content Source:
- laravel-news.com
VuePress: A Vue-powered Static Site Generator
VuePress is a minimalistic Vue-powered static site generator from Evan You, the creator of Vue.js. It was built to support the documentation needs of Vue’s projects. By default, the generated theme comes optimized for technical documentation.
VuePress sites are an SPA, and during a build, a server-rendered version gets created by visiting each route. VuePress is powered by Vue, Vue Router, and Webpack. You also can use Vue inside of your markdown!
Getting Started with VuePress
You can quickly add documentation to an existing project writing in Markdown format. The following example is from the getting started section of the guide and serves as an example of how quickly you can get started:
# install as a local dependency yarn add -D vuepress # OR npm install -D vuepress # create a docs directory mkdir docs # create a markdown file echo '# Hello VuePress' > docs/README.md
While you are writing content, the browser gets updated in real-time, which is extremely helpful while building documentation.
Features
Vue components in .vuepress/components
are automatically registered as global, async components that can be used directly in your markdown documentation.
Markdown files are first compiled to HTML and passed on as a Vue component to vue-loader
, and you can use Vue interpolation and have access to site data:
{{ 5 + 5 }} {{ $page }}
VuePress enables custom theming through Vue single file components. You can create a custom theme at .vuepress/themes/Layout.vue
, and you can organize your theme however you want. You can use a custom theme from a dependency with the format of an NPM module vuepress-theme-xxx
, in the following example that would be vuepress-theme-cobalt
:
module.exports = { theme: 'cobalt' }
You can use Markdown extensions including YAML front matter, emoji support, Github-style tables, and custom blocks:
::: danger STOP Danger zone, do not proceed :::
Which might look something like the following with the default theme.

Pic courtesy: laravel-news.com
For more Information and to build website using Laravel, Hire Laravel Developer from us as we give you 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 custom website using Laravel, please visit our technology page.
Content Source:
- laravel-news.com
Laravel Model Caching
You’ve probably cached some model data in the controller before, but here’s we like to show you a Laravel model caching technique that’s a little more granular using Active Record models.
Using a unique cache key on the model, you can cache properties and associations on your models that are automatically updated (and the cache invalidated) when the model (or associated model) is updated. A side benefit is that accessing the cached data is more portable than caching data in the controller, because it’s on the model instead of within a single controller method.
Here’s the gist of the technique:
Let’s say you have an Article
model that has many Comment
models. Given the following Laravel blade template, you might retrieve the comment count like so on your /article/:id
route:
<h3>$article->comments->count() {{ str_plural('Comment', $article->comments->count())</h3>
You could cache the comment count in the controller, but the controller can get pretty ugly when you have multiple one-off queries and data you need to cache. Using the controller, accessing the cached data isn’t very portable either.
We can build a template that will only hit the database when the article is updated, and any code that has access to the model can grab the cached value:
<h3>$article->cached_comments_count {{ str_plural('Comment', $article->cached_comments_count)</h3>
Using a model accessor, we will cache the comment count based on the last time the article was updated.
So how do we update the article’s updated_at
column when a new comment is added or removed?
Enter the touch method.
Touching Models
Using the model’s touch()
method, we can update an article’s updated_at
column:
$ php artisan tinker
>>> $article = \App\Article::first();
=> App\Article {#746
id: 1,
title: "Hello World",
body: "The Body",
created_at: "2018-01-11 05:16:51",
updated_at: "2018-01-11 05:51:07",
}
>>> $article->updated_at->timestamp
=> 1515649867
>>> $article->touch();
=> true
>>> $article->updated_at->timestamp
=> 1515650910
We can use the updated timestamp to invalidate a cache, but how can we touch the article’s updated_at
field when we add or remove a comment?
It just so happens that Eloquent models have a property called $touches
. Here’s what our comment model might look like:
<?php
namespace App;
use App\Article;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
protected $guarded = [];
protected $touches = ['article'];
public function article()
{
return $this->belongsTo(Article::class);
}
}
The $touches
property is an array containing the association that will get “touched” when a comment is created, saved, or removed.
The Cached Attribute
Let’s go back to the $article->cached_comments_count
accessor. The implementation might look like this on the App\Article
model:
public function getCachedCommentsCountAttribute()
{
return Cache::remember($this->cacheKey() . ':comments_count', 15, function () {
return $this->comments->count();
});
}
We are caching the model for fifteen minutes using a unique cacheKey()
method and simply returning the comment count inside the closure.
Note that we could also use the Cache::rememberForever()
method and rely on our caching mechanism’s garbage collection to remove stale keys. We’ve set a timer so that the cache will be hit most of the time, with a fresh cache every fifteen minutes.
The cacheKey()
method needs to make the model unique, and invalidate the cache when the model is updated. Here’s my cacheKey
implementation:
public function cacheKey()
{
return sprintf(
"%s/%s-%s",
$this->getTable(),
$this->getKey(),
$this->updated_at->timestamp
);
}
The example output for the model’s cacheKey()
method might return the following string representation:
articles/1-1515650910
The key is the name of the table, the model id, and the current updated_at
timestamp. Once we touch the model, the timestamp will be updated, and our model cache will be invalidated appropriately.
Here’s the Article
model if full:
<?php
namespace App;
use App\Comment;
use Illuminate\Support\Facades\Cache;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
public function cacheKey()
{
return sprintf(
"%s/%s-%s",
$this->getTable(),
$this->getKey(),
$this->updated_at->timestamp
);
}
public function comments()
{
return $this->hasMany(Comment::class);
}
public function getCachedCommentsCountAttribute()
{
return Cache::remember($this->cacheKey() . ':comments_count', 15, function () {
return $this->comments->count();
});
}
}
And the associated Comment
model:
<?php
namespace App;
use App\Article;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
protected $guarded = [];
protected $touches = ['article'];
public function article()
{
return $this->belongsTo(Article::class);
}
}
What’s Next?
We’ve shown you how to cache a simple comment count, but what about caching all the comments?
public function getCachedCommentsAttribute()
{
return Cache::remember($this->cacheKey() . ':comments', 15, function () {
return $this->comments;
});
}
You might also choose to convert the comments to an array instead of serializing the models to only allow simple array access to the data on the frontend:
public function getCachedCommentsAttribute()
{
return Cache::remember($this->cacheKey() . ':comments', 15, function () {
return $this->comments->toArray();
});
}
Lastly, we defined the cacheKey()
method on the Article
model, but you would want to define this method via a trait called something like ProvidesModelCacheKey
that you can use on multiple models or define the method on a base model that all our models extend. You might even want to use a contract (interface) for models that implement a cacheKey()
method.
Hire Laravel Developer from us, as we give you 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 custom web app using Laravel, please visit our technology page.
Content Source:
- laravel-news.com