You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The command above will generate a file in ```application/migrations``` directory
which will have a filename like ```2012_11_25_004329_create_table_users.php``` composed of the timestamp in which the file was generated plus the actual name of the migration. If you open it up it will look something like this:
```
```php
<?php
class Create_Users_Table {
@@ -320,7 +320,7 @@ since the process is basically the same.
The migration file for adding foreign keys to the users table will look like this
on the first time you open it.
```
```php
<?php
class Add_Foreignkeys_To_Users_Table {
@@ -350,7 +350,7 @@ class Add_Foreignkeys_To_Users_Table {
Add these code to the ```up()``` method. This adds a foreign key and index to the ```department_id``` and ```role_id``` fields.
@@ -621,7 +621,7 @@ Back to the ```action_``` thingy. If you want a method to render a specific view
For example if you want the index or the ```public/login``` page to accessible in the browser then you should name it like the following.
```
```php
class Login_Controller extends Base_Controller{
public function action_index(){
@@ -632,15 +632,15 @@ class Login_Controller extends Base_Controller{
If your method isn't gonna render a view and its just going to perform some computations or database related stuff in your controller then just make it into a private method.
```
```php
private function compute_stuff(){
}
```
Then you can just access it in your controller like.
```
```php
public function action_index(){
$this->compute_stuff();
}
@@ -650,7 +650,7 @@ Then you can just access it in your controller like.
Going back to restful controllers, laravel generator usually generates something like this if you haven't specified some of the methods.
```
```php
<?php
class Login_Controller extends Base_Controller {
@@ -667,7 +667,7 @@ php artisan generate:controller login index restful
If you have executed the command above then your controller will look like this.
```
```php
<?php
class Login_Controller extends Base_Controller {
@@ -705,7 +705,7 @@ In this case were just rendering the login view that we created earlier.
Create another method called ```post_index``` this will be executed everytime the login form is submitted.
```
```php
public function post_index(){
}
@@ -753,7 +753,7 @@ If the validation failed all we have to do is to redirect to the login page
passing in the validation instance using the ```with_errors()``` method.
This can then be accessed from the error view that we created earlier.
If the validation suceeded then we will try to login the user.
We can do that by using the ```attempt()``` method from the ```Auth``` class in Laravel.
```
```php
if(Auth::attempt($user_details)){ //attempt to login the user
if(Auth::check()){ //check if the user is already logged in
$user_id = Auth::user()->user_id;
@@ -810,7 +810,7 @@ First let's create the main template to be used on all pages.
It's basically the same with the public template that we created earlier
the only difference is the navigation section.
```
```html
<!DOCTYPE html>
<htmllang="en">
<head>
@@ -880,7 +880,7 @@ On the other hand ```@foreach``` is just like the ```foreach``` that were using
Of course all the data that we are iterating through aren't directly available in the view, we will have to pass the data to the view using the controller which will render this view. And that's what were going to do next.
Define the default data that will be used throughout the controller.
```
```php
private $departments;
private $it_roles;
private $marketing_roles;
@@ -1012,7 +1012,7 @@ for caching things or saving things temporarily to a location were access is fas
This is commonly used for caching data from the database so the application won't have to hit the database
everytime a particular page is accessed by a user.
```
```php
public function __construct(){
parent::__construct();
@@ -1072,7 +1072,7 @@ public function get_new_user(){
Now let's write the code for saving the new user into the database.
```
```php
public function post_new_user(){
//get user details
@@ -1165,7 +1165,7 @@ It's a very simple function which checks if a cache item exists.
If it exists we store it in a variable ```$current_data``` . Then we add the new data to the current data using ```array_push()```.
Finally we put back the new one into the cache.
```
```php
function add_cache_item($key, $data){
if(Cache::has($key)){ //check if item exists in the cache
$current_data = Cache::get($key); //store it to a variable
@@ -1180,7 +1180,7 @@ function add_cache_item($key, $data){
We've also used another helper function which is ```log_action()``` which is simply used to log what
every user is doing into the database.
```
```php
function log_action($transaction){
$user_id = Session::get('current_user_id');
$user = Session::get('current_user');
@@ -1213,7 +1213,7 @@ Create a new view called ```create_role``` where we will put the form for creati
This will have two fields: department and role.
The idea here is that for every department there are 1 or more roles that can be added.
```
```php
@layout('main')
@section('content')
@@ -1277,7 +1277,7 @@ Just like for every form if there's a ```get``` there's also a ```post``` as I h
methods with a prefix of ```get``` are used for rendering views while ```post``` are used
for processing forms that are submitted.
```
```php
public function post_new_role(){
//get the data inputted by the user
@@ -1343,7 +1343,7 @@ update user details. The administrator can also update the status of the user fr
The status can either be ```enabled``` or ```disabled``` if the user is disabled then he cannot login to the application. Lastly, we'll also include a link to the user activity log so that the administrator can view
all the transactions that the user has performed in the application.
```
```html
@layout('main')
@section('content')
@@ -1494,7 +1494,7 @@ public function get_users(){
Create another view for updating the user.
This is very similar to the view for creating users.
```
```html
@layout('main')
@section('content')
@@ -1596,7 +1596,7 @@ This is very similar to the view for creating users.
Create another method in the ```admin``` controller that will render the user update form.
```
```php
public function get_user($user_id){
$user = $this->_get_userdata($user_id);
@@ -1632,7 +1632,7 @@ private function _get_userdata($user_id){
Then the code for updating the user details.
```
```php
public function post_user($user_id){
$firstname = Input::get('firstname');
$middlename = Input::get('middlename');
@@ -1704,7 +1704,7 @@ public function post_user($user_id){
Create another view and call it ```userlogs```. Nothing fancy here, this will just list out all the activities/transactions performed by a specific user or all users on the current day.
```
```html
@layout('main')
@section('content')
@@ -1746,7 +1746,7 @@ from the ```DB``` class.
If there's a user id supplied then its only going to select the logs for a specific user which has that id.
If there's no user id then its going to select all the transactions performed by every user on that day.
```
```php
public function get_logs($user_id = ''){
$scope = '';
if(!empty($user_id)){
@@ -1789,7 +1789,7 @@ The admin will just have to select the role that he wants to update.
After that he'll just click on the ```view``` button to load the transactions for that role.
Then he'll just have to deselect the transactions that cannot be performed by the role and select all the transactions that can be performed by the role. Were using ```ajax``` to submit the status of the transaction to the server-side that's why we don't have something like a submit button to commit the changes.
```
```html
@layout('main')
@section('content')
@@ -1907,7 +1907,7 @@ we have specified earlier in the ```transactions``` view
where the ```roletransaction_id``` and ```status``` is submitted.
As you can see were just accessing those submitted values through the parameters which represents the third and fourth segment of the route.
```
```php
public function post_update_transactionstatus($roletransaction_id, $status){
DB::table('roletransactions')
->where('id', '=', $roletransaction_id)
@@ -1948,7 +1948,7 @@ Here were just attaching data that is fetched from the database.
Go ahead and open up ```routes.php``` inside the ```application``` directory and add the following code:
```
```php
View::composer(
//specify the views where the data will be attached
array(
@@ -2007,7 +2007,7 @@ We have a variable called navigation ```{{ $navigation }}``` and that variable i
It might not click right away but that's how view nesting works.
```
```html
<ulclass="left">
<liclass="divider"></li>
@foreach($navigation as $key => $nav)
@@ -2029,7 +2029,7 @@ It might not click right away but that's how view nesting works.
Going back to the ```routes.php``` file. Create a filter and call it ```check_roles``` we will use this filter to check if the current user has the authority/privilege to access the page that he is trying to access.
```
```php
Route::filter('check_roles', function()
{
$current_url = URI::current(); //get current url excluding the domain.
@@ -2092,7 +2092,7 @@ Route::Controller(Controller::detect()); //create a route for every controller s
Finally, the logout. Were just going to call two methods then redirect to the login page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
There's no shortage of good resources for learning laravel.
So instead of the usual introductory tutorial were just gonna learn Laravel by building
a project from scratch and that's gonna be a User Management System.
I don't know if my definition of a User Management System is correct
but here's my idea of what's it's capable of doing:
- Register Roles
- Register Users
- Update Users
- Disable Users
- Update Transactions which can be performed by each role
- Login Users
- Limit Transactions that can be performed by each role
Yup! that's a lot so you might want to go ahead and grab some coffee and some snacks
before we start.
The version of Laravel that were gonna use is Laravel v3.2.1 so if you're reading this and version 4 is already out then you might want to use that version instead. There maybe some parts which won't work because of changes in the syntax
but the Laravel Documentation is always updated so you might want to check it out if some of the code below won't work
as you expected.
If you haven't downloaded Laravel yet now is the time to do so. Just go to [Laravel.com](http://laravel.com/) and click the big download button.
###Project Setup
After extracting the laravel zip file the root of your project should now look like this:
To make your life easier you might want to use [Laravel Generator](https://github.com/JeffreyWay/Laravel-Generator) by Jeffrey Way.
It's use to generate views, models, controllers, assets, tests and migrations easier.
Just grab the ```generate.php``` file from the github page I linked to earlier.
Then paste it to the ```application\tasks``` folder.
###Configuration
For every framework there's always something you need to configure and
for that you need to go to ```application/config``` directory and
open up the ```application.php``` file. Remove the default value for the key or if you want
just type in some 32 characters of random gibberish. The key is used for encryption and cookie stuff. Based on my understanding its like the salt for a password used to make it more difficult for a hacker to crack it.
```php
'key' => ''
```
If you don't want to type the key by hand there's the ```artisan``` tool to the rescue, just execute the following command
while you're in your projects root directory to generate the random gibberish for you.
```
php artisan key:generate
```
Next thing you need to configure is the ```profiler```. Just set it to true.
This will give you an idea how long it took the page to execute, or how many queries
were executed, what queries were executed.
```
profiler' => true
```
Next open up the ```database.php``` file. Make sure that the default is set to mysql:
```
'default' => 'mysql'
```
Then enter your database information:
```
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'rpt',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'prefix' => '',
)
```
Next open up the ```session.php``` file. Set the driver to file.
```
'driver' => 'file'
```
The driver is the means of storing a session. You can also use cookies, database, memcached, apc or redis.
Set the ```lifetime``` of the session to whatever feels right.
Since were building a user management system you want to keep it to a minimum.
This means that the session will automatically be destroyed after 15 minutes of being idle.
```
'lifetime' => 15
```
You may also want to set ```expire_on_close``` to ```true``` for extra security.
```
'expire_on_close' => true
```
Next open up the ```auth.php``` file. Were doing this configuration in advance since we haven't created the users table yet.
Go ahead and read up the text in the database section to create the users table then go back to this one.
Otherwise just continue with this and change the field names in the users table later on.
The ```auth.php``` file stores the configuration for the default user authentication functionality that is available on laravel.
Change the values for ```driver``` , ```username``` , ```password``` and ```model```.
```
'driver' => 'eloquent',
'username' => 'username',
'password' => 'hashed_password',
'model' => 'User',
```
The driver can either be ```fluent``` or ```eloquent``` but were using ```eloquent``` to have a flexibility in naming the primary key. Since the default name for primary key field is ```id``` and if we have something like ```user_id``` as a field name
then it won't work. The values for ```username``` and ```password``` are the field names of your username and password fields in your users table. The model is the name of the model for the ```users``` table.
###Database
It's good practice to use migrations to track the changes in the database.
Database migrations is like a version control for databases.
In order to use database migrations you first have to create the table that will be used
by laravel to track the migrations that are created. To do that execute the following command:
```
php artisan migrate:install
```
The command will create a ```laravel_migrations``` table in your database.
Once that's done create the migration file that will create the users table.
The syntax for generating migrations would be:
- what the migration does (Eg. create, update, delete)
- what's the name of the table or field (Eg. users, username, roles)
- what will be generated (Eg. table, field)
**Users Table**
```
php artisan migrate:make create_users_table
```
The command above will generate a file in ```application/migrations``` directory
which will have a filename like ```2012_11_25_004329_create_table_users.php``` composed of the timestamp in which the file was generated plus the actual name of the migration. If you open it up it will look something like this:
```
<?php
class Create_Users_Table {
public function up(){
}
public function down(){
}
}
?>
```
The ```up()``` method contains what you want to do to the database when you execute the migration.
It will normally contain an array of fields to be created and some default values to be inserted on the table.
The ```down()``` method will contain what you want to do when you rollback the migration.
Open up the migration file for creating the users table.
```
Schema::create('create', function($table) {
$table->increments('id');
$table->string('firstname', 200);
$table->string('middlename', 200);
$table->string('lastname', 200);
$table->integer('department_id');
$table->string('role_id');
$table->string('username', 200);
$table->text('hashed_password');
$table->integer('status');
});
```
You can also insert some default data on the table if you want:
```
DB::table('users')->insert(
array(
'firstname' => 'Hibari',
'middlename' => 'Neo',
'lastname' => 'Kyoya',
'department_id' => 1,
'role_id' => 1
'username' => 'hkyoya',
'hashed_password' => Hash:make('somepassword')
'status' => 1
)
);
```
By now you should have grok database migrations. Let's move on to the next level by generating migrations using the Laravel generator tool.
If you open up the files that were generated you will see that there's a method called ```timestamps()```.
This creates two additional fields: created_at and updated_at.
In most cases you don't need those, you can go ahead and remove those for each migration file.
```
$table->timestamps();
```
Next, execute the migration to create the tables in the database:
```
php artisan migrate
```
Executing the above command will create the following tables in your database:
-**users** - stores user login information
-**departments** - stores departments, offices or sections
-**roles** - stores the roles or user groups for each department. (Eg. collector in the treasury department)
-**rolestransactions** - stores the status of the transactions that can be performed by each role
-**transactions** - stores all the transactions that can be performed in the application
If for some reason you have made a mistake, you can execute ```php artisan migrate:rollback``` to drop the table.
Once that's executed you can go ahead and make the necessary changes on the migration file then execute ```php artisan migrate``` again to commit the changes to the database.
Once the tables are added into the database let's add the relationships between those tables.
This time we will just use the default functionality for creating migrations in laravel and not the laravel generator.
Based on the documentation of laravel generator I think there's still no way of specifying the relationships for each table.
But we don't know maybe by the time you're reading this Jeffrey Way has already added that functionality so you might want to use it if its already available to save some time.
Execute the following commands to generate migrations for adding relationships for each table:
Generate the template for the public view using the following command.
```
php artisan generate:view public
```
This will generate a file called ```public.blade.php```.
By default the laravel generator automatically uses ```.blade``` as a file extension so that you can use whatever syntactic sugar it offers (no ugly php opening and closing tags, sweet!).
This is like the ```header.php``` that most of us are familiar with when we first started with PHP
in which we include all the common elements to be used on all pages like system-wide scripts, styling and header.
@yield('content') //yields a particular section defined from a page
{{ URL::to_asset('img/umslogo.png') }} //includes the application logo
{{ Asset::styles() }} //includes the stylesheets that we have added earlier on the base controller
{{ Asset::scripts() }} //includes the scripts that we have added earlier on the base controller
```
The only thing to remember when you're using these methods is that their root is the public directory of your project.
####Login View
Next is the login page. The login page will inherit from the public template that we have just created.
The magic keyword for inheriting what's on a specific template is ```@layout('name_of_the_template')```.
Another magic keyword that we have used below is ```@section``` which basically lets you define a section that you want to be rendered in the template. That's what the ```@yield('content')``` in the template is used for, to render the specific section that you have defined in a specific page.
We also have ```@render('errors')``` so this means that we can also render sections inside a section in laravel (How cool is that?).
I haven't told you about how are Laravel controllers by default so before you wrap your mind
about restful controllers I'll talk a little about default controllers.
By default controllers in Laravel has a prefix of ```action_``` which indicates that they are used to render a specific view and pass data into it.
```php
class Login_Controller extends Base_Controller{
}
```
Laravel controllers normally extend the ```base controller``` in which we specified the projects assets earlier. The naming convention would be ```Name_of_the_controller``` + ```_Controller```. Where the name of the controller normally starts with a capital letter. The filename should be the same with name of the controller.
Back to the ```action_``` thingy. If you want a method to render a specific view then it should be a public method with the prefix of ```action_```.
For example if you want the index or the ```public/login``` page to accessible in the browser then you should name it like the following.
```
class Login_Controller extends Base_Controller{
public function action_index(){
return View::make('login'); //renders the login.blade.php located in the root of the view folder
}
}
```
If your method isn't gonna render a view and its just going to perform some computations or database related stuff in your controller then just make it into a private method.
```
private function compute_stuff(){
}
```
Then you can just access it in your controller like.
```
public function action_index(){
$this->compute_stuff();
}
```
####Restful Controllers
Going back to restful controllers, laravel generator usually generates something like this if you haven't specified some of the methods.
```
<?php
class Login_Controller extends Base_Controller {
public $restful = true;
?>
```
To specify some methods, just add the method name right after the name of the controller.
In this case the name of the controller is ```login``` and the method name is ```index```.
```
php artisan generate:controller login index restful
```
If you have executed the command above then your controller will look like this.
```
<?php
class Login_Controller extends Base_Controller {
public $restful = true;
public function get_index()
{
}
?>
```
Restful methods generally has these prefix:
-**get** - when requesting a specific page (Eg. login/index)
-**post** - when submitting data through a form
-**put** - when updating data
-**delete** - when deleting data
Only the first two can materialize (sorry couldn't think of a better word, peace grammar natzis) on a browser. But the idea is that methods which are used to render a specific view will have ```get_``` as its prefix.
And methods which processes or validates a form will have ```post_``` as its prefix.
###Login Controller
Ok back with the controller. For the index just like with any other PHP framework that you might have used before, the index method is the default method for a controller.
This means that you don't have to type in ```login/index``` to access what the index method has to return.
In this case were just rendering the login view that we created earlier.
```
public function get_index(){
return View::make('login');
}
```
Create another method called ```post_index``` this will be executed everytime the login form is submitted.
```
public function post_index(){
}
```
####Getting Inputs
Inside the method we'll first have to get what the user has inputted in the form.
Laravel allows as to do that using the ```Input::get('field_name')``` method
where the ``field_name``` is the name of the input field ```<inputtype="text"name="username"/>```.
There's also the ```input::all()``` method which gets all the data inputted in the form
and it would be nice if we could just use that but we need to hash the password before saving it to the database that's why we need to get those fields separately.
```
$username = Input::get('username');
$password = Input::get('password');
$user_details = Input::all(); //Input::all() gets all the data inputted in the form
```
####Form Validation
Next we have to specify the validation rules for each field.
Laravel still uses the name attribute of the input field for this.
For both fields were using the same rules which is ```required``` this is the only rule we need since this is just a login form.
Next, create another view for the registration of new users.
Again there's nothing bizzare about this.
The only thing that we haven't already used is ```input::old()``` and ```@foreach```. The ```input::old()``` method is
used to access the value that was inputted by the user before the form
was submitted. This is very useful since we don't have to write the functionality ourselves, Laravel has already this useful functionality built in to it. The most common use case for this is for forms that has validation errors.
Normally you would want to retrieve the values that were originally submitted.
On the other hand ```@foreach``` is just like the ```foreach``` that were using in plain PHP: to iterate over an array or an object. In this case were merely iterating through all the departments and the roles for each department in the database. There are only 3 departments so the looping for the department can be done without the ```@foreach``` but it is such a joy to use ```@foreach``` that I didn't really think of it.
Of course all the data that we are iterating through aren't directly available in the view, we will have to pass the data to the view using the controller which will render this view. And that's what were going to do next.
```
@layout('main')
@section('content')
<div class="row">
<div class="twelve columns">
<h5>Create User</h5>
</div>
</div>
<div class="row">
@render('errors')
@render('success')
<form method="post">
<div class="row">
<div class="two columns">
<label for="firstname" class="right inline">First Name </label>
<button class="success medium button" href="#">Create User</button>
</div>
</div>
</form>
</div>
@endsection
```
###Admin Controller
As I have said earlier were now going to create the controller that will
contain the code to render and process the form that we've just created.
```
php artisan generate:controller admin restful
```
####Default Data
Define the default data that will be used throughout the controller.
```
private $departments;
private $it_roles;
private $marketing_roles;
private $defense_roles;
```
####Constructor
On the constructor we first have to call ```parent::__construct();``` to make sure we won't be overriding what the base controller has on its constructor.
In the code below were using 1 new animal which is the ```Cache```. The ```Cache``` class is basically used
for caching things or saving things temporarily to a location were access is faster.
This is commonly used for caching data from the database so the application won't have to hit the database
everytime a particular page is accessed by a user.
```
public function __construct(){
parent::__construct();
if(Cache::has('admin_defaults')){ //check if the cache has already the ```admin_defaults``` item
$admin_defaults = Cache::get('admin_defaults'); //get the admin defaults
We'll also need to have a feature wherein the administrator can view a list of the users who are using the application.
This will also serve as a link to the user update page where the administrator can
update user details. The administrator can also update the status of the user from this page.
The status can either be ```enabled``` or ```disabled``` if the user is disabled then he cannot login to the application. Lastly, we'll also include a link to the user activity log so that the administrator can view
all the transactions that the user has performed in the application.
function(response){ //the response is either 1 or 0, if the admin disabled the user the response would be the opposite which is 1. If the admin enabled the user the response would be 0
var icons = ["foundicon-unlock", "foundicon-lock"];
child.removeClass();
child.addClass("icons " + icons[response]); //change the icon based on the response
child.data("action", response); //change the data-action attribute based on response
}
);
});
</script>
@endsection
```
Back to the ```admin``` controller. Create a new method and call it ```post_update_userstatus``` it will
accept two arguments: user_id and status.
```
public function post_update_userstatus($user_id, $status){
//update user status
DB::table('tbl_users')
->where('user_id', '=', $user_id)
->update(array('status' => $status));
log_action("update user status");
//determine the new status
$new_status = ($status == 1) ? 0 : 1; //the new status will be equal to 0 if status is 1, it will be equal to 1 if status is 0
echo $new_status; //echo it out, this is the response that were getting earlier from JavaScript
}
```
To render the view for viewing the list of users, create another method.
```
public function get_users(){
if(!Cache::has('users')){ //if the users has not already been cached
<button class="success medium button" href="#">Update User</button>
</div>
</div>
</form>
</div>
@endsection
```
Create another method in the ```admin``` controller that will render the user update form.
```
public function get_user($user_id){
$user = $this->_get_userdata($user_id);
return View::make(
'admin.user',
array(
'user' => $user,
'departments' => $this->departments,
'admin_roles' => $this->admin_roles,
'assessor_roles' => $this->assessor_roles,
'treasury_roles' => $this->treasury_roles
)
);
}
```
You will notice that we have used a method called ```_get_userdata()``` which takes the users id as
an argument. This method returns the user details based on the id that is specified.
We are joining the ```departments``` and ```roles``` table as well to get the department and the role to which the user belongs. Then we use the ```where()``` method to specify that we only want to get the user
which has a specific id. Then we use the ```first()``` method to let Laravel know that we only want to fetch a single record. Because when we just use ```get()``` Laravel(fluent) will return an array and we'll have to access
the results later on by doing something like ```$user_data[0]->user_id``` which isn't that bad but we'll have two type more characters.
User::$rules['username'] = 'required|unique:tbl_users,username,' .$user_id . ',user_id'; //username is still unique but we need to exclude the user that were currently updating by specifying the user id
User::$rules['password'] = ''; //by default password is required now it isn't
Create another view and call it ```userlogs```. Nothing fancy here, this will just list out all the activities/transactions performed by a specific user or all users on the current day.
```
@layout('main')
@section('content')
<div class="row">
<div class="twelve columns">
<h5>User Logs - {{ $scope }}</h5>
</div>
</div>
<div class="row">
<div class="twelve columns">
<table class="twelve dtable">
<thead>
<tr>
<th>Username</th>
<th>Department</th>
<th>Activity</th>
<th>Timestamp</th>
</tr>
</thead>
<tbody>
@foreach($userlogs as $logs)
<tr>
<td>{{ $logs->user }}</td>
<td>{{ $logs->department }}</td>
<td>{{ $logs->transaction }}</td>
<td>{{ date("M d, Y @ g:i A", strtotime($logs->dateandtime)) }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
@endsection
```
Going back to the ```admin``` controller we create another method for rendering the user logs.
Nothing fancy here except for the usage of a raw query which can be done by using the ```query()``` method
from the ```DB``` class.
If there's a user id supplied then its only going to select the logs for a specific user which has that id.
If there's no user id then its going to select all the transactions performed by every user on that day.
Create another view and call it ```transactions``` this will be used to update the transactions
that can be performed by each role.
I guess its about time to give a little bit of explanation on what these transactions really are in this project that were creating.
Transactions are the things that the users can do in the application. In this project the navigation is representing the transactions. So disabling a transaction will hide the equivalent menu in the navigation so that the user won't be able to access it. But what we need to do is more than just hiding the menu item. What if the user has already memorized the actual route to access that specific page and he just types it in the address bar?
He will still be able to access the page only this time he didn't have to use the menu.
That's what were going to do later. For now let's put our minds back to the updating of transactions that can be performed by users.
Again there's nothing special about the form below.
The admin will just have to select the role that he wants to update.
After that he'll just click on the ```view``` button to load the transactions for that role.
Then he'll just have to deselect the transactions that cannot be performed by the role and select all the transactions that can be performed by the role. Were using ```ajax``` to submit the status of the transaction to the server-side that's why we don't have something like a submit button to commit the changes.
Create another method called ```post_update_transactionstatus```. This is the method that
we have specified earlier in the ```transactions``` view
where the ```roletransaction_id``` and ```status``` is submitted.
As you can see were just accessing those submitted values through the parameters which represents the third and fourth segment of the route.
```
public function post_update_transactionstatus($roletransaction_id, $status){
DB::table('roletransactions')
->where('id', '=', $roletransaction_id)
->update(array('status' => $status));
log_action("update transaction status");
}
```
###Generating the User Navigation
Yep! you heard that right, were generating the navigation everytime the user logs in.
Were going to fetch what transactions the user can perform in the application and loop through the results.
This means that for every user, different menu items will be generated.
But of course were not going to have a feature wherein the admin updates the transactions for a particular role and it will automatically update the UI of all the users who are currently logged in to the application.
That would be uber-cool but I don't currently know how to do those real-time applications.
So we'll just stick with old-school for now.
The menu will just change once the user has logged out and logged back in again.
And this is just fine its not like the admin is going to update the transactions that the users can perform every second of the day. We don't need to over-engineer things for the sake of being cool.
####View Composers
Before anything else I'd like to introduce another templating concept in Laravel which is the view composers.
View composers are simply used to nest or attach data or a view into another view.
This is perfect for our purpose since we want the user navigation to be different for each role.
View composers takes 2 parameters.
The first parameter is the view in which you want to attach a specific data.
But of course you can use an array to specify multiple views.
The second parameter is what you want to do to those views.
Here were just attaching data that is fetched from the database.
Go ahead and open up ```routes.php``` inside the ```application``` directory and add the following code:
```
View::composer(
//specify the views where the data will be attached
array(
'admin.home',
'admin.create_role', 'admin.create_user',
'admin.user', 'admin.users',
'admin.userlogs', 'admin.transactions'
),
function($view){
$role_id = Session::get('role_id'); //load role id of current user from session
Going back to the ```routes.php``` file. Create a filter and call it ```check_roles``` we will use this filter to check if the current user has the authority/privilege to access the page that he is trying to access.
```
Route::filter('check_roles', function()
{
$current_url = URI::current(); //get current url excluding the domain.
$current_page = URI::segment(2); //get current page which is stored in the second uri segment. Just a refresher: //the first uri segment is the controller, the second is the method,
//third and up are the parameters that you wish to pass in
$access = 0;
$nav = Session::get('navigation'); //get menu items from session
//excluded pages are the pages we don't want to execute this filter
//since they should always be accessible for a logged in user