Showing posts with label Laravel. Show all posts
Showing posts with label Laravel. Show all posts

Wednesday, December 18, 2019

Laravel Custom Data Validation | Validate Request Data And Return Appropriate Error Message

Now we are ready to fill in our store method with the logic to validate the new blog post. To do this, we will use the validate method provided by the Illuminate\Http\Request object. If the validation rules pass, your code will keep executing normally; however, if validation fails, an exception will be thrown and the proper error response will automatically be sent back to the user. In the case of a traditional HTTP request, a redirect response will be generated, while a JSON response will be sent for AJAX requests.
<?php
namespace App\Http\Controllers;

use Validator;
use App\Models\Users;
use Illuminate\Support\Facades\Log;

class RegistrationController extends ControllerBase {
    /**
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function register() {
        if ($this->isLoggedIn()) {
            $this->setErrorMessage("Already logged in");
            throw new \Exception("Already logged in");
        }

        // if data is json formatted
        if (true) {
            $data = json_decode(request()->getContent(), true);

            request()->merge($data);
        }

        // custom messaged will show when validation fail
        // for example if name is missing will return 'The Name field is required'
        // we can define full message without using :attribute like 'email.unique'
        $customMessages = [
            'required' => 'The :attribute field is required.',
            'in' => 'The :attribute field has invalid data',
            'password.required' => 'Password required',
            'email.unique' => 'Email address must be unique'
        ];

        // used to set display name against key
        // for example if email is required then 'The Email Address field is required'
        $attributes = [
            'name' => 'Name',
            'email' => 'Email Address',
            'password' => 'Password',
            'status' => 'Status'
        ];

        $validator = Validator::make(request()->all(), [
            'name' => 'required|max:70',
            'email' => 'required|email|max:70|unique:users',
            'password' => 'required|min:6|max:70',
            'status' => 'required|in:pending',
        ],  $customMessages, $attributes);

        $validator->after(function($validator) {
            // If some validation failed
            if (true) {
                $validator->errors()->add('field', 'The field has invalid data');
            }
        });

        if ($validator->fails()) {
            Log::error($validator->errors());
            return response()->json(["success" => 0, "error" => $validator->errors()->first()], 200);
        }

        $user = Users::create(request([
            'name',  'email', 'password', 'status'
        ]));

        return response()->json(["success" => 1, "user_id" => $user->id]);
    }
}

Tuesday, November 12, 2019

How to configure virtual host for Laravel on Linux

In this article we will discuss How to configure virtual host for Laravel with Apache server as web server (I installed lampp on my linux machine, which contains apache server installed). It would be very helpful to be able to manage many site on the same host specially when we work with api and specially when want feel like project is running on a real server like my_laravel.com.
At first we need to enable virtual host, below is the command to edit httpd.conf:

sudo gedit /opt/lampp/etc/httpd.conf
Now locate

# Virtual hosts
#Include etc/extra/httpd-vhosts.conf

and comment out the following line:

Include etc/extra/httpd-vhosts.conf
Next step is to put and entry to system host file (execute below command):

sudo gedit /etc/hosts

And add entry 127.0.0.1 my_laravel.com to the end of the file
Next step is to modify file httpd-vhosts.conf, execute below command to modify:

sudo gedit /opt/lampp/etc/extra/httpd-vhosts.conf
<VirtualHost *:80>
    DocumentRoot "/opt/lampp/htdocs"
    ServerName localhost
</VirtualHost>


<VirtualHost my_laravel.com:80>
    DocumentRoot "/home/pritom/codes/laravel_test_success/public"
    ServerName my_laravel.com
    ErrorLog "logs/my_laravel.com-error.log"
    CustomLog "logs/my_laravel.com-access.log" combined
    <Directory "/home/pritom/codes/laravel_test_success/">
        Options Indexes FollowSymLinks MultiViews
            AllowOverride All
            Order allow,deny
            allow from all
            Require all granted
    </Directory>
</VirtualHost>
Finally restart apache server using command
sudo /opt/lampp/lampp restart
and browse my_laravel.com from browser

Saturday, March 9, 2019

Install ReactJS along with Laravel 5.X along with higher version such 6.X

We need npm command, so for this we need to install NodeJS first, this will create NPM along with this, for windows users, go to https://nodejs.org/en/ and download your suitable installer and install if not alredy installed..
Now we will create an Laravel project first using following command (this will take some time):
composer create-project --prefer-dist laravel/laravel ReactJSLaravelTutorial


Laravel installed:

Now we need to initiate scaffolding with React. Luckily for us, there is a preset Artisan command we can use for that. The preset command was added in Laravel 5.5, which allows us to specify our JavaScript framework of choice.

php artisan preset react

After that, we need to install the JavaScript dependencies of our project. By default, package.json file is there, so we just need to type the following command to get the NPM dependencies.

Please run npm install && npm run dev to compile your fresh scaffolding.
We should now have an Example.js file inside resources/assets/js/components, which is a basic React component. Also, resources/assets/js/app.js has been updated to make use of the Example component.

Now go to your database manager, for example, phpMyAdmin or MySQL work bench and create one database.
Go to .env file and enter your database credentials.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db-laravel1
DB_USERNAME=root
DB_PASSWORD=
Now we will create a model using command: php artisan make:model Project -m (this will create an migration script):

D:\all-my-php-projects\ReactJS\ReactJSLaravelTutorial>php artisan make:model Project -m
Model created successfully.
Created Migration: 2019_03_03_153423_create_projects_table

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Project extends Model
{
    protected $fillable = ['name', 'description'];
}

<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateProjectsTable extends Migration
{
    public function up()
    {
        Schema::create('projects', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->text('description');
            $table->boolean('is_completed')->default(0);
            $table->timestamps();
        });
    }

    public function down()
    {
        
    }
}

And execute command php artisan migrate, this will create/modify table as needed.
We’ll start by defining the API endpoints. Open routes/api.php and replace it content with the code below:

<?php
Route::get('projects', 'ProjectController@index');
Route::post('projects', 'ProjectController@store');
Route::get('projects/{id}', 'ProjectController@show');
Route::put('projects/{project}', 'ProjectController@markAsCompleted');
Now we will create controller using command: php artisan make:controller ProjectController

<?php
namespace App\Http\Controllers;

use App\Project;
use Illuminate\Http\Request;

class ProjectController extends Controller
{
    public function index()
    {
        $projects = Project::where('is_completed', false)
            ->orderBy('created_at', 'desc')
            ->withCount(['tasks' => function ($query) {
                $query->where('is_completed', false);
            }])
            ->get();

        return $projects->toJson();
    }

    public function store(Request $request)
    {
        $validatedData = $request->validate([
            'name' => 'required',
            'description' => 'required',
        ]);

        $project = Project::create([
            'name' => $validatedData['name'],
            'description' => $validatedData['description'],
        ]);

        return response()->json('Project created!');
    }

    public function show($id)
    {
        $project = Project::with(['tasks' => function ($query) {
            $query->where('is_completed', false);
        }])->find($id);

        return $project->toJson();
    }

    public function markAsCompleted(Project $project)
    {
        $project->is_completed = true;
        $project->update();

        return response()->json('Project updated!');
    }
}
We’ll be using React Router to handle routing in our application. For this, we need to render a single view file for all our application routes. Open routes/web.php and replace it content with the code below:

Route::view('/{path?}', 'app');
Next, let’s create the app.blade.php view file. We’ll create this file directly within the resources/views directory, then paste the following code in it:

<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <title>Project Management</title>
    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app"></div>

<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
The App component will serve as the base for our React components. Let’s rename the default Example component to App and replace it content with the following code:
// resources/js/components/App.js

import React, { Component } from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import Header from './Header'
import ProjectsList from './ProjectsList'

class App extends Component {
    render () {
        return (
            <BrowserRouter>
                <div>
                    <Header />
                    <Switch>
                        <Route exact path='/' component={ProjectsList} />
                    </Switch>
                </div>
            </BrowserRouter>
        )
    }
}

ReactDOM.render(<App />, document.getElementById('app'));


Now install react router using command: npm install react-router-dom

update resources/assets/js/app.js as below:

require('./bootstrap');
require('./components/App');
Create a new Header.js file within the resources/js/components directory and paste the code below in it:

import React from 'react'
import { Link } from 'react-router-dom'

const Header = () => (
    <nav className='navbar navbar-expand-md navbar-light navbar-laravel'>
        <div className='container'>
            <Link className='navbar-brand' to='/'>Project Management</Link>
        </div>
    </nav>
);

export default Header
Create a new ProjectsList.js file within the resources/js/components directory and paste the code below in it:

import axios from 'axios'
import React, { Component } from 'react'
import { Link } from 'react-router-dom'

class ProjectsList extends Component {
    constructor () {
        super();
        this.state = {
            projects: []
        }
    }

    componentDidMount () {
        axios.get('/api/projects').then( response => {
            this.setState({
                projects: response.data
            })
        })
    }

    render () {
        const { projects } = this.state;
        return (
            <div className='container py-4'>
                <div className='row justify-content-center'>
                    <div className='col-md-8'>
                        <div className='card'>
                            <div className='card-header'>All projects</div>
                            <div className='card-body'>
                                <Link className='btn btn-primary btn-sm mb-3' to='/create'>
                                    Create new project
                                </Link>
                                <ul className='list-group list-group-flush'>
                                    {projects.map(project => (
                                        <Link
                                            className='list-group-item list-group-item-action d-flex justify-content-between align-items-center'
                                            to={`/${project.id}`}
                                            key={project.id}>
                                            {project.name}
                                            <span className='badge badge-primary badge-pill'>{project.tasks_count}</span>
                                        </Link>
                                    ))}
                                </ul>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

export default ProjectsList
This is the basic structure for ReactJS with Laravel. Execute php artisan serve to start server.
Some sample screen shots:



Run command npm run dev (for windows user, run command as an administrator) to compile ReactJS code once you made some changes.

Below is GitHub link of this project:

https://github.com/pritomkucse/reactjs-with-laravel-6.X

After download source from GitHub run command composer install to install laravel dependencies, then run php artisan migrate for database migration (but make sure you configure database in .env file) and then run npm install to install ReactJS dependencies. Finally run npm run dev to package ReactJS and then browser your project directory. That's all.


Sample .env File
APP_NAME=Laravel
APP_ENV=local
APP_KEY=base64:PuBBf9PHnf4RkJokRNDMeTDY6SWWr8s2TilF9E3b4Fs=
APP_DEBUG=true
APP_URL=http://react-with-laravel.com
APP_PATH=/

LOG_CHANNEL=stack

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db-laravel1
DB_USERNAME=root
DB_PASSWORD=1234

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

Sample Virtual Host File

<VirtualHost react-with-laravel.com:80>
    DocumentRoot "C:\Users\PRITOM\Desktop\MINE\reactjs-with-laravel-6.X\public"
    ServerName react-with-laravel.com
    ErrorLog "logs/react-with-laravel.com-error.log"
    CustomLog "logs/react-with-laravel.com-access.log" combined
    <Directory "C:\Users\PRITOM\Desktop\MINE\reactjs-with-laravel-6.X">
        Options Indexes FollowSymLinks MultiViews
            AllowOverride All
            Order allow,deny
            allow from all
            Require all granted
    </Directory>
</VirtualHost>

Friday, March 1, 2019

How to install Laravel 5 with Xampp (Windows)

Requirements
  1. PHP >= 5.5.9
  2. OpenSSL PHP Extension
  3. PDO PHP Extension
  4. Mbstring PHP Extension
  5. Tokenizer PHP Extension
Install Xampp
First of all, we need Xampp, so we can download it from the official page: Download Xampp
Install Composer
After you've downloaded and installed Xampp, we need to install Composer.
Composer is a PHP package manager that is integrated with Laravel Framework. In Windows we can install it easy going to the official page and download the installer. Composer Download page

Install Laravel Framework
We are prepared to install and configure a Laravel Framework. First of all, we have to navigate to htdocs folder to install it and run this following command:
composer create-project laravel/laravel laravel "5.1.*"
When it finishes, it will create following directory schema:

Now browse your laravel project into browser:


Friday, February 8, 2019

Try catch not working Laravel raw queries | How to properly catch PHP exceptions (Laravel 5.X) | Why try catch not work in Laravel


Make sure you're using your namespaces properly. If you use a class without providing its namespace, PHP looks for the class in the current namespace. Exception class exists in global namespace, so if you do that try/catch in some namespaced code, e.g. your controller or model, you'll need to do catch(\Exception $e) to catch all your exceptions:  


try {
  //code causing exception to be thrown
}
catch(\Exception $e) {
  //exception handling
}


If you do it like this there is no way to miss any exceptions. Otherwise if you get an exception in a controller code that is stored in App\Http\Controllers, your catch will wait for App\Http\Controllers\Exception object to be thrown.

Laravel 5 Check if request is ajax request | Ajax request validation


<?php
use Illuminate\Support\Facades\Request;

return Request::ajax(); /* True | False */




Using custom monolog handlers in Laravel

You can easily add new handlers to Monolog


$manage_monolog = function(\Monolog\Logger $monolog) {
    #New monolog file name
    $filename = storage_path('logs'.DIRECTORY_SEPARATOR.'custom.log');
    $handler = new \Monolog\Handler\RotatingFileHandler($filename);

    #If you only keep this handler only
    $monolog->setHandlers(array($handler));

    #If you need to add this custom handler to existing handlers
    $monolog->pushHandler($handler);

    print_r($monolog->getHandlers());
};
$manage_monolog(\Illuminate\Support\Facades\Log::getMonolog());
\Illuminate\Support\Facades\Log::info("Its completed...");



How to pass data to all views in Laravel 5 | Sharing Data Between Views Using Laravel View Composers | Laravel 5.3 - Sharing $user variable in all views | Passing data to all views | View Composer to pass variable to all views | Passing $variables to multiple views

A view composer is exactly what you're looking for. A view composer allows you to tell your application do x when view y is rendered. For example when pages.buy is rendered anywhere in my application attach $articles.
The main thing is to create a service provider under "project/app/Providers" folder as below:
<?php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        view()->composer('*', function($view) {
            $view->with('isAdmin', true);
            $view->with('isSupervisor', false);
        });
        /* Make sure you have a view named "index.blade.ctp" in a folder
        named "customFolder" under "project/resources/views" folder.
         */
        view()->composer(array("customFolder.index"), function($view) {
            $view->with("xor", "XOR-1");
        });
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

Laravel :: Getting url() in a Command returns http://localhost | URL problem with queued jobs | Url helper functions that are relative to application url config | Localhost url problems

First need to configure project/config/app.php as below:
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/

'url' => 'http://localhost:81/my_project/'
Now need to edit project/app/Providers/AppServiceProvider.php as below:
namespace App\Providers;

use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\ServiceProvider;


class AppServiceProvider extends ServiceProvider
{
    private static $logStream;


    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        URL::forceRootUrl(Config::get('app.url'));
    }
}

Override setGlobalTo of Laravel Mailer| Laravel Message Sending listener | Laravel Mail Sending Listener | How to create Event for Mail sending in Laravel 5

We need to create event listener for "Illuminate\Mail\Events\MessageSending" event. So our listener file would be under "project/app/Listeners" as below.
<?php
namespace App\Listeners;

use Illuminate\Support\Facades\Log;
use Illuminate\Mail\Events\MessageSending;

class MessageSendingListener {
    public function __construct() {

    }

    public function handle(MessageSending $swiftMessage) {
        $server = env("MODE", "LIVE");
        if ($server != "LIVE") {
            $swiftMessage->message->setSubject($swiftMessage->message->getSubject() . " ($server)");
        }
        Log::info("SENDING EMAIL=".$swiftMessage->message->getSubject());
    }
}
The above file will be called before each mail be send. So we can modify or check anything as global option.
Now we require to register event on EventServiceProvider.php file so, open app/Providers/EventServiceProvider.php and copy this code and put in your file.
<?php

namespace App\Providers;

use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    /**
     * The event listener mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        'App\Events\SomeEvent' => [
            'App\Listeners\EventListener',
        ],
        'Illuminate\Mail\Events\MessageSending' => [
            'App\Listeners\MessageSendingListener',
        ],
    ];

    /**
     * Register any other events for your application.
     *
     * @param  \Illuminate\Contracts\Events\Dispatcher  $events
     * @return void
     */
    public function boot(DispatcherContract $events)
    {
        parent::boot($events);

        //
    }
}
This is all.

Laravel, get last insert id using Eloquent | laravel 5.2 get insert id from eloquent model | Get Last Inserted ID With Example

We have needed some it last inserted ID in Laravel application. so, here we have find 4 different way to get last inserted ID in Laravel. you can use it and get last ID of inserted record in Laravel application.
Using lastInsertId() method
DB::table('users')->insert([
    'name' => 'TestName'
]);
$id = DB::getPdo()->lastInsertId();
Using create() method
$data = User::create(['name'=>'first']);
$id = $data->id;
Using save() method
$data = new User;
$data->name = 'Test';
$data->save();
$id = $data->id;
Using insertGetId() method
$id = DB::table('users')->insertGetId([
    'name' => 'first'
]);

Friday, April 20, 2018

Extending from Laravel 5 core - SqlServerConnection | Extending The Connection Class In Laravel

The first thing the ConnectionFactory::createConnection() method does is to check if the db.connection.{$driver} alias is bound, and if so, it returns that connection object. If it is not bound, it returns the base connection object (Illuminate\Database\MySqlServerConnection for the mysql driver)
Therefore, all you need to do to use your own custom connection is to bind the db.connection.mysql alias to your custom MySqlServerConnection class
You can create a new service provider in which to do this, or you can just add the line to your existing AppServiceProvider
<?php
namespace App\Providers;

use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot(DispatcherContract $events)
    {
        parent::boot($events);
    }

    public function register() {
        $this->app->bind('db.connection.mysql', \App\Database\MySqlConnection::class);
    }
}
Remember that there may be two methods in any ServiceProvider, first call "register" method of each ServiceProvider listed and after that "boot" method called each ServiceProvider listed in "config/app.php" in providers section.
<?php
return [
    'providers' => [
        App\Providers\EventServiceProvider::class,
        App\Providers\AppServiceProvider::class
    ]
];
You have to create a MySQL connection class \App\Database\MySqlConnection
<?php
namespace App\Database;

use Illuminate\Database\MySqlConnection as ParentMySqlConnection;

class MySqlConnection extends ParentMySqlConnection {
    public function select($query, $bindings = [], $useReadPdo = true) {
        return parent::select($query, $bindings, $useReadPdo);
    }
}
So its completed, MySqlConnection is now extended with our own connection class.
So you can now anything do with your custom connection class.