Authentication

In previous example we already had access to database and user model which allow us to use user model globally as model to create user login. To create authentication in Slim, we have to create authentication controller, View and create a form where user can sign up with account and last we have to insert new user login record in our database.

1. Create user login View

Inside the resources/view create new folder called auth and add new file signup.twig

{%  extends 'templates/app.twig' %}

{% block content %}
 <div class="row">
 <div class="col-md-8 col-md-offset-2">
 <div class="card">
 <div class="card-header text-center">Sign up</div>
 <div class="card-body">
 <div class="card-text">
 <form action="{{ path_for('auth.signup') }}" method="post" 
                            autocomplete="off">
 <div class="form-group">
 <label for="email">Email</label>
 <input type="email" name="email" id="email" 
                                placeholder="your@domain.com" class="form-control">
 </div>
 <div class="form-group">
 <label for="name">Name</label>
 <input type="text" name="name" id="name" 
                                    class="form-control">
 </div>
 <div class="form-group">
 <label for="password">Password</label>
 <input type="password" name="password" id="password" 
                                    class="form-control">
 </div>
 <button type="submit" class="btn btn-default">Sign Up</button>
 </form>
 </div>
 </div>
 </div>
 </div>
 </div>
{% endblock %}

Step 2: Define User Model in app/Models/User.php 

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

Class User extends Model {
 protected $table = 'users';

 protected $fillable = [
 'email',
 'name',
 'password',
    ];

}
Step 3: Create authController
Inside the app/Controllers folder add new folder called Auth and add new file called AuthController.php. In AuthController.php we have two methods
1. getSignUp ( to render the view template auth/signup.twig file)
    This method is called when we sent get request to http://localhost/testSlim/public/auth/signup
2. postSignUp  (This is called when we submit the form)
    This method is called when we submit the login form, it will create new user and insert new user into our      database table user.

Add following code

<?php

namespace App\Controllers\Auth;

use App\Models\User;
use App\Controllers\Controller;

class AuthController extends Controller {

 public function getSignUp($req, $res){
 return $this->view->render($res, 'auth/signup.twig');
    }

 public function postSignUp($req, $res){
 // var_dump($res->getParams());
       $user = User::create([
 'name' => $req->getParam('email'),
 'email' => $req->getParam('name'),
 'password' => password_hash($req->getParam('password'), PASSWORD_DEFAULT), 
        ]);

 return $res->withRedirect($this->router->pathFor('home'));
    }
}
For the password we are using php password hashing API, first argument is data that we want to hash and second argument is algorithm we want to use.

Step 3: Define route for signup get and post methods, add following code in app/routes.php 

<?php

$app->get('/', 'HomeController:index')->setName('home');
$app->get('/auth/signup', 'AuthController:getSignUp')->setName('auth.signup');
$app->post('/auth/signup', 'AuthController:postSignUp');
We can attach name to route for controller, so we can used is as reference in our code of view and controller.

Step 4: Define AuthController in our bootstrap/app.php 

$container['AuthController'] = function($container) {
 return new \App\Controllers\Auth\AuthController($container);
};
Step 5: Insert new user account in our database table
    http://localhost/testSlim/public/auth/signup

Model – How Does Eloquent Work?

The Eloquent ORM provides an ActiveRecord implementation to work with your database. This means that each model you create in your MVC structure corresponds to a table in your database. Models are mostly used to interact with the database using Eloquent ORM.

Note that we did not tell Eloquent which table to use for our User model. The “snake case”, plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, Eloquent will assume the User model stores records in the users table.
Example A User model will correspond to a users table in your database. Since we have convention when creating our models and database tables, we can easily call data from our database.

For example, to get all Users from a User model, all you would do is User::all(). Using this function would query the database and generate the proper SQL command. Here are some quick examples:

Description                        Function
Find all Users                    User::all()
Find a record                     User::find(id)
Delete a record                 User::delete(id)

Step 1: First we have to create table name users, plural in our database and add required field.

Step 2: Defining Eloquent Model Class
Create a folder called Models inside app folder and inside the Models folder add new file called User.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

Class User extends Model {
    protected $table = 'users';

    protected $fillable = [
      'email',
      'name',
      'password',
    ];

}

Note that we did not tell Eloquent which table to use for our User model. The “snake case”, plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, Eloquent will assume the User model stores records in the users table. We can use Model name as directly connection to our database table.

Example A User model will correspond to a users table in your database. Since we have convention when creating our models and database tables, we can easily call data from our database.
In above code first we need to extend our user model with Model class and have to define what field to be specifically we want to write to database table through define table field name in $fillable.

Step 3: Access our our database action in controller through Model name
a. First we have to include our Model class name.
b. We can define a method to access database through model name and methods.

In example below we are inserting a new record our database table User.

<?php

namespace App\Controllers;

use App\Models\User;
use Slim\Views\Twig as View;

class HomeController extends Controller {

 public function index($req, $res){
 User::create([
 'name' => 'Test Allu',
 'email' => 'allutest@gmail.com',
 'password' => 1234,
        ]);
 
 return $this->view->render($res, 'home.twig');
    }
}
You could use several prebuilt Eloquent functions for this purpose.
Retrieving All Records
    $users = User::all();
Retrieving A Record By Primary Key
    $user = User::find(1);
    var_dump($user->name);
Querying Using Eloquent Models
$users = User::where(‘votes’, ‘>’, 100)->take(10)->get();
foreach ($users as $user){
    var_dump($user->name);
}
Eloquent Aggregates
Of course, you may also use the query builder aggregate functions.
$count = User::where(‘votes’, ‘>’, 100)->count();

Eloquent with Slim

We can use a database ORM such as Eloquent to connect your SlimPHP application to a database. We need to setup the databse and Model in best possible way. We are using Lavravel Eloquent ORM which provides a beautiful, simple ActiveRecord implementation for working with your database. We can use Eloquent outside of Lavravel and can easily use in our Slim project. Each database table has a corresponding “Model” which is used to interact with that table. Models allow you to query for data in your tables, as well as insert new records into the table.

Step 1: Define Database schema
Inside phpmyadmin create a database name slimDB and add new table called users. Add following field ID, Name, Email, Password, Created_at, update_at. Where ID is integer, auto increment and primary field. Define database as utf8_unicode_ci.

Step 2: Install illuminate/database
composer require illuminate/database

Step 3: Configure the databse
In bootstrap/app.php we have set up the database configuration and we need to a way to define eloquent within our Slim project.

<?php

session_start();

require __DIR__ . '/../vendor/autoload.php';
$app = new \Slim\App([ 
    'settings' => [
        'displayErrorDetails' => true,
        'db' => [
            'driver' => 'mysql',
            'host' => 'localhost',
            'database' => 'tamoslim1',
            'username' => 'root',
            'password' => 'tamo1959',
            'charset' => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix' => '',
        ]
        ],
]);
$container = $app->getContainer();
$capsule = new \Illuminate\Database\Capsule\Manager;
$capsule->addConnection($container['settings']['db']);
$capsule->setAsGlobal();
$capsule->bootEloquent();

$container['db'] = function ($container) use ($capsule) {
    return $capsule;
};
The capsule is way the Laravel let us to use it component outside of the Laravel. Now we can access our database . Now we need booted it globally, so we can use Model and we can access it via  through container within our controller.

Now test database or eloquent in our app/Controllers/homeController.php add this code.

<?php

namespace App\Controllers;

use Slim\Views\Twig as View;

class HomeController extends Controller {

    public function index($req, $res){
        $user = $this->db->table('users')->find(1);
        var_dump($user->email);
        die();

        return $this->view->render($res, 'home.twig');
    }
}

Bootstrap in Slim

In a Slim 3 application, we can use Twig template engine, to easily create a standard page template, or layout. We will create a few site pages (home, about, contact).

In this articles we will learn how to add bootstrap front end framework in slim and create a base layout app.twig that can be use by any/all of your application’s views to give all of your pages a consistent design and structure.

Step 1: Install twig template engine through composer
$ composer require slim/twig-view

Step 2: Add bootstrap css, javascript and jquery cdn in our base template
Create new folder template in resources/views/templates/app.twig and add new file called app.twig. This file is act as base layout. Here we have to include bootstrap css, bootstrap js and jquery in our base template view twig.

<html>
 <head>
 <meta charset="utf-8"/>
 <title>Slim 3</title>
 <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css
          /bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFc
          JlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
 <link rel="stylesheet" href="{{ base_url }}/css/app.css" >
 </head>
 <body>

    {% include 'templates/include/navigation.twig' %}
 
 <div class="container">
 
        {% block content %} {% endblock %}
 </div>

 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" 
        integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" 
        crossorigin="anonymous"></script>
 </body>
</html>

In app.twig we have to include navigation.twig for navigation. In above code we have
{% block content %} {% endblock %}

Where we define our content inside the block statement above. If any file or view want to use the above layout template have to define content for app.twig.

Step 3: Define include folder to create frequently used layout
Create new folder called include in templates add new file called navigation.twig and add code below for navigation.


<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
      <a class="navbar-brand" href="#">Navbar</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>

      <div class="collapse navbar-collapse" id="navbarsExampleDefault">
        <ul class="navbar-nav mr-auto">
          <li class="nav-item active">
            <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">Link</a>
          </li>
          <li class="nav-item">
            <a class="nav-link disabled" href="#">Disabled</a>
          </li>
        </ul>
        <form class="form-inline my-2 my-lg-0">
          <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
          <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
        </form>
      </div>
    </nav>

Step 4: We have to extend app.twig template and have to define block of content for our app.twig layout inside our resources/views/home.twig 

{% extends 'templates/app.twig' %}
{% block content %}
      Home
{% endblock %}

Step 5: Add style sheet to our application, inside the public folder add new folder called css and add app.css file 

body{
    padding-top:80px;
    padding-bottom: 40px;
}

 

Base Controller

We will define base Controller class , where we pass entire container to base Controller class that can be access by all sub class controller of Base Controller.

Step 1: Create a Base Controller
In app/Controllers/Controller.php we will create base controller name as Controller and add following code.

<?php
app/Controllers/Controller.php
namespace App\Controllers;

class Controller {

    protected $container;

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

Accessing property from this methods is not best practice but we can used it for rapid prototyping of our project.
    public function __get($property) {  
        if ( $this->container->{$property}){
            return $this->container->{$property};
        }
    }
}

In Base controller constructor we are passing the container, we are using __get($property) method to access container property in base class. We don’t have to define

Step 2: In bootstrap/app.php we will modified container->view to $container in HomeController as view is already attach container in app.php

$container['HomeController'] = function($container) {
    return new \App\Controllers\HomeController($container);
};

Step 3: Now in app/Controller/HomeController we can extend Base Controller and can access view through container from Base Controller
return $this->container->view->render($res, ‘home.twig’);

We can access view without container in HomeController, for that we have to define
public function __get($property) {}
method in base Controller, this will return any property that we want to access, in our case we can access view directly from homeController without container. Dumping the property argument will return error with view object.

<?php

namespace App\Controllers;

use Slim\Views\Twig as View;

class HomeController extends Controller {

    public function index($req, $res){
        return $this->view->render($res, 'home.twig');
    }
}

First Application

We will create our first slim application, where we will learn setting very simple slim application with popular template view called Twig.
Getting Set Up
Start by making a folder for your project called firstSlim. Inside our firstSlim project add following folder public, bootstrap in root folder. Add two file in public folder.

Inside the bootstrap/app.ph add the following code

<?php
session_start();
require __DIR__ . '/../vendor/autoload.php';

Where autoload.php will load all the dependencies of our slim applicaiton.

Inside the index.php add the following code to access

<?php
require __DIR__ . '/../bootstrap/app.php';

$app->run();

$app = new \Slim\App([ 
    'settings' => [
        'displayErrorDetails' => true,
        ],
]);
require __DIR__ . '/../app/routes.php';

Now we can access our public folder as http://localhost/testApp/public/

Step 2: Create routes
Slim doesn’t use any automatic mapping or URL formula so you can make any route pattern you like map onto any function you like, it’s very flexible. Routes can be linked to a particular HTTP verb (such as GET or POST), or more than one verb.
Create new folder app in root folder and add new file routes.php inside

app/routes.php.
$app->get('/', function($req, $res){
return 'Home';
});

We have to add httaccess file, .htaccess is short for Hypertext Access is a configuration file for use on web servers running the Apache Web Server software. With .httaccess now we can access
localhost/testApp/public/home

Step 2: Installing Twig template
The Slim Framework view helper built on top of the Twig templating component. You can use this component to create and render templates in your Slim Framework application.
composer require slim/twig-view

Our resources folder add new folder called views, where we can store all about views. Inside resources/views/home.twig add code
Home Twig

In bootstrap/app.php add the following code to add view dependency to container to the

$container['view'] = function ($container) {
    $view = new \Slim\Views\Twig( __DIR__ . '/../resources/views', [
        'cache' => false,
    ]);

    $view->addExtension(new \Slim\Views\TwigExtension(
        $container->router,
        $container->request->getUri()
    ));

    return $view;
};

In above code we have first attach our view template to container and we are also creating new slim instance we have to define path where our view are kept. For the production we may keep our cache in different folder.
We can also add optional addExtension to define routes, we need router because we are using link inside our view and we also have to get current uri through request which is the current request of the page.

In app/routes.php we have to add following code to access view page home.twig

<?php
$app->get('/home', function($req, $res ){
return $this->view->render($res, 'home.twig');
});

Slim

What is SLIM Framework?
PHP micro framework that helps PHP developers quickly and easily write web applications and APIs. Think of it as a core set of tools with which a developer can build amazing things.”

Called micro framework because Slim framework which focus on the basic needs required of a web application such as: received a HTTP request, send request to appropriate code, and restore HTTP responses.

How to install SLIM Framework?
Before readers install SLIM framework it would be nice readers adjust a PHP
version used. There are two requirements which readers must fullfill.
1. We need a web server like Nginx or Apache.
3. Slim 3 support PHP Version 5.5 or latest

For installing Slim we need to install web server, here we have using xampp for Apache server and also we have to install composer.

1. Manually installing the slim framework
2. Installing Slim from slim skeleton.
Step 1: Create slim project

$ cd xampp\htdocs
$ mkdir firstSlim
$ cd firstSlim

# install slim via composer
$ composer require slim/slim "^3.0"

The above command will create a composer.json file in your project root:

Step 2: Create new filw index.php add required dependencies.
Now just create index.php file containing:

<?php
require 'vendor/autoload.php';

$app = new Slim\App();
$app->get('/hello', function ($request, $response, $args) {
    $response->write("Hello World");
    return $response;
});
$app->run();

Now goto browser and hit testSlim url like http://localhost:8080/firstSlim you will see hello World. That’s it.

composer require slim/twig-view

To test the working of slim add following code in index.php for test. In root folder create create src/public, add two file index.php and .httaccess. In index.php add the following code

<?php
require 'vendor/autoload.php';

$app = new Slim\App();
$app->get('/hello/{name}', function ($request, $response, $args) {
    $response->write("Hello, " . $args['name']);
    return $response;
});
$app->run();

In .httaccess add following code

RewriteEngine On
RewriteCond %{Request_Filename} !-F
RewriteCond %{Request_Filename} !-d
RewriteRule ^ index.php [QSA,L]

To make your life easier, you should create a .htaccess file that defines a clean URL structure. In the public directory, make a .htaccess file and add the following code in it. This will provide a clean URL structure for the PHP file. (this just means that you don’t have to include PHP filenames in the URL calls). If the index file is located in a different folder (for instance, the public folder) and the .htaccess file is on the root, you can insert the full path of the index file in the last line:
RewriteRule ^ public/index.php [QSA,L]

we can access by
php -S localhost:8000 or
http://localhost/testSlim/public/

Upgrade slim 3.0 to 3.5: first change composer.json and run
composer update

Slim Framework

Installing slim through composer:
1. composer require slim/slim “^3.0”
2. composer require slim/twig-view
3.

Blog to learn Slim:
https://github.com/xssc/awesome-slim

https://www.codecourse.com/lessons?subject=slim

https://arjunphp.com/category/php-mysql/slim-framework/

How to Use Eloquent in Slim Framework

https://steemit.com/utopian-io/@alfarisi94/how-to-use-twig-templating-in-slim


https://glenneggleton.com/page/slim-3-tutorial

How to Create a Simple REST API With Slim Framework

https://www.cloudways.com/blog/twig-templates-in-slim/

Slim 2 : Customer Orders Web App structure – http://www.kode-blog.com/slim-framework-twig-template-tutorial

Slim composer:
composer require slim/twig-view

Slime Skeleton : https://github.com/aurmil/slim3-skeleton/blob/master/composer.json

http://www.kode-blog.com/rahaslim-slim-controller