Building A Simple Product Management App Using Angular JS + Cygnite PHP + Bootstrap


Introduction:

My previous article was “How to install custom theme in Magento”. Recently AngularJS occupied the market space and become one of the most demanded frontend framework. Building application using core javascript is really painful and you may not like the development because you need to write bunch of code or building everything from scratch. Modern applications need likes compact solution with some flavour of objects, this is where Angular JS takes place. It does fulfill all your basic needs. RESTful routing, dependency injection service make you to love developing web application. But in order to build full featured web application you also need a powerful backend framework to do some of the job with ease.

In this tutorial I will show you how you can make use of Angular routing to build single page application without refreshing page. I will make use of Cygnite PHP Framework, as it is easy, powerful and does awesome job handling your backend.

Getting Started:

Very first thing we need to do is install Cygnite. I will not explain installation briefly, as it is described well in Cygnite'sbeautiful documentation.

Installation:

After downloading cygnite package from github repo, unzip and rename the folder to "cygnite". Now open your browser and navigate to http://localhost/cygnite/. You will see Cygnite’s welcome page as below.

  Live Demo   Download

After downloading the skeleton package from GITHUB, we need to install Cygnite core packages in order to make the application work. Please ensure you have composer installed already into your machine, and issue below command from your project root directory to install framework into your system.


  composer install


Database Configurations:

Before getting started with migrations you need to configure database connections into /apps/configs/database.php file. If you open the file you can see sample database connection provided. You may change accordingly. You can see we are making use of “cygnite” database, you may create same database, follow the steps or use different database and make changes accordingly.


  'db' => array(
            'driver' => 'mysql',
            'host' => 'localhost',
            'port' => '',
            'database' => 'cygnite',
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8'
         )

Once you configure database connection, you are ready for running migrations.

You may be also interested to read Facebook Style Autocomplete Using AngularJS + Cygnite PHP Framework + MySQL

Migrations & Seeding:

If you open /apps/database/migrations/ folder you can see some files with number prefixed (xxxx_product.php etc.). These are the migration files we will run. Open your terminal, if you are using windows obviously command prompt and execute below command from your installation directory to create schema file and run migrations.

Before running migration please make sure you are running migrations.sql query into your database which is available into apps/database/migrations.sql.



 cd console/bin 

 php cygnite migrate


Before running above command make sure you are changing the database connection name into the migration file (apps/database/migrations/xxxx_user.php). Then run the command you will see new table “user” created into your database with sample data. To check you may manually open phpmyadmin and find table over there. This is the table by which we will authenticate users.

RESTful Routing:

We will display some basic layout page where angular templates will render. Want to display multiple theme based on the page ? Cygnite layout just made it simple. You can see if you just enter the base url it will display different page and different page when uri match with routing uri "angular". Simply define layout in your controller and it will make use of the theme you wish. You can controllers using routing and also directly via uri. In the apps/ directory you will also find "routes.php" file where we can define routing for our application. Open the file and add below routing to the file in order to display our login page by default.



 $app->router->get('/', function ($router)
 {
   echo Widget::make('home:index'); // apps/views/home/index.view.php
 });


It will display the basic page from where you will find login link, click on that and login page will appear. You can login into the application using your credentials.

Default credentials are below:



Email: admin@cygnite.com

Password: admin@123


You can make use of Migrations files to seed some sample users to authenticate.

Controllers:

You will find AuthController available into your apps/controllers/ directory. This controller used to authenticate users. You can find checkAction and logoutAction. You don't need write authentication code as AuthController shipped with Cygnite skeleton project. Auth Controller looks like below.


namespace Apps\Controllers;

use Cygnite\Common\Encrypt;
use Cygnite\Common\Input\Input;
use Cygnite\Foundation\Application as App;
use Cygnite\Mvc\Controller\AbstractBaseController;
use Application\Components\Authentication\Auth;

/**
* This file is generated by Cygnite CLI
* You may alter code to fit your needs
*/

class AuthController extends AbstractBaseController
{
    //protected $layout = 'layout.base';

    protected $templateEngine = false;

    private $auth;

    /**
    * Your constructor.
    * @access public
    *
    */
    public function __construct()
    {
        parent::__construct();
        $this->auth = Auth::model('\Apps\Models\User');
    }


   /**
    * Default Action
    */
    public function indexAction()
    {
    }

    /**
    * Authenticate user and login into the system
    *
    */
    public function checkAction()
    {
        $input = Input::make();
        $post = $input->json();

        $crypt = new Encrypt();
        $credentials = array(
            'email' => $post->email,
            'password' => $crypt->encode($post->password)
        );

        if ($this->auth->verify($credentials)) {
            $this->auth->login();
            $userInfo = $this->auth->userInfo();
            echo json_encode(array('success' => true, 'flash' => 'Logged In Successfully!!', 'name' => $userInfo['username']));
        } else {
            echo json_encode(array('success' => false, 'flash' => 'Invalid username or password', 'name' => ''));
        }
    }

    /**
    * Display specific information into the form to edit.
    *
    */
    public function logoutAction()
    {
        $this->auth->logout(false);

        echo json_encode(array('success' => true, 'flash' => 'Successfully Logged Out!'));
    }
}//End of your LoginController



Models:

Cygnite model classes are interacting with database. You can find the model user available in apps/models/User.php so you may not need to create it. You can also create a new model manually into apps/models/User.php and change database name.

Feeling lazy? Yes. No worry! Cygnite makes your job simple, you can simply issue below command to generate model for you.



php cygnite model:create user cygnite


Above command “cygnite” represent your database name and “user” your model name.

Index View Page:

You can simply open /apps/views/user/index.view.php file, which is the landing page of our application. This single view page render all angular templates into it. In this page you will also find ng-app="MyTutorialApp" in the tag, “ng-init” and “ng-view” directives of angular js framework. You may get more informations about those in angular documentation.

In your view page you must have below tag with angular module name, baseurl, and ng-view. Apart from that you also required to include angular.min.js script, app.js, and bootstrap css etc. You can find the view in apps/views/home/index.view.php file.



  <html lang="en" ng-app="MyTutorialApp">
 <head>
<link rel="stylesheet" type="text/css" title= '' href="/mycygnite/assets/css/bootstrap/css/bootstrap.min.css" >
    <link rel="stylesheet" type="text/css" title= '' href="/mycygnite/assets/css/bootstrap/css/bootstrap-theme.min.css" >
 </head>

 ..............


 <base href="{{baseUrl}}" ng-init="baseUrl = '<?php echo Url::getBase(); ?>'" />


 <div id="view" ng-view></div>

 <!-- load angular and angular route via CDN -->
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
 <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
 <script type="text/javascript" src="/mycygnite/assets/js/angular/app.js"></script>


Our all angular templates will render into “ng-view” directive.

Angular Templates:

If you open assets/ folder you will find another folder called templates/ where all your templates located. Each template called via angular routing. I will not display template html code here as you can find easily there.

Angular Module Script:

If you open /assets/js/angular/ you will find app.js which is has all necessary code for angular to work with Cygnite to authenticate users. For this tutorial we are making use of Angular routing, Factory Service, Controllers etc. So end of this tutorial you will be able to understand how Angular routing, Authentication Service, Controllers works.

Below code to define and getting the app object. We are also using ngRoute as dependency below.



  var app = angular.module('MyTutorialApp',  ['ngRoute']);


and in the next line we are configuring routes to repond to our url.



 app.config(function($routeProvider) {
    //………………
 });



And next AuthenticationService factory to authenticate user against database.



 app.factory("AuthenticationService", function($http, UrlService) {
     //…………………

 });


This factory helps us to authenticate and login user, checking if user logged in, logout and get username from session.

Apart from that we have LoginController, LogoutController, HomeController to perform needed openration.

Below entire code for our angular authentication app.


var app = angular.module('MyTutorialApp',  ['ngRoute']);

/**
 * Configure routing for application
 */
app.config(function($routeProvider) {

    $routeProvider
        // route for the login page
        .when('/login', {
            templateUrl : 'assets/templates/login.html',
            controller  : 'LoginController'
        })

        // route for the home page
        .when('/home', {
            templateUrl : 'assets/templates/home.phtml',
            controller  : 'HomeController'
        })

        // route for the contact page
        .when('/logout', {
            templateUrl : 'assets/templates/logout.html',
            controller  : 'LogoutController'
        });
});

/**
 * Url Service manager
 */
app.factory("UrlService", function($rootScope) {
    return {
        set: function(url) {
            $rootScope.baseUrl = url;
        },
        get: function() {
            return $rootScope.baseUrl;
        }
    }
});

/**
 * Authentication Service handler
 */
app.factory("AuthenticationService", function($http, UrlService) {

    var cacheSession = function () {
        sessionStorage.setItem('authenticated', true);
    };

    return {
        login: function(credentials, url) {
            UrlService.set(url);

            var input = {'email': credentials.email, 'password': credentials.password};
            var login = $http.post(UrlService.get()+"auth/check", JSON.stringify(input));

            login.success(function (data) {
                sessionStorage.setItem('authenticated', true);
                sessionStorage.setItem('username', data.name);
            });

            return login;
        },
        logout: function() {
            var logout = $http.get(UrlService.get() +"auth/logout");

            logout.success(function () {
                return sessionStorage.removeItem('authenticated');
            });

            return logout;
        },
        isLoggedIn: function() {
            return sessionStorage.getItem('authenticated');
        },
        getUser: function() {
            return sessionStorage.getItem('username');
        }
    };

});

/**
 * Handle Login request. Authenticate user against database
 * and login into application
 */
app.controller("LoginController", function($scope, $location, AuthenticationService) {

    $scope.credentials = { email: "", password: "" };

    if (AuthenticationService.isLoggedIn()) {
        $location.path('/home');
    }

    $scope.login = function() {

        AuthenticationService.login($scope.credentials, $scope.baseUrl).success(function(response, status, headers, config) {

            //console.log(response);
            if (response.success == true) {
                $location.path('/home');

            } else {
                alert(response.flash);
                return false;
            }
        }).error(function(response, status, headers, config) {
            alert("Login error: " + status + response);
            return false;
        });
    };


});

/**
 * Logout from current session
 */
app.controller("LogoutController", function($scope, $location, AuthenticationService) {

    $scope.logout = function () {

        AuthenticationService.logout().success(function(response) {

            //console.log(response);
            if (response.success == true) {
                alert(response.flash);
                $location.path('/login');

            }
        }).error(function(response, status) {
                alert("Login error: " + status + response);
                return false;
            });
    };
});

app.controller("HomeController", function($scope, $location, AuthenticationService) {

    $scope.username = '';
    if (!AuthenticationService.isLoggedIn()) {
        $location.path('/login');
        return false;
    }
    $scope.content = true;
    $scope.username = AuthenticationService.getUser();
    $scope.title = "Hello Developer!!";
    $scope.cygnite = "Cygnite PHP Framework";
    $scope.angular = "Angular JS";

});


If you have a look at the code you can see all templates getting included only if there is a matching uri, angular routing made it just simple. AuthenticationService use to validate user against database using Ajax request, and display error if user credential doesn't match with database or if success redirect user to home page.

Conclusion:

That’s all we are done with the “Angular + Cygnite PHP + Bootstrap“ tutorial part1. You can see the entire application works without refreshing the page. That is how most of the modern application works. In the part 2 tutorial I will show you “How to Manage Products (CRUD) using Angular JS + Cygnite PHP Framework + Bootstrap”.

Hope you enjoyed the article and helpful to you to understand how Angular and Cygnite PHP Framework does awesome job together to build interactive applications. You may feel free to add more features to your application. In case if you don’t find more information about Cygnite PHP Framework or Angular JS you are looking for, take a look at Cygnite Framework and Angular JS documentation .

Got some idea? Send some love back. Please feel free to like, share or tweet. You will find more in coming days. Keep visiting.

Good Day!

Follow Us On Facebook Open Source Web Developers by Appsntech facebook group Twitter Open Source Web Developers by Appsntech twitter group Google+ Open Source Web Developers by Appsntech Google group Linkedin Open Source Web Developers by Appsntech, LinkedIn group
Copyright @2011-2015 appsntech.com. All rights reserved. Powered By- Sanjoy Dey Productions