PHP & Web Development Blogs

Search Results For: class
Showing 16 to 20 of 27 blog articles.
6749 views · 5 years ago
Custom extension to Laravel Application class

Hello folks! This post is for those of you using Laravel. This beautiful framework makes web development super-easy compared to most of competitors. In the heart of Laravel is the Application class, which is responsible for bootstrapping, registering services and also serves as a dependency injection container. What I do with my Laravel apps, is that I take a slight detour from the common path by adding a custom Application class. While this is not really necessary, I find this approach nice, and will try to share my thought below.

It's normal practice in Laravel world to build all kinds of objects like this:

$cache = app("cache");


I find it a bit confusing to call app("cache"") and expect a Cache\Repository instance as result. If I pass the result of this call to a function that requires a Cache\Repository as parameter, I will probably have a code inspection warning from IDE. Moreover, if I want proper autocompletion, I will have to add additional comment:


$cache = app("cache");


This is where a custom application class might be handy:

namespace App;
class MyApp extends Application
{
public function cacheRepository(): Repository
{
return $this->make(Repository::class);
}
}


This way I get a TypeError in case of a misconfiguration, and I have a type-hint which allows the IDE to recognize the return value. Bye-bye nasty comment lines and IDE warnings! I make a method per service, with type-hints, like dbConnection() or viewFactory() - works really well for me!

I also thought that, if I have a custom class, then all the custom setup that normally you have in bootstrap/app.php, should reside in that custom class:

namespace App;
class MyApp extends Application
{
public function __construct()
{
define('LARAVEL_START', microtime(true));
define("APP_ROOT", realpath(__DIR__ . "/../"));
parent::__construct(APP_ROOT);
$this->setUp();
}
private function setUp()
{
$this->singleton(
Contracts\Http\Kernel::class,
\App\Http\Kernel::class
);
}
}


Then your bootstrap/app.php becomes just this:

return new \App\MyApp;


The Laravel app() function will also return an instance of MyApp from now on. However, it's @phpdoc says it returns \Illuminate\Foundation\Application, so for better clarity, I also added my own accessor method:

namespace App;
class MyApp extends Application
{
public static function app(): self
{

$ret = parent::getInstance();
return $ret;
}
}


I tend to limit the use of global/static functions and methods, but sometimes it can be handy, and whenever I need an instance of MyApp, I just call MyApp::app(). The IDE wil be aware of the return type due to the type-hint, so I get everything I want for clean and clear development.

With your projects in Laravel, you may or may not want to follow this particular advice, but just be aware that extending a framework built-in classes for your team's comfort, is definitely something that can make your life easier. See you around, don't forget to leave comments!
19218 views · 5 years ago
Generate PDF from HTML in Laravel 5.7

Today, I will share with you how to create a PDF file from HTML blade file in Laravel 5.7. We will be using dompdf package for generating the PDF file.

In the below example, we will install barryvdh/laravel-dompdf using composer package and thereafter we will add new route url with controller. Then we will create a blade file. Then after we have to just run project with serve and we can check the PDF file is for download.

Download Laravel 5.7

Now I am going to explain the step by step from scratch with laravel installation for dompdf. To get started, we need to download fresh Laravel 5.7 application using command, so open our terminal and run the below command in the command prompt:

composer create-project --prefer-dist laravel/laravel blog


Install laravel-dompdf Package

Now we will install barryvdh/laravel-dompdf composer package by using the following composer command in ourLlaravel 5.7 application.

composer require barryvdh/laravel-dompdf


Then the package is successfully installed in our application, after that open config/app.php file and we need to add alias and service provider.
config/app.php

'providers' => [
....
Barryvdh\DomPDF\ServiceProvider::class,
],

'aliases' => [
....
'PDF' => Barryvdh\DomPDF\Facade::class,
]


Create Routes

Now we need to create routes for the items listing. so now open our "routes/web.php" file and we need to add following route.
routes/web.php

Route::get('demo-generate-pdf','HomeController@demoGeneratePDF');


Create Controller

Here,we need to create a new controllerHomeController (mostly it will be there, we can skip this step if we don't need to create a controller) that will manage our pdf generation using the generatePDF() method of route.
app/Http/Controllers/HomeController.php

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use PDF;

class HomeController extends Controller
{
public function demoGeneratePDF()
{
$data = ['title' => 'Welcome to My Blog'];
$pdf = PDF::loadView('myPDF', $data);

return $pdf->download('demo.pdf');
}
}


Create Blade File

In the final step, let us create demoPDF.blade.php in the resources/views/demoPDF.blade.php for structure of pdf file and add the following code:
resources/views/demoPDF.blade.php

<!DOCTYPE html>
<html>
<head>
<title>Hi</title>
</head>
<body>
<h1>Welcome to My BLOG - {{ $title }}</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</body>
</html>


Now run the below command for serve and test it:

php artisan serve

7612 views · 5 years ago
Iterator in PHP

Every time I see this
$users = [new User(), new User()];

I see a lost opportunity to use Iterator.

Why Iterators?

Collections are an awesome way to organize your previously no-named array. There is a couple of reasons why you should use iterators. One of reason stays for behavior, you can specify exact behavior on standard calls such as next, current, valid etc. Other reason could be that you want to ensure that collection contains an only specific type of an object.

Understand a suffer from using an array of unknown value types.
Very common in the PHP world arrays are used to store all kind of data, in many dimensions in many nested forms. Arrays introduced infinite flexibility to the developer, but because of that, they become very evil.

Example:

- Your function (getUsers) returns an array of User objects.
- Another function (setUsersToActiveState) using getUsers output array and set all users active status to true.
- setUsersToActiveState loop through the array and expect to call a specific method on array item. For example, the method name is getActiveStatus.
- If given array is an array of desired objects which have a callable method getActiveStatus, all fine. But if not exception will be thrown.
- How we can ensure that given array is always an array of objects of a specific type?

public function getUsers(): array
{

return $userArray;
}

public function setUsersToActiveState()
{
$users = $this->getUsers();

foreach ($users as $user) {
if(!$user->getActiveStatus()) {
$user->setActiveStatus(true);
}
}
}

There immediately two problems occurred.
    . One is the problem of type. Our IDE doesn't know what's inside array of $users, so because of that IDE can't suggest us how to use $user element. (I put this comment block above foreach, it works for phpStorm and I guess for some other IDEs)
    . Your colleagues! How they possibly know what's inside array if there is no any hint.
    . Bonus problem, getUsers can return literally any array and there won't be warning in the system.

Solution



class UsersCollection implements \IteratorAggregate
{

private $users = [];

public function getIterator() : UserIterator
{
return new UserIterator($this);
}

public function getUser($position)
{
if (isset($this->users[$position])) {
return $this->users[$position];
}

return null;
}

public function count() : int
{
return count($this->users);
}

public function addUser(User $users)
{
$this->users[] = $users;
}
}

class UserIterator implements \Iterator
{

private $position = 0;


private $userCollection;

public function __construct(UsersCollection $userCollection)
{
$this->userCollection = $userCollection;
}

public function current() : User
{
return $this->userCollection->getUser($this->position);
}

public function next()
{
$this->position++;
}

public function key() : int
{
return $this->position;
}

public function valid() : bool
{
return !is_null($this->userCollection->getUser($this->position));
}

public function rewind()
{
$this->position = 0;
}
}

Tests

Off course there is the tests to ensure that our Collection and Iterator works like a charm. For this example I using syntax for PHPUnit framework.

class UsersCollectionTest extends TestCase
{

public function testUsersCollectionShouldReturnNullForNotExistingUserPosition()
{
$usersCollection = new UsersCollection();

$this->assertEquals(null, $usersCollection->getUser(1));
}


public function testEmptyUsersCollection()
{
$usersCollection = new UsersCollection();

$this->assertEquals(new UserIterator($usersCollection), $usersCollection->getIterator());

$this->assertEquals(0, $usersCollection->count());
}


public function testUsersCollectionWithUserElements()
{
$usersCollection = new UsersCollection();
$usersCollection->addUser($this->getUserMock());
$usersCollection->addUser($this->getUserMock());

$this->assertEquals(new UserIterator($usersCollection), $usersCollection->getIterator());
$this->assertEquals($this->getUserMock(), $usersCollection->getUser(1));
$this->assertEquals(2, $usersCollection->count());
}

private function getUserMock()
{
}
}


class UserIteratorTest extends MockClass
{

public function testCurrent()
{
$iterator = $this->getIterator();
$current = $iterator->current();

$this->assertEquals($this->getUserMock(), $current);
}


public function testNext()
{
$iterator = $this->getIterator();
$iterator->next();

$this->assertEquals(1, $iterator->key());
}


public function testKey()
{
$iterator = $this->getIterator();

$iterator->next();
$iterator->next();

$this->assertEquals(2, $iterator->key());
}


public function testValidIfItemInvalid()
{
$iterator = $this->getIterator();

$iterator->next();
$iterator->next();
$iterator->next();

$this->assertEquals(false, $iterator->valid());
}


public function testValidIfItemIsValid()
{
$iterator = $this->getIterator();

$iterator->next();

$this->assertEquals(true, $iterator->valid());
}


public function testRewind()
{
$iterator = $this->getIterator();

$iterator->rewind();

$this->assertEquals(0, $iterator->key());
}

private function getIterator() : UserIterator
{
return new UserIterator($this->getCollection());
}

private function getCollection() : UsersCollection
{
$userItems[] = $this->getUserMock();
$userItems[] = $this->getUserMock();

$usersCollection = new UsersCollection();

foreach ($userItems as $user) {
$usersCollection->addUser($user);
}

return $usersCollection;
}

private function getUserMock()
{
}
}


Usage


public function getUsers(): UsersCollection
{
$userCollection = new UsersCollection();

foreach ($whatIGetFromDatabase as $user) {
$userCollection->addUser($user);
}
return $userCollection;
}

public fucntion setUsersToActiveState()
{
$users = $this->getUsers();

foreach ($users as $user) {
if(!$user->getActiveStatus()) {
$user->setActiveStatus(true);
}
}
}

As you can see setUsersToActiveState remains the same, we only do not need to specify for our IDE or collagues what type $users variable is.

Extending functionalities

Believe or not you can reuse this two objects and just change names of variables to fit most of the needs. But if you want any more complex functionality, than feel free to add it in iterator or collection.

Example 1


For example, let's say that userCollection accepts only users with age more than 18. Implementation will happen in UsersCollection class in the method addUser.

 public function addUser(User $users)
{
if ($user->getAge() > 18) {
$this->users[] = $users;
}
}

Example 2

You need to add bulk users. Then you can expand your userCollection with additional method addUsers and it might look like this.

public function addUsers(array $users)
{
foreach($users as $user) {
$this->addUser(User $users);
}
}

11626 views · 5 years ago
Creating a Tiny Blog Management system in Laravel 5.7

Hey There,
I am expecting you are familiar with PHP. In this post I will be using the Laravel framework to create a small blog system. I am showing here very simple steps to create blogs, If you want this complete code then please message me.
What are major Prequisites for Laravel:
* PHP version >= 5.6
* Composer should be installed in system

Create a project with name tiny_blog with following command

composer create-project laravel/laravel --prefer-dist tiny_blog


enter into the laravel project

cd tiny_blog


create a migration file using following artisan command
<pre>php artisan make:migration create_blog_table</pre>
After this command you will found a new file created in database/migrations folder in your project, Just edit the file having 'create_blog_table' appended in its name

Now replace following code to create table schema with function up(), So now the method will look like following:

public function up()
{
Schema::create('blogs', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id');
$table->string('category');
$table->string('title');
$table->text('description');
$table->timestamps();
});

}


replace following snippet with down method, it will look like following:

public function down()
{
Schema::dropIfExists('blogs');
}


Its time to run the migration file we have created

php artisan migrate



After running,It will create the blogs table in database.Now time to create form and insert data into the table

Laravel itsef provide authentication , use following artisan command :

php artisan make:auth


Now start Larvel:

php artisan serve


it will start the laravel development server at http://127.0.0.1:8000


Now if you run that url the basic default ui will be created and login & register link you can see in Top right position of header

You can register and login now.this feature is provided by authentication module.
Now we need to create a controller for manage blogs with following command:

php artisan make:controller BlogController


will create a file namedBlogController.php in** app/HTTP/controllers** folder location

Now we need to create a Model also, use following command

php artisan make:model Blog


will create a file namedBlog.php in app folder location

Now in Controller we need to create a method for create blogs and available that method in Routes to access it via url. Just editroutes/web.php file and add the following line

Route::get('blog/create','BlogController@createBlog');

/create/blog/ will be url route that land on Blog Controller's createBlog method using get method.

Now before running this route just go to the app/Http/Controllers folder and Edit BlogController.php file and Add the createBlog method in that class as following

public function createBlog()
{
return view('blog.create');
}


This code will try to load the view from/resources/views/blog/create.blade.php

In Laravel blade is a template engine. As we had not created the view file yet, so we need to create a blog folder inside/resources/views/ folder then inside blog folder create a file create.blade.php with following form

@extends('layouts.app')

@section('content')
<div class="container">
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div><br />
@endif
<div class="row">
<form method="post" action="{{url('blog/create')}}">
<div class="form-group">
<input type="hidden" value="{{csrf_token()}}" name="_token" />
<label for="title">Title:</label>
<input type="text" class="form-control" name="title"/>
</div>
<div class="form-group">
<label for="title">Category/Tags:</label>
<input type="text" class="form-control" name="category"/>
</div>
<div class="form-group">
<label for="description">Description:</label>
<textarea cols="10" rows="10" class="form-control" name="description"></textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
@endsection



Now we need to add a additional route to handle the post request on blog/create route, Just edit routes/web.php file and just add following line in last:

Route::post('blog/create','BlogController@saveBlog'); 


post route to handle the form post on route blog/create


Now create a method name saveBlog to save the user input data in the form
 public function saveBlog(Request $request)
{
$blog = new Blog();

$this->validate($request, [
'title'=>'required',
'category'=>'required',
'description'=> 'required'
]);

$blog->createBlog($request->all());
return redirect('blog/index')->with('success', 'New blog has been created successfully :)'); }


Notice This method is using Blog object that we don't know that where it comes from? , So to make above code working we need to include the model which we created earlier need to include in our controller file So use following code to include it before the class created.

use App\Blog;


Now following line shows that there is a method named createBlog in Model(app/Blog.php), but in actual it is not there:

$blog->createBlog($data);



So go to the file app/Blog.php and Edit it and inside the class add following method:

 public function createBlog($data)
{

$this->user_id = auth()->user()->id;
$this->title = $data['title'];
$this->description = $data['description'];
$this->category = $data['category'];
$this->save();
return 1;
}


Now the creation of blog task has been done , Its time to show the created Entries So just create a route blog/index in routes/web.php

Route::get('blog/index','BlogController@showAllBlogs');


get route blog/index to show all the created blogs by current user


Now just add a method in controller
public function showAllBlogs()
{
$blogs = Blog::where('user_id', auth()->user()->id)->get();

return view('blog.index',compact('blogs'));
}



This method requires to create a index view in blog folder , So create a file named index.blade.php in /resources/views/blog/ folder with following code

@extends('layouts.app')

@section('content')
<div class="container">
@if(\Session::has('success'))
<div class="alert alert-success">
{{\Session::get('success')}}
</div>
@endif
<a type="button" href="{{url('blog/create')}}" class="btn btn-primary">Add New Blog</a>
<br>
<table class="table table-striped">
<thead>
<tr>
<td>ID</td>
<td>Title</td>
<td>Category</td>
<td>Description</td>
<td colspan="2">Action</td>
</tr>
</thead>
<tbody>
@foreach($blogs as $blog)
<tr>
<td>{{$blog->id}}</td>
<td>{{$blog->title}}</td>
<td>{{$blog->category}}</td>
<td>{{$blog->description}}</td>
<td>Edit</td>
<td>Delete</td>
</tr>
@endforeach
</tbody>
</table>
<div>
@endsection



Now all code is ready but we need to add 1 line of code to prevent the blog controller without authentication or without login

just add the following constructor method in BlogController class

 public function __construct()
{
$this->middleware('auth');
}


this constructor method will call very first when user will try to access any of BlogController class method, and the middleware will check whether user is logged in then only it will allow to access that method otherwise it will redirect to login page automatically.


After It Run your Code and you will able to create and listing your created blogs/articles. but the Edit and Delete links are not working right now, If you want that also working then please comment here or message me. If we get multiple requests then definitely i will write its part 2 article


Thanks very much for reading this blog, if you have any doubt about it then let me know in comments or by messaging me.

Following is the final code for BlogController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Blog;



class BlogController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}

public function createBlog()
{
return view('blog/create');
}


public function saveBlog(Request $request)
{
$blog = new Blog();

$this->validate($request, [
'title'=>'required',
'category'=>'required',
'description'=> 'required'
]);

$blog->createBlog($request->all());
return redirect('blog/index')->with('success', 'New blog has been created successfully :)');
}

public function showAllBlogs()
{
$blogs = Blog::where('user_id', auth()->user()->id)->get();

return view('blog.index',compact('blogs'));
}

}

20480 views · 5 years ago
Making Charts and Graphs using Laravel

Installing composer

Composer is a package management tool for PHP. Laravel requires composer for installation. We can download composer from https://getcomposer.org/download/

After installation that you can test whether composer installed or not by command
composer

Installing Laravel

The current stable version of laravel is laravel 5.6. We can install laravel package with three ways.

In command prompt or terminal by running composer global require "laravel/installer" and then Laravel new

or

We can create the project with Composer by running composer create-project --prefer-dist laravel/laravel

or

Directly clone from github
git clone https://github.com/laravel/laravel/tree/master and after that composer update

Laravel local development server

Run the below command in command prompt or terminal
PHP artisan serve


Above command will start to local development servehttp://localhost:8000 or if you want to change default port:

php artisan serve --port 


Generating charts and graphs

We are using consoletvs package for generating charts. So for installation we can first move inside to our project using command prompt or terminal. We are following the below steps to install

Step 1:

First we need to install ConsoleTVs/Charts composer package inside our laravel project.
composer require consoletvs/charts


Step 2:

After successfully installation of above package, open app/config.php and add service provider.
In config/app.php


'providers' => [
....
ConsoleTVs\Charts\ChartsServiceProvider::class,
],


After the service provider we need to add alias
'aliases' => [
....
'Charts' => ConsoleTVs\Charts\Facades\Charts::class,
]



Step 3

We need to configure of database for application. We can configure in either .env file or config/database.php file.


Step 4

We can migrate our default tables that is user. We can find the table in database/migration folder.

Step 5

We can generate dummy records for demo in users table. For creating dummy records, we need to run the below command in command prompt or terminal
php artisan tinker>>> factory(App\User::class, 20)->create();

the above command will create a set of 20 records.

If we need to add more records we need to run the above command or we can increase the count as much as we want. For example
php artisan tinker>>> factory(App\User::class, 2000)->create();


Step 6Creating controller

For creating controller we need to run below command in terminal or command prompt
php artisan make controller:<controller_name>


Step 7Adding the routes

We can add the routes for navigating our application. You can find routes file inside routes folder. Before 5.4 we can find routes.php file itself, now its web.php. If you are using laravel 5.2 routes.php will inside app/http folder.

So inside web.php:

Route::get('create-chart/{type}','ChartController@makeChart');


Here type will be the parameter we are passing and it will focus to makeChart() function inside chartcontroller

Step 8

Import charts to controller, for that in the namespace section add:

Use charts;


Step 9

We can put the below code into chartController

public function makeChart($type)
{
switch ($type) {
case 'bar':
$users = User::where(DB::raw("(DATE_FORMAT(created_at,'%Y'))"),date('Y'))
->get();
$chart = Charts::database($users, 'bar', 'highcharts')
->title("Monthly new Register Users")
->elementLabel("Total Users")
->dimensions(1000, 500)
->responsive(true)
->groupByMonth(date('Y'), true);
break;
case 'pie':
$chart = Charts::create('pie', 'highcharts')
->title('HDTuto.com Laravel Pie Chart')
->labels(['Codeigniter', 'Laravel', 'PHP'])
->values([5,10,20])
->dimensions(1000,500)
->responsive(true);
break;
case 'donut':
$chart = Charts::create('donut', 'highcharts')
->title('HDTuto.com Laravel Donut Chart')
->labels(['First', 'Second', 'Third'])
->values([5,10,20])
->dimensions(1000,500)
->responsive(true);
break;
case 'line':
$chart = Charts::create('line', 'highcharts')
->title('HDTuto.com Laravel Line Chart')
->elementLabel('HDTuto.com Laravel Line Chart Lable')
->labels(['First', 'Second', 'Third'])
->values([5,10,20])
->dimensions(1000,500)
->responsive(true);
break;
case 'area':
$chart = Charts::create('area', 'highcharts')
->title('HDTuto.com Laravel Area Chart')
->elementLabel('HDTuto.com Laravel Line Chart label')
->labels(['First', 'Second', 'Third'])
->values([5,10,20])
->dimensions(1000,500)
->responsive(true);
break;
case 'geo':
$chart = Charts::create('geo', 'highcharts')
->title('HDTuto.com Laravel GEO Chart')
->elementLabel('HDTuto.com Laravel GEO Chart label')
->labels(['ES', 'FR', 'RU'])
->colors(['#3D3D3D', '#985689'])
->values([5,10,20])
->dimensions(1000,500)
->responsive(true);
break;
default:
break;
}
return view('chart', compact('chart'));
}


Step 10

Create a blade file. Blade is the view file used inside the laravel. You can add new blade file with any name with an extension of .blade.php
Here we are creating chart.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My Charts</title>
{!! Charts::styles() !!}
</head>
<body>

<div class="app">
<center>
{!! $chart->html() !!}
</center>
</div>

{!! Charts::scripts() !!}
{!! $chart->script() !!}
</body>
</html>


Step 11

We can run our laravel application in local development server by php artisan serve command:

http://localhost:8000/create-chart/bar
http://localhost:8000/create-chart/pie
http://localhost:8000/create-chart/donut
http://localhost:8000/create-chart/line
http://localhost:8000/create-chart/area
http://localhost:8000/create-chart/geo



In the above example we was creating line chart, geo chart, bar chart, pie chart, donut chart, line chart and area chart. We can also create gauge chart, progressbar chart, areaspline chart, scatter chart, percentage chart etc using consoletvs charts composer package.

There are a lot of jQuery libraries also available like amcharts, chartjs, highcharts, google, material, chartist, fusioncharts, morris, plottablejs etc. However, using this plugin we can easily create charts without having to use jQuery, another advantage to building it in with Laravel.

SPONSORS