An introduction to the Fuel PHP framework
Table of contents:
Before You Get Started
This tutorial is here to introduce you to the FuelPHP framework by walking you through the creation of a simple messaging app.
Choose – Windows or Linux/OSX
Requirements
First and foremost, here’s what you’re going to need on Windows:
- Fuel PHP framework (we’re using v1.7)
- XAMPP (if you’re having trouble installing this, go here for a tutorial)
- PHP Environment Variables Configured in Windows (for command line executions)
- phpMyAdmin (it comes with XAMPP)
- A basic understanding of the Model-View-Controller (MVC) pattern.
- At least a basic understanding of Git and version control systems.
First and foremost, here’s what you’re going to need on Linux/OSX:
- Fuel PHP framework (we’re using v1.7)
- XAMPP (for beginners) or any basic LAMP package
(many tutorials exist, here are some for a few popular linux distros: Ubuntu, Debian, SUSE, and Fedora) - phpMyAdmin (installation will vary depending on your os, XAMPP users have it already!)
- A basic understanding of the Model-View-Controller (MVC) pattern.
- At least a basic understanding of Git and version control systems.
Keep in mind that the completed source code for this tutorial is available from the Fuel Crash Course GitHub repository. Simply clone our repo and make sure you initialize all the sub-repos using git submodule update --init
Part 1 – Creating a Messaging System
Basic FuelPhp Setup
Create a folder called “fuel_intro” in the htdocs folder of xampp.
Next, open up command line, navigate to that folder, and type in the following: git clone https://github.com/fuel/fuel.git .
Don't forget the period at the end, that will clone the files into the directory you are currently in.
Now that the files have been clones, you have to update all the registered submodules by typing in the following two commands:
git submodule init
then
git submodule update
then
php composer.phar update
Checking Your Work
In your browser, navigate to http://localhost/fuel_intro/public and you should see the “successful install” page below from Fuel.
Config It Up
For this tutorial we’re going to be using an orm package, included in your install of Fuel. Head over to /fuel/app/config/config.php
and uncomment the “always_load” array. Then uncomment the “packages” array and the “orm” package:
/**************************************************************************/ /* Always Load */ /**************************************************************************/ 'always_load' => array( /** * These packages are loaded on Fuel's startup. * You can specify them in the following manner: * * array('auth'); // This will assume the packages are in PKGPATH * * // Use this format to specify the path to the package explicitly * array( * array('auth' => PKGPATH.'auth/') * ); */ 'packages' => array( 'orm', ), /** * These modules are always loaded on Fuel's startup. You can specify them * in the following manner: * * array('module_name'); * * A path must be set in module_paths for this to work. */ // 'modules' => array(), /** * Classes to autoload & initialize even when not used */ // 'classes' => array(), /** * Configs to autoload * * Examples: if you want to load 'session' config into a group 'session' you only have to * add 'session'. If you want to add it to another group (example: 'auth') you have to * add it like 'session' => 'auth'. * If you don't want the config in a group use null as groupname. */ // 'config' => array(), /** * Language files to autoload * * Examples: if you want to load 'validation' lang into a group 'validation' you only have to * add 'validation'. If you want to add it to another group (example: 'forms') you have to * add it like 'validation' => 'forms'. * If you don't want the lang in a group use null as groupname. */ // 'language' => array(), ),
While you're in this file, there's another Fuel preset you'll want to set. That'd be the default timezone. Fuel requires that you set a default timezone for it to work. Fuel uses PHP's built-in time zones, so check out PHP's list of supported timezones and find one that corresponds to yours.
For simplicity's sake, this tutorial will use America/New_York.
/** * DateTime settings * * server_gmt_offset in seconds the server offset from gmt timestamp when time() is used * default_timezone optional, if you want to change the server's default timezone */ 'server_gmt_offset' => 0, 'default_timezone' => 'America/New_York',
After doing that, go to phpmyadmin (http://localhost/phpmyadmin) and create a database called “fuel_intro”. No need to create any tables now, we'll use Fuel to setup our tables.
We renamed the database to "fuel_intro" and changed the password to the default password for our mysql install. Aside from that, we left everything else alone since the defaults will work fine.
Now, make these changes in the db configuration in Fuel’s development environment: fuel/app/classes/config/development/db.php
return array( 'default' => array( 'connection' => array( 'dsn' => 'mysql:host=localhost;dbname=fuel_intro', 'username' => 'root', 'password' => '', ), ), );
Oil Slick
Fuel has a cool command line utility called Oil that lets you set up a lot of your controllers and tables automatically.
Bring up Command Prompt, type in the file path of your Fuel installation, and then run php oil
. You should see a bit of oil usage documentation.
Seeing this means that Oil is successfully installed and working! Now let’s get to business.
Every Building Needs a Scaffold
Scaffolding in fuel allows you to quickly create a related controller, model (using ORM), and view for manipulating information.
What we want to end up with after creating the scaffold is a table with the following fields:
The ‘id’, ‘created_at’, and ‘updated_at’ columns are made automatically, so we only have to tell oil to make the 'name' and 'message' fields. Just feed your command prompt the following:
php oil generate scaffold messages name:string message:text
The only weird thing about this is that the “string” type for the name is a shortcut that is really varchar[255].
If you look at your document tree, you can see that the controller, model, and view were created and populated with default content.
If you look at your database, you’ll notice that no table has been created. That’s because we need to migrate the database.
Migra-wha?
A migration is like a version control scheme for your database. If you open up the file /fuel/app/migrations/001_create_messages.php
you can see what is going to be generated when the migration runs. Checking the file before you run the migration is a good idea, at least to check for typos.
<?php namespace Fuel\Migrations; class Create_messages { public function up() { \DBUtil::create_table('messages', array( 'id' => array('constraint' => 11, 'type' => 'int', 'auto_increment' => true), 'name' => array('constraint' => 255, 'type' => 'varchar'), 'message' => array('type' => 'text'), 'created_at' => array('constraint' => 11, 'type' => 'int'), 'updated_at' => array('constraint' => 11, 'type' => 'int'), ), array('id')); } public function down() { \DBUtil::drop_table('messages'); } }
Since we know what the migration is going to create, go ahead and run it. That'll be:
php oil refine migrate
Quick Note: If you encounter errors migrating with oil, you may need to change this dp.php file to read 'mysql:host=<IP_ADDRESS>;dbname=fuel_intro'
.
Now the table has been created, and you can add messages to it! Take a look at your database, you should see something like the screenshot from before.
Prettying Up The Code
Navigate to “http://localhost/fuel_intro/public/messages” and add a message.
If you see the following error, copy and paste the code into a new php file called crypt.php at /fuel/app/config
.
If you look at the message, you’ll notice that all the layout is done using a table, so take a minute to make the code semantic.
Go into /fuel/app/views/messages/index.php
and change the following table into an unordered list:
After:

Listing Messages

 <?php if ($messages): ?>
 <?php foreach ($messages as $message): ?>
<?php echo $message->name; ?>

<?php echo $message->message; ?>

<?php echo Html::anchor('messages/view/'.$message->id, 'View'); ?>

<?php echo Html::anchor('messages/edit/'.$message->id, 'Edit'); ?>

<?php echo Html::anchor('messages/delete/'.$message->id, 'Delete', array('onclick' => "return confirm('Are you sure?')")); ?>

 <?php endforeach; ?>
 <?php else: ?>
No Messages.
 <?php endif; ?>
 <?php echo Html::anchor('messages/create', 'Add new Message', array('class' => 'btn success')); ?>

Now your code is more semantic, if not more understandable (If you don’t like the bullets or the list view, you can take them away using CSS).
New Landing Page
Remember the successful install page you visited immediately after installing fuel? What you were seeing on that page comes from a view as well. Through routing, fuel can redirect the browser to display views outside of the default structure. These routing directions are stored in /fuel/app/config/routes.php
.
By default there are two routes: the landing page and the 404 page.
<?php return array( '_root_' => 'welcome/index', // The default route '_404_' => 'welcome/404', // The main 404 route 'hello(/:name)?' => array('welcome/hello', 'name' => 'hello'), );
You need to have Fuel redirect the browser to the messages view when going to http://localhost/fuel_intro/public instead of the successful install page. To do that, simply edit the value for the _root_ key like so:
<?php return array( '_root_' => 'messages/index', // The default route '_404_' => 'welcome/404', // The main 404 route 'hello(/:name)?' => array('welcome/hello', 'name' => 'hello'), );
Part 2 – Adding Comments
New Comments
Now that we have semantic messages, we need to add a way for users to add comments to those messages.
We could use a scaffold again to create everything necessary for comments, but let's do everything that the scaffolding command does by hand. This will give you an idea as to just how powerful oil commands are.
The first step is to create our controllers and views for the comments. We will be using oil’s generate command again to do this. Let’s watch:
php oil generate controller comments edit create
As you can see, a controller was generated called “comments” with the actions create and edit. Two views were also created, both associated with the comments controller (edit.php and create.php).
Open the controller at fuel/app/classes/controller/comments.php
and see what was made.
Controlling the Power
The comments controller should look like this:
<?php class Controller_Comments extends Controller_Template { public function action_edit() { $data["subnav"] = array('edit'=> 'active'); $this->template->title = 'Comments » Edit'; $this->template->content = View::forge('comments/edit', $data); } public function action_create() { $data["subnav"] = array('create'=> 'active'); $this->template->title = 'Comments » Create'; $this->template->content = View::forge('comments/create', $data); } }
Defaults
The default class name for the controller is Controller_NAME, and methods accessible through the url are action_NAME. So if you’re making your own methods or controllers, you should follow the conventions that are set forth in this file.
Take careful note that the class ought to read "Controller_Comments", rather than the default "Controller_Comment". Older versions of fuel will autocorrect the name and make it singular.
Now, back in your action_create function, we need to make a few changes to prepare for the views we are about to build:
public function action_create() { $data["subnav"] = array('create'=> 'active'); $this->template->title = 'Comments » Create'; $data['form'] = View::forge('comments/_form'); $this->template->content = View::forge('comments/create', $data); }
We loaded the form we're about to build into the $data
array with the key 'form'. This will be accessible in our view as $form
.
Form Templates
If you look at the Messages views (/fuel/app/views/messages/), you will see a file called “_form.php”. This is a form template for messages that gets called in the messages views and should be recreated for the comments views as well.
Go ahead and create a new file called/fuel/app/views/comments/_form.php
.
Since this is a form template, you’re going to start the file with new form tags. Rather than using straight HTML, Fuel has classes for HTML elements that we will use. To open a new form write the following:
<?php echo Form::open(); ?>
This is analogous to writing “<form action="http://localhost/fuel_intro/public/index.php/comments/create" accept-charset="utf-8" method="post">
” so it’s a good idea to use these HTML elements when possible.
Next, create a name field for the comment:
<?php echo Form::open(); ?>
 <?php echo Form::label('Name', 'name'); ?> <?php echo Form::input('name', Input::post('name', isset($comment) ? $comment->name : '')); ?>

Form::label()
takes (in order) the text that will be displayed to the user and the id that should match the name attribute of the input field.Form::input()
takes (in order) the name attribute of the form and the default value of that form element.
You can repeat this code for the comment text as well. The only difference is that instead of Form::input
, you’ll need to use Form::textarea()
, which takes in the same parameters.
<?php echo Form::open(); ?>
 <?php echo Form::label('Name', 'name'); ?> <?php echo Form::input('name', Input::post('name', isset($comment) ? $comment->name : '')); ?>

 <?php echo Form::label('Comment', 'comment'); ?> <?php echo Form::textarea('comment', Input::post('comment', isset($comment) ? $comment->comment : ''), array('cols' => 60, 'rows' => 8)); ?>

Did you notice the extra bit of code at the end? The final parameter you can pass for the label, input, or textarea tags is an array of attributes. So when we write “array('cols' => 60, 'rows' => 8));
” at the end of the textarea function, it’s the same as saying “<textarea cols="60" rows="8"></textarea>
“
Next we just need to add the submit button, a hidden input to keep track of the message this comment is attached to, and close the form:
<?php echo Form::open(); ?>
 <?php echo Form::label('Name', 'name'); ?> <?php echo Form::input('name', Input::post('name', isset($comment) ? $comment->name : '')); ?>

 <?php echo Form::label('Comment', 'comment'); ?> <?php echo Form::textarea('comment', Input::post('comment', isset($comment) ? $comment->comment : ''), array('cols' => 60, 'rows' => 8)); ?>
 <?php echo Form::hidden('message_id', Input::post('message_id', isset($message) ? $message : '')); ?>
 <?php echo Form::submit(); ?>
 <?php echo Form::close(); ?>
Now open up fuel/app/views/comments/create.php
and write the following code:
<?php $message = isset($message) ? $message : ''; ?>
New Comment
 <?php echo $form; ?>
<?php echo Html::anchor('messages/view/'.$message, 'Back'); ?>

This bit of code does the following:
- If the message variable doesn't exist, set it to an empty string.
- Print out the form to the screen.
- Create an anchor tag to take us back to the message.
Go to http://localhost/fuel_intro/public/comments/create/ and take a look at the form. You should see this:
Modeling
This is the easy part of the tutorial. All you need to do is run the following in the command line for oil to use (make sure the model name is singular!):
php oil generate model comment name:string comment:text message_id:int
This command created comment.php in the fuel/app/classes/model
folder. If you open up the file you should see this:
<?php class Model_Comment extends \Orm\Model { protected static $_properties = array( 'id', 'name', 'comment', 'message_id', 'created_at', 'updated_at' ); protected static $_observers = array( 'Orm\Observer_CreatedAt' => array( 'events' => array('before_insert'), 'mysql_timestamp' => false, ), 'Orm\Observer_UpdatedAt' => array( 'events' => array('before_save'), 'mysql_timestamp' => false, ), ); }
Why It’s So Small
Notice that there’s not much code there? That’s because the comment model extends a class called ORM, or the Object-relational mapper. You can take a look at some of the more complicated things ORM can do, but for now we’re just going to stick to the defaults.
Since we made another model, we’re going to have to migrate to the newest version:
Quick Note: If an error is encountered when migrating, you can fix any typos in your migration file by going to /fuel/app/migrations/###_create_NAME.php
and editing the file.
Adding to the Database
We can now edit the comments controller to actually add our comments to the database. So go ahead and open the /fuel/app/classes/controller/comments.php
file.
First and foremost, an $id
variable is going to be taken in, so we need to add that as an attribute to the action_create function:
public function action_create($id = null) { $data["subnav"] = array('edit'=> 'active'); $this->template->title = 'Comments » Create'; $data['form'] = View::forge('comments/_form'); $this->template->content = View::forge('comments/create', $data); }
Notice that we are setting the $id
to null by default. Now we need to check to make sure that they’ve completed the form, so we add an if statement:
public function action_create($id = null) { if (Input::post()) { } $data["subnav"] = array('edit'=> 'active'); $this->template->title = 'Comments » Create'; $data['form'] = View::forge('comments/_form'); $this->template->content = View::forge('comments/create', $data); }
This is using Fuel’s Input class, but we could have just as easily used "if ($_POST)
” as well.
But what about going to the form before submitting?
public function action_create($id = null) { if (Input::post()) { } else { $this->template->set_global('message', $id, false); } $data["subnav"] = array('edit'=> 'active'); $this->template->title = 'Comments » Create'; $data['form'] = View::forge('comments/_form'); $this->template->content = View::forge('comments/create', $data); }
This means if they didn’t post anything, take the $id
and turn it into a variable called $message
that the view can use.
Now we need to build a new comment model in order to save the comment into the database.
public function action_create($id = null) { if (Input::post()) { $comment = Model_Comment::forge(array( 'name' => Input::post('name'), 'comment' => Input::post('comment'), 'message_id' => Input::post('message_id'), )); } else { $this->template->set_global('message', $id, false); } $data["subnav"] = array('edit'=> 'active'); $this->template->title = 'Comments » Create'; $data['form'] = View::forge('comments/_form'); $this->template->content = View::forge('comments/create', $data); }
$comment
is now an object that has the comment information in it, so we need to try and save the comment:
public function action_create($id = null) { if (Input::post()) { $comment = Model_Comment::forge(array( 'name' => Input::post('name'), 'comment' => Input::post('comment'), 'message_id' => Input::post('message_id'), )); if ($comment and $comment->save()) { } } else { $this->template->set_global('message', $id, false); } $data["subnav"] = array('edit'=> 'active'); $this->template->title = 'Comments » Create'; $data['form'] = View::forge('comments/_form'); $this->template->content = View::forge('comments/create', $data); }
‘And’ is used here instead of ‘&&’ because it’s part of the Fuel coding standards.
If the if
statement is successful, it will save the comment to the database, so we should now set a flash to show that to the user. Session Flashes are for information with a limited lifespan, such as presenting success or failure information.
So we can set our flash and redirect our user back to the message they were viewing:
public function action_create($id = null) { if (Input::post()) { $comment = Model_Comment::forge(array( 'name' => Input::post('name'), 'comment' => Input::post('comment'), 'message_id' => Input::post('message_id'), )); if ($comment and $comment->save()) { Session::set_flash('success', 'Added comment #'.$comment->id.'.'); Response::redirect('messages/view/'.$comment->message_id); } } else { $this->template->set_global('message', $id, false); } $data["subnav"] = array('edit'=> 'active'); $this->template->title = 'Comments » Create'; $data['form'] = View::forge('comments/_form'); $this->template->content = View::forge('comments/create', $data); }
or else we set the flash to say that the comment couldn’t be saved:
public function action_create($id = null) { if (Input::post()) { $comment = Model_Comment::forge(array( 'name' => Input::post('name'), 'comment' => Input::post('comment'), 'message_id' => Input::post('message_id'), )); if ($comment and $comment->save()) { Session::set_flash('success', 'Added comment #'.$comment->id.'.'); Response::redirect('messages/view/'.$comment->message_id); } else { Session::set_flash('error', 'Could not save comment.'); } } else { $this->template->set_global('message', $id, false); } $data["subnav"] = array('edit'=> 'active'); $this->template->title = 'Comments » Create'; $data['form'] = View::forge('comments/_form'); $this->template->content = View::forge('comments/create', $data); }
Creating a Comment from a Message
Now we’re going to add a link to the view.php
file in the messages view, so you can add a comment to any message.
Go to /fuel/app/views/messages/view.php
and add:

 Name: <?php echo $message->name; ?>

 Message: <?php echo $message->message; ?>

<?php echo Html::anchor('comments/create/'.$message->id, 'Add new Comment'); ?>
 <?php echo Html::anchor('messages/edit/'.$message->id, 'Edit'); ?> | <?php echo Html::anchor('messages', 'Back'); ?>
Go on back to http://localhost/fuel_intro/public/messages and add a comment to one of your messages so we can keep going.
Now that we have a Comment…
Since there is a comment in the database now, we can add functions to the controller to manipulate that comment. First off, we need a way to be able to edit that comment in /fuel/app/classes/controller/comments.php
.
The edit function will take in one parameter which is the id of the comment
public function action_edit($id = null) { $data["subnav"] = array('edit'=> 'active'); $this->template->title = 'Comments » Edit'; $this->template->content = View::forge('comments/edit', $data); }
Now we use the comment model to find the comment, based on its id.
public function action_edit($id = null) { $comment = Model_Comment::find($id); $data["subnav"] = array('edit'=> 'active'); $this->template->title = 'Comments » Edit'; $this->template->content = View::forge('comments/edit', $data); }
The rest of the code is pretty much the same as creating a comment with a few minor tweaks, here it is in bulk:
public function action_edit($id = null) { $comment = Model_Comment::find($id); if (Input::post()) { $comment->name = Input::post('name'); $comment->comment = Input::post('comment'); if ($comment->save()) { Session::set_flash('success', 'Updated comment #'.$id); Response::redirect('messages/view/'.$comment->message_id); } else { Session::set_flash('error', 'Could not update comment #'.$id); } } else { $this->template->set_global('comment', $comment, false); $this->template->set_global('message', $comment->message_id, false); } $data["subnav"] = array('edit'=> 'active'); $this->template->title = 'Comments » Edit'; $data['form'] = View::forge('comments/_form'); $this->template->content = View::forge('comments/edit', $data); }
The action $comment->save()
updates the comment if it already exists in the database, or adds it if it doesn’t.
Note the global variable $message
, which will keep track of the message id.
Also note the $form
variable, which will contain our form.
All that remains is to fix up the comment edit view. Go ahead and open up fuel/app/views/comments/edit.php
. It'll wind up looking like the view for editing messages, with a few differences:

 <li class='<?php echo Arr::get($subnav, "edit" ); ?>'><?php echo Html::anchor('comments/edit','Edit');?>
 <li class='<?php echo Arr::get($subnav, "create" ); ?>'><?php echo Html::anchor('comments/create','Create');?>

Editing Comment

 <?php $message = isset($message) ? $message : ''; ?> <?php echo $form; ?>
<?php echo Html::anchor('messages/view/'.$comment->message_id, 'Back'); ?>

Deletion
Deleting the comment is just as easy as saving it. Go back to /fuel/app/classes/controller/comments.php
and create another action function called delete, and then call $comment->delete()
instead of $comment->save()
. Don't forget to pass the comment id!
public function action_delete($id) { $comment = Model_Comment::find($id); if ($comment) { $comment->delete(); Session::set_flash('success', 'Deleted comment #'.$id); } else { Session::set_flash('error', 'Could not delete comment #'.$id); } Response::redirect('messages/view/'.$comment->message_id); }
In the next section we aim to accomplish two things: showing the number of comments that a message has and showing the comments in a list when we view the message.
Number of Comments
Open up the messages controller. At this point you should be pretty good at navigating the file tree, so we’ll stop giving you paths to things you’ve everything) and take a look at action_index:
public function action_index() { $data = array('messages' => Model_Message::find('all')); $this->template->title = "Messages"; $this->template->content = View::forge('messages/index', $data); }
Pretty simple, it's finding all the messages and sending them to the view. In this statement. To make things a little more flexible as we add in comments, we're going to put the view and messages into their own variables.
Go to the top of the function and add this:
public function action_index() { $messages = Model_Message::find('all'); $view = View::forge('messages/index', array('messages' => $messages)); $this->template->title = "Messages"; $this->template->content = $view; }
Just under the messages array we’re going to declare an array called $comment_links, and then loop through the messages:
public function action_index() { $messages = Model_Message::find('all'); $comment_links = array(); foreach ($messages as $message) { } $view = View::forge('messages/index', array('messages' => $messages)); $this->template->title = "Messages"; $this->template->content = $view; }
We need to retrieve the comments associated with this particular message, so we query the database for comments that match the message’s id. So far we have been using models to retrieve information from the database, and we could do that here using the Model's query method, but Fuel also has a DB class that we'd like to show you.
public function action_index() { $messages = Model_Message::find('all'); $comment_links = array(); foreach ($messages as $message) { $query = DB::select() ->from('comments') ->where('message_id', $message->id) ->execute(); } $view = View::forge('messages/index', array('messages' => $messages)); $this->template->title = 'Messages'; $this-template->content = $view; }
The DB::select()
method builds a SQL query to retrieve all the comments. This is analogous to “SELECT * FROM 'comments' WHERE message_id = $message->id
“
Now we just need to count the number of results and add that number to the $comment_links array. To make the message's comments easy to access, we’re going to make the comment array key match the message id:
public function action_index() { $messages = Model_Message::find('all'); $comment_links = array(); foreach ($messages as $message) { $results = DB::select() ->from('comments') ->where('message_id', $message->id) ->execute(); $count = count($results); $comment_links[$message->id] = "View | $count Comment(s)"; } $view = View::forge('messages/index', array('messages' => $messages)); $this->template->title = 'Messages'; $this->template->content = $view; }
Let's pretty up the comment count. We'll use Fuel's Inflector class to automatically pluralize ‘Comment‘ if the count is 0 or above 1.
public function action_index() { $messages = Model_Message::find('all'); $comment_links = array(); foreach ($messages as $message) { $results = DB::select() ->from('comments') ->where('message_id', $message->id) ->execute(); $count = count($results); if ($count == 0) { $comment_links[$message->id] = 'View'; } else { $comment_links[$message->id] = $count.' '.Inflector::pluralize('Comment', $count); } } $view = View::forge('messages/index', array('messages' => $messages)); $this->template->title = 'Messages'; $this->template->content = $view; }
Now we just need to set the $comment_links
and $messages
variables to the view (which is why we declared $view
at the top of the function):
public function action_index() { $messages = Model_Message::find('all'); $comment_links = array(); foreach ($messages as $message) { $results = DB::select() ->from('comments') ->where('message_id', $message->id) ->execute(); $count = count($results); if ($count == 0) { $comment_links[$message->id] = 'View'; } else { $comment_links[$message->id] = $count.' '.Inflector::pluralize('Comment', $count); } } $view = View::forge('messages/index'); $view->set('comment_links', $comment_links); $view->set('messages', $messages); $this->template->title = 'Messages'; $this->template->content = $view; }
Now that we are passing the number of comments to the messages view, we need to modify the html to display it. Go back to the index.php
file for the messages view, and change it from this:

<?php echo Html::anchor('messages/view/'.$message->id, 'View'); ?>

To this:

<?php echo Html::anchor('messages/view/'.$message->id, $comment_links[$message->id]); ?>

What we did was modify the “View” message link to include the number of comments, if any are present. At the moment, there shouldn’t be any.
Now if you go to http://localhost/fuel_intro/public/messages/ you should see the number of comments each message has.
Showing the Comments
To actually show the comments for each view, you need to get all the comments associated with a message in the messages controller:
public function action_view($id = null) { is_null($id) and Response::redirect('messages'); if ( ! $message = Model_Message::find($id)) { Session::set_flash('error', 'Could not find message #'.$id); Response::redirect('messages'); } $comments = Model_Comment::find('all', array('where' => array('message_id' => $id))); $data = array( 'message' => $message, 'comments' => $comments ); $this->template->title = 'Message'; $this->template->content = View::forge('messages/view', $data); }
The second parameter of the find()
method defines the options in the query. Here we use it to define the WHERE
statement in our query.
Now all we need to do is show it on the view.php page of the message views:
Message: <?php echo $message->message; ?>

Comments

 <?php foreach ($comments as $comment) : ?>

Name: <?php echo $comment->name; ?>

Comment:
<?php echo $comment->comment; ?>

<?php echo Html::anchor('comments/edit/'.$comment->id, 'Edit'); ?>| <?php echo Html::anchor('comments/delete/'.$comment->id, 'Delete', array('onclick' => "return confirm('Are you sure?')")); ?>

 <?php endforeach; ?>

The final section will deal with logging and and creating users.
Part 3 – Adding a Login System
Creating Users and Login
At this point we’ve made our messages and comments system. However, we don’t want just anyone to be able to edit/delete messages, and it would be nice if messages were associated with some kind of username, so we’re going to make a simple and generic user system for our messages.
First add the ‘auth’ package to the package list in the config file. That’s fuel/app/config/config.php
, in case you forgot.
'packages' => array( 'orm', 'auth', ),
Then we need to create a controller for our login:
php oil g controller users login logout register
Notice that we used g
instead of generate
. This is just one example of the many short tags that Oil allows you to use.
Now we need to build the models:
php oil g model user username:string password:string group:int email:string last_login:string login_hash:string profile_fields:string
The only thing that should be explained on this line is groups. Here’s the default group number definitions:
- -1 =
- Banned
- 0 =
- Guests
- 1 =
- Users
- 50 =
- Moderators
- 100 =
- Administrators
This allows you to check all of your user access in bulk, e.g. restricting access for all users whose group is lower than a specific number.
Finally, migrate to the new version (using the short tag “r” instead of “refine”):
php oil r migrate
The Default Table
The auth package defaults to a user table called “users” by default, so we don't need to do change any configuration options here. But it’s good to know where to find the default table name, and how to change it. The auth package has it's own configurations located within the package directory, the following file defines what the user table is called.
/fuel/packages/auth/config/simpleauth.php
:
/** * DB table name for the user table */ 'table_name' => 'users',
You can change the setting directly in this file, however the best method to change the user table would be to duplicate the above config and place it in a fuel/app/config/simpleauth.php
file. Fuel will automatically override the default package configuration files with your app's configurations.
Registration
Now that we have a model, controller, and views, we need to add a link to the registration so people can actually sign up! Since this should be on the top of all the pages, we need to edit the template page for the entire site. So go to /fuel/app/views/template.php
and add the following:

<?php echo $title; ?>

 <?php if (isset($user_info)) { echo $user_info; } else { $link = array(Html::anchor('users/login', 'Login'), Html::anchor('users/register', 'Register')); echo Html::ul($link); } ?> <?php if (Session::get_flash('success')): ?>
This checks to see if a user is logged in (we’ll call the object with the user’s info in it $user_info
), if they’re not logged in, then it builds an unordered list that links to a registration page.
Registration Model
We’re going to create the registration form using the model and passing it with the controller. Create a function at the bottom of the user model. It’s going to have an empty form called a Fieldset passed into it, which is kind of like a form that has validation attached to it:
<?php class Model_User extends \Orm\Model { protected static $_properties = array( 'id', 'username', 'password', 'group', 'email', 'last_login', 'login_hash', 'profile_fields', 'created_at', 'updated_at' ); protected static $_observers = array( 'Orm\Observer_CreatedAt' => array( 'events' => array('before_insert'), 'mysql_timestamp' => false, ), 'Orm\Observer_UpdatedAt' => array( 'events' => array('before_save'), 'mysql_timestamp' => false, ), ); public static function register(Fieldset $form) { } }
Now we need to attach fields to this form, and send it back to the controller.
public static function register(Fieldset $form) { $form->add('username', 'Username:')->add_rule('required'); $form->add('password', 'Choose Password:', array('type'=>'password'))->add_rule('required'); $form->add('password2', 'Re-type Password:', array('type' => 'password'))->add_rule('required'); $form->add('email', 'E-mail:')->add_rule('required')->add_rule('valid_email'); $form->add('submit', ' ', array('type'=>'submit', 'value' => 'Register')); return $form; }
The add()
function adds a certain field with the field’s name, label, and attributes in that order. The add_rule()
function adds a validation rule to the field. All the rules available by default can be found here.
User Controller Registration Function
Now we’re going to go to the action_register function within the users controller.
We are going to change it from this:
public static function action_register() { $this->template->title = 'Users » Register'; $this->template->content = View::forge('users/register'); }
To this:
public static function action_register() { $auth = Auth::instance(); $view = View::forge('users/register'); $form = Fieldset::forge('register'); Model_User::register($form); $view->set('reg', $form->build(), false); $this->template->title = 'User » Register'; $this->template->content = $view; }
We will use $auth
to authenticate users, $view
will be the view that will be displayed to the user, and $form
will be the fieldset that we’re sending to the model. Model_User::register($form)
just populates the form with the fields.
If we build the form in the view, we can see how this will work. Go to the user register view and add:

Register
 <?php echo $reg; ?>
Once you do this, you should see the registration form if you go to http://localhost/fuel_intro/public/index.php/users/register.
Validating the Registration
Now what happens when someone actually fills out the form? We need to have their registration validated. So we need to repopulate the form field with the values that the user typed in, and then send the whole form and authentication to a validation controller. Insert this into your users controller:
public static function action_register() { $auth = Auth::instance(); $view = View::forge('users/register'); $form = Fieldset::forge('register'); Model_User::register($form); if (Input::post()) { $form->repopulate(); $result = Model_User::validate_registration($form, $auth); } $view->set('reg', $form->build(), false); $this->template->title = 'User » Register'; $this->template->content = $view; }
Your user model now needs to take in the form and authentication, so add this function to it:
public static function register(Fieldset $form) { $form->add('username', 'Username:')->add_rule('required'); $form->add('password', 'Choose Password', array('type'=> 'password'))->add_rule('required'); $form->add('password2', 'Re-type Password:', array('type' => 'password'))->add_rule('required'); $form->add('email', 'E-mail:')->add_rule('required')->add_rule('valid_email'); $form->add('submit', ' ', array('type' => 'submit', 'value' => 'Register')); return $form; } public static function validate_registration(Fieldset $form, $auth) { }
Then we need to add a rule to the password field that will ensure that the user has typed in a matching password in the password2 field:
public static function validate_registration(Fieldset $form, $auth) { $form->field('password')->add_rule('match_value', $form->field('password2')->get_attribute('value')); }
Now we need to create a validation object and set messages to display what we want if the user enters in something incorrectly:
public static function validate_registration(Fieldset $form, $auth) { $form->field('password')->add_rule('match_value', $form->field('password2')->get_attribute('value')); $val = $form->validation(); $val->set_message('required', 'The field :field is required'); $val->set_message('valid_email', 'The field :field must be an email address'); $val->set_message('match_value', 'The passwords must match'); }
For a full explanation of the set message feature, look at Fuel’s documentation on error messages.
Next, we try to run the validation to see if it passes or fails:
public static function validate_registration(Fieldset $form, $auth) { $form->field('password')->add_rule('match_value', $form->field('password2')->get_attribute('value')); $val = $form->validation(); $val->set_message('required', 'The field :field is required.'); $val->set_message('valid_email', 'The field :field must be an e-mail address.'); $val->set_message('match_value', 'The passwords must match.'); if ($val->run()) { } else { $errors = $val->show_errors(); return array('e_found' => true, 'errors' => $errors); } }
So, if the validation doesn’t pass, the show_errors()
function turns the errors into an HTML list, and we return that and a boolean saying that errors were found.
What if they Pass?
If the user passes validation, then we get their username, password, and email from the form:
public static function validate_registration(Fieldset $form, $auth) { $form->field('password')->add_rule('match_value', $form->field('password2')->get_attribute('value')); $val = $form->validation(); $val->set_message('required', 'The field :field is required.'); $val->set_message('valid_email', 'The field :field must be an e-mail address.'); $val->set_message('match_value', 'The passwords must match.'); if ($val->run()) { $username = $form->field('username')->get_attribute('value'); $password = $form->field('password')->get_attribute('value'); $email = $form->field('email')->get_attribute('value'); } else { $errors = $val->show_errors(); return array('e_found' => true, 'errors' => $errors); } }
Try to create the user in the database, and catch any errors if we find them:
public static function validate_registration(Fieldset $form, $auth) { $form->field('password')->add_rule('match_value', $form->field('password2')->get_attribute('value')); $val = $form->validation(); $val->set_message('required', 'The field :field is required.'); $val->set_message('valid_email', 'The field :field must be an e-mail address.'); $val->set_message('match_value', 'The passwords must match.'); if ($val->run()) { $username = $form->field('username')->get_attribute('value'); $password = $form->field('password')->get_attribute('value'); $email = $form->field('email')->get_attribute('value'); try { $user = $auth->create_user($username, $password, $email); } catch (Exception $e) { $error = $e->getMessage(); } } else { $errors = $val->show_errors(); return array('e_found' => true, 'errors' => $errors); } }
We’re going to be nice here and log the user in once they register. So if the $user
object is present, we can use the $auth
object we passed to log the person in:
public static function validate_registration(Fieldset $form, $auth) { $form->field('password')->add_rule('match_value', $form->field('password2')->get_attribute('value')); $val = $form->validation(); $val->set_message('required', 'The field :field is required.'); $val->set_message('valid_email', 'The field :field must be an e-mail address.'); $val->set_message('match_value', 'The passwords must match.'); if ($val->run()) { $username = $form->field('username')->get_attribute('value'); $password = $form->field('password')->get_attribute('value'); $email = $form->field('email')->get_attribute('value'); try { $user = $auth->create_user($username, $password, $email); } catch (Exception $e) { $error = $e->getMessage(); } if (isset($user)) { $auth->login($username, $password); } } else { $errors = $val->show_errors(); return array('e_found' => true, 'errors' => $errors); } }
If the login doesn’t work, then we create an unordered list and return both that and the errors found array:
public static function validate_registration(Fieldset $form, $auth) { $form->field('password')->add_rule('match_value', $form->field('password2')->get_attribute('value')); $val = $form->validation(); $val->set_message('required', 'The field :field is required'); $val->set_message('valid_email', 'The field :field must be an email address'); $val->set_message('match_value', 'The passwords must match'); if ($val->run()) { $username = $form->field('username')->get_attribute('value'); $password = $form->field('password')->get_attribute('value'); $email = $form->field('email')->get_attribute('value'); try { $user = $auth->create_user($username, $password, $email); } catch (Exception $e) { $error = $e->getMessage(); } if (isset($user)) { $auth->login($username, $password); } else { if (isset($error)) { $li = $error; } else { $li = 'Something went wrong with creating the user!'; } $errors = Html::ul(array($li)); return array('e_found' => true, 'errors' => $errors); } } else { $errors = $val->show_errors(); return array('e_found' => true, 'errors' => $errors); } }
We have two more things to do. First, go to action_register()
on the users controller and add a check for errors, if there are no errors found, log the user in and redirect to the homepage:
public static function action_register() { $auth = Auth::instance(); $view = View::forge('users/register'); $form = Fieldset::forge('register'); Model_User::register($form); if (Input::post()) { $form->repopulate(); $result = Model_User::validate_registration($form, $auth); if ($result['e_found']) { $view->set('errors', $result['errors'], false); } else { Session::set_flash('success', 'User created.'); Response::redirect('./'); } } if (Input::post()) { $form->repopulate(); $result = Model_User::validate_registration($form, $auth); } $view->set('reg', $form->build(), false); $this->template->title = 'User » Register'; $this->template->content = $view; }
Second, go to the register view and check for errors:
<?php if (isset($errors)){echo $errors;}?> <?php echo $reg; ?>
There, now you should be able to register and be logged in automatically.
Regular Logging In and Out
At this point in the crash course we should be able to give you the code for this and expect you to understand it.
Add the following within the users controller:
public function action_login() { $view = View::forge('users/login'); $form = Form::forge('login'); $auth = Auth::instance(); $form->add('username', 'Username:'); $form->add('password', 'Password:', array('type' => 'password')); $form->add('submit', ' ', array('type' => 'submit', 'value' => 'Login')); if (Input::post()) { if ($auth->login(Input::post('username'), Input::post('password'))) { Session::set_flash('success', 'Successfully logged in! Welcome '.$auth->get_screen_name()); Response::redirect('messages/'); } else { Session::set_flash('error', 'Username or password incorrect.'); } } $view->set('form', $form, false); $this->template->title = 'User » Login'; $this->template->content = $view; } public function action_logout() { $auth = Auth::instance(); $auth->logout(); Session::set_flash('success', 'Logged out.'); Response::redirect('messages/'); }
Don’t forget to echo the form in the login view! The code is very similar to the user registration view with the exception of swapping $reg
with $form
.
Finishing Touches
Let’s quickly tidy up some of our code. Head over to the comments form view and remove the hidden field containing the id of the comment’s message:
<?php echo Form::hidden('message_id', Input::post('message_id', isset($message) ? $message : '')); ?>
Now in the comments controller, change the assignment of the comment’s message_id
property to use the $id
variable passed in rather than relying on the old hidden form:
public function action_create($id = null) { if (Input::post()) { $comment = Model_Comment::forge(array( 'name' => Input::post('name'), 'comment' => Input::post('comment'), 'id' => $id, //previously: Input::post('message_id'), ));
Now we just need to add the name of the person making the message (instead of letting them type it in themselves), and give them editing rights to their own posts.
Go to the _form.php files in both the comments and the messages views and replace the name input field with the user’s name.
In messages, from this:
<?php echo Form::label('Name', 'name'); ?>
 <?php echo Form::input('name', Input::post('name', isset($message) ? $message->name : '')); ?>
To this:
<?php echo Form::label('Name', 'name'); ?>
 <?php echo 'Name: '.Auth::instance()->get_screen_name(); ?>
In comments, from this:
<?php echo Form::label('Name', 'name'); ?> <?php echo Form::input('name', Input::post('name', isset($comment) ? $comment->name : '')); ?>
To this:
<?php echo Form::label('Name', 'name'); ?> <?php echo 'Name: '.Auth::instance()->get_screen_name(); ?>
Next, in both the message and comment controllers, replace the posted name with the user name in the action_create()
function. Change it from this:
'name' => Input::post('name'),
To this:
'name' => Auth::instance()->get_screen_name(),
Since we don't have a name input form any more, and the message model is still expecting one, you'll have to remove that old requirement. Head over to the message model and remove the validation check for the name field:
$val->add_field('name', 'Name', 'required|max_length[255]');
Now, head over to the messages index view. Add a check to see if any of the messages being browsed were created by the current user, and if so enable edit/delete privileges on them. This is actually pretty easy. Just change this:

<?php echo Html::anchor('messages/edit/'.$message->id, 'Edit'); ?>

<?php echo Html::anchor('messages/delete/'.$message->id, 'Delete', array('onclick' => "return confirm('Are you sure?')")); ?>

To this:
<?php if ($message->name == Auth::instance()->get_screen_name()) : ?>
<?php echo Html::anchor('messages/edit/'.$message->id, 'Edit'); ?>

<?php echo Html::anchor('messages/delete/'.$message->id, 'Delete', array('onclick' => "return confirm('Are you sure?')")); ?>
 <?php endif; ?>
Since there’s also an Edit link inside each message, we need to put a check in the message view as well. This code:
<?php echo Html::anchor('messages/edit/'.$message->id, 'Edit'); ?> | <?php echo Html::anchor('messages/', 'Back'); ?>
Becomes:
<?php if ($message->name == Auth::instance()->get_screen_name()) { echo Html::anchor('messages/edit/'.$message->id, 'Edit'); echo ' | '; } echo Html::anchor('messages', 'Back'); ?>
We should do the same check for comments.
This Is the Last Thing, I Promise
The very last thing we’re going to do is to check if the user is logged in. If they are, allow them to make a message or comment.
Near the bottom of the message view, find the creation of the 'Add new Comment' anchor. Wrap it up in an if
statement like so:
<?php if (Auth::instance()->check()) : ?>
<?php echo Html::anchor('comments/create/'.$message->id, 'Add new Comment'); ?>
 <?php endif; ?>
Likewise at the bottom of the message’s index view:
<?php if (Auth::instance()->check()) { echo Html::anchor('messages/create', 'Add new Message'); } ?>
Finally, we need to replace the login and registration links at the top of the page with a logout link. Head back over to the template file and make these few changes:
if (isset($user_info)) { echo $user_info; } else { if (Auth::instance()->check()) { $link = array('Logged in as: '.Auth::instance()->get_screen_name(), Html::anchor('users/logout', 'Logout')); } else { $link = array(Html::anchor('users/login', 'Login'), Html::anchor('users/register', 'Register')); } echo Html::ul($link); }
Now instead of always showing links for logging in or registering, once a user is logged in their name will be displayed along with a link to log out!
Finished!
Congratulations! You now have a working understanding of Fuel along with this neat little messaging system!
For questions, comments, or suggestions, let us know on Twitter @Techrangers!


All applicants must maintain a complete and current list of leadership and businesses associated with their organization.
You are required to notify the LCRB of any changes to your legal entity structure within ten business days of the change being made. These changes include:
All applicants must maintain a complete and current list of individual and businesses partners associated with their organization.
You are required to notify the LCRB of any changes to your legal entity structure within ten business days of the change being made. These changes include:
Sole Proprietors must provide their leadership information and keep it up to date.
You are required to notify the LCRB of name changes within ten business days of the change being made.
{{this.account?.businessType}} applicants must provide their leadership information and keep it up to date.
You are required to notify the LCRB of name changes within ten business days of the change being made.
An applicant that is an Indigenous Nation may have associates that are required to consent to security screening and financial integrity assessments as part of the application for a non-medical cannabis retail store licence. Applicants are required to provide associates with the Parcel Identifier (PID) or proposed retail store location address.
Parcel Identifier (PID):Applicants should direct associates to the LCRB non-medical cannabis webpage to download required forms and instructions for submitting documentation.
Associates will submit documentation for security screening and financial integrity assessments directly to the LCRB. Applicants should not delay submitting a completed application form and business financial integrity form. It is the applicant's responsibility to direct all associates to the link provided .
Associates for Indigenous Nations applications include all persons who are authorized to act on behalf of the nation.
If you require more information please email<EMAIL_ADDRESS>.
Please note: While they are not normally required as part of the licence application process, the Liquor and Cannabis Regulation Branch reserves the right to ask for an Indigenous Nation’s membership lists.
Fees are calculated based on the type of change reported and the number of licences and/or authorizations impacted. If no changes are made, or no licences or authorizations are held, you will not be charged a fee for submitting this information.
Please check appropriate box(es) below. You may complete more than one change section on this form. An incomplete application will be held for a maximum of thirty (30) days. If still incomplete after the thirty (30) day period, the application may be terminated.
Application Fee of ${{item.CannabisFee}} per Licence
Application Fee of ${{item.CannabisFee}} per Cannabis Licence, ${{item.LiquorFee}} per Liquor Licence
{{item.helpTextHeader}}
Complete this section when shares have been transferred within the licensee corporation or holding companies or there has been an amalgamation of companies within the licensee corporation but no new shareholders have been added (holding companies or individuals). See example:
Third party operators should also complete this section when an internal share transfer or an amalgamation occurs.
All newly added shareholders holding 10% or greater interest must complete a Personal History Summary and/or Cannabis Associate Security Screening form and required documents as described below
Shareholders (individuals) holding less than 10% interest, or non-voting shareholders, in the applicant corporation must provide their full legal name and date of birth. They do not need to provide a Personal History Summary or Cannabis Associate Security Screening form.
If the change is the result of an internal amalgamation, attach:
Complete this section when you have issued shares to a new individual or shareholder business.
Provide an updated central securities register.
If one of the new shareholders is a private corporation, a public corporation, a society or a partnership, documentation to support the applicable business type must be submitted, even if the shareholder holds less than 10% interest in the applicant corporation:
All newly added individuals with 10% or more interest must complete a Personal History Summary and/or Cannabis Associate Security Screening form and required documents as described below.
Shareholders (individuals) holding less than 10% interest in the applicant corporation must provide their full legal name and date of birth. They do not need to provide a Personal History Summary or Cannabis Associate Security Screening form.
Provide the updated Notice of Articles for your corporation. Alternatively, you can provide list of all current directors/officers by full legal name, position and date of appointment.
To be completed when a person holding an interest in a licence has legally changed their name.
| Person's Name: |
|
|
| Name changed to: |
|
|
To be completed when a corporation with an interest in a licence has legally changed its name, but existing corporate shareholders, directors and officers, and certificate number on the certificate of incorporation have not changed. The fee is 20 per licence.
To be completed when the legal name of a partnership is changed but no new partners are added and no existing partners.
If the partnership is registered, upload a copy of the Partnership Registration document from the BC Registrar of Companies showing the change of name. If the partnership is not registered, provide a legal document showing change of name.
To be completed when the legal name of a society is changed, but the society structrure, membership and certification number on the certificate of incorporation does not change.
To be completed upon the death, bankruptcy or receivership of a licensee. Fill out A or B and attach the required documents.
Note: The Branch may renew the licence with the name of the executor, administrator or successor appended, for a period of one year. By the end of the one-year renewal period, relevant applications (e.g. transfer of ownership or transfer of shares) and appropriate documentation must be submitted to the Branch.
Upload a copy of Assignment of Executor or a copy of the last will(s) and testament(s):
Upload a copy of the Death Certificate:
Upload a copy of Court Order appointing Receiver
(Order must include authority to operate the licensee's business and must specify the licence number(s)).
Upload a copy of Court Order filed under the Office of the Superintendent of Bankruptcy Canada.
The application must only be submitted by an individual with the authority to bind the applicant. The branch relies on the applicant to ensure that the individual who submits this application is authorized to do so. Typically, an appropriate individual in a corporation will be a duly authorized signatory who will usually be an officer or, in some cases, a director.
Note: A lawyer or consultant, may NOT submit this application on behalf of the applicant.


|
For the above animation: inspiration; Go source; flash version. Want 8 Gophers? See: JS; flash.  The Haxe compiler then generates equivalent code for JavaScript, ActionScript, C++, Java, C#, PHP or Neko. The objective of the project is to save time and energy by enabling transpilations of the same Go code to form part of an application written in any of these target languages. On the client-side, using Haxe libraries like OpenFL allows Go to be deployed on a very wide range of platforms, including iOS, Android, Windows, Mac, Linux, HTML5 (example at the top of this page) and Flash. Micro FAQ:
|
Box the gopher!Interactive mouse-tracking example:plays a sound when you put the gopher in the box (except on Safari or IE). |
Elliott's talk featured on the official Go blog:
Go talks at FOSDEM 2014;
and a celebrity endorsement:
Bradfitz's kind words about the project on Reddit.


Level
Shields
Health
Armor
Base
Type
Shield
Proto Shield
Shield
Proto Shield
Shield
Proto Shield
or
Load
--select--
Effective
Spreadsheet version of Enemy calculator
Home
| Enemy Scaler |
notes


What I'm Reading | 2016-06-05 - 2016-06-11
The Obama Doctrine - Jeffrey Goldberg
-
“The world is ever-shrinking,” he said. “Withdrawal is untenable.” The other boxes he labeled realism, liberal interventionism, and internationalism. “I suppose you could call me a realist in believing we can’t, at any given moment, relieve all the world’s misery,” he said. “We have to choose where we can make a real impact.
-
the Israeli prime minister launched into something of a lecture about the dangers of the brutal region in which he lives, and Obama felt that Netanyahu was behaving in a condescending fashion, and was also avoiding the subject at hand: peace negotiations. Finally, the president interrupted the prime minister: “Bibi, you have to understand something,” he said. “I’m the African American son of a single mother, and I live here, in this house. I live in the White House. I managed to get elected president of the United States. You think I don’t understand what you’re talking about, but I do.
-
“It is literally in my DNA to be suspicious of tribalism.”
-
Obama has come to a number of dovetailing conclusions about the world, and about America’s role in it. The first is that the Middle East is no longer terribly important to American interests. The second is that even if the Middle East were surpassingly important, there would still be little an American president could do to make it a better place. The third is that the innate American desire to fix the sorts of problems that manifest themselves most drastically in the Middle East inevitably leads to warfare, to the deaths of U.S. soldiers, and to the eventual hemorrhaging of U.S. credibility and power. The fourth is that the world cannot afford to see the diminishment of U.S. power.
The Machiavelli of Maryland - Thomas Meaney
-
“I believe that one ought to have only as much market efficiency as one needs,” Luttwak told Robin. “Because everything that we value in human life is within the realm of inefficiency – love, family, attachment, community, culture, old habits, comfortable old shoes.”
-
As a historian of the ancient world, he is too alive to the prospect of civilisational ruin to put any faith in the idea that capitalism contains its own solution.
-
In the Italian port city of Bari, Luttwak says his work included helping the police fight off the local mafia, who were helping Albanian smugglers deliver rafts that included al-Qaida operatives onto the country’s shores.
The Empty Brain - Robert Epstein
-
here is what we are not born with: information, data, rules, software, knowledge, lexicons, representations, algorithms, programs, models, memories, images, processors, subroutines, encoders, decoders, symbols, or buffers – design elements that allow digital computers to behave somewhat intelligently. Not only are we not born with such things, we also don’t develop them – ever.
-
The faulty logic of the IP metaphor is easy enough to state. It is based on a faulty syllogism – one with two reasonable premises and a faulty conclusion. Reasonable premise #1: all computers are capable of behaving intelligently. Reasonable premise #2: all computers are information processors. Faulty conclusion: all entities that are capable of behaving intelligently are information processors.
-
even if we had the ability to take a snapshot of all of the brain’s 86 billion neurons and then to simulate the state of those neurons in a computer, that vast pattern would mean nothing outside the body of the brain that produced it. This is perhaps the most egregious way in which the IP metaphor has distorted our thinking about human functioning. Whereas computers do store exact copies of data – copies that can persist unchanged for long periods of time, even if the power has been turned off – the brain maintains our intellect only as long as it remains alive.
-
We are organisms, not computers. Get over it. Let’s get on with the business of trying to understand ourselves, but without being encumbered by unnecessary intellectual baggage.
Security and the Null Hypothesis - Aaron Bedra
-
One of the most important questions you can ask of your security leadership is of their understanding and pursuit of normal. If they can talk about their approach to this or better yet, show you, then you are on the right track. If you get silence and strange looks, it’s time to press harder.
-
Successful logins, Failed logins, Time of login event, Location of the login (geographic) Device (if possible). Collecting these data points gives us a way to understand normal. Defining normal includes answering questions like “when do my users login?”, “are there times when they don’t or shouldn’t?”, and “do I have users that typically mistype their password?”.


i'm a biomedical engineer , graduated from yarmouk university at february 2019 , i have training and work in different companies , first , i was traning in semiens copmany , it was a great chanse , i worked in different medical devices like CT , MRI , X-RAY , PET ,SPECT , and another devises , another copmany called Al-Asalh , is a bad time with this company , another think , i love madrid soo much , and i need to travel to germany to live and work in this country
The companies I worked with :
- extynsya
- crestell
- abdellhadi alhaj
i have some goals


You should know what’s being cooked in the kitchen otherwise you might eat a forbidden food.
~ Afrikan Proverb


Abstract
Objective This study presents the cultural and linguistic adaptation and psychometric properties of the Argentine version of the Quality of Life in Epilepsy Inventory (QOLIE-31P) scale.
Methods An instrumental study was carried out. A version of QOLIE-31P translated into Spanish was provided by the original authors. To assess the content validity, evaluation of expert judges was requested, and the degree of agreement was determined. The instrument was administered to 212 people with epilepsy (PWE) of Argentina, together with the BDI-II, B-IPQ and a sociodemographic questionnaire. A descriptive analysis of the sample was carried out. Discriminative capacity of the items was performed. Cronbach's alpha was calculated to assess reliability. To study the dimensional structure of the instrument, a confirmatory factorial analysis (CFA) was performed. Convergent and discriminant validity was tested through mean difference tests, linear correlation, and regression analysis.
Results Aiken's V coefficients ranged between .90 and 1 (acceptable), which allows to state that a conceptually and linguistically equivalent version of the QOLIE-31P was reached. Cronbach's Alpha of 0.94 was obtained for the Total Scale (optimal). As a result of CFA, 7 factors were obtained, being the dimensional structure similar to the original version. Also, unemployed PWE reported significant lower scores than employed PWE. Finally, QOLIE-31P scores negatively correlated with depression symptom severity and negative illness perception.
Conclusion The Argentine version of the QOLIE-31P is a valid and reliable instrument, presenting good psychometric properties, such as high internal consistency and a dimensional structure similar to that of the original version.
download it here.


With the implementation of the explicit-control evaluator we come to the end of a development, begun in chapter 1, in which we have explored successively more precise models of the evaluation process. We started with the relatively informal substitution model, then extended this in chapter 3 to the environment model, which enabled us to deal with state and change. In the metacircular evaluator of chapter 4, we used Scheme itself as a language for making more explicit the environment structure constructed during evaluation of an expression. Now, with register machines, we have taken a close look at the evaluator's mechanisms for storage management, argument passing, and control. At each new level of description, we have had to raise issues and resolve ambiguities that were not apparent at the previous, less precise treatment of evaluation. To understand the behavior of the explicit-control evaluator, we can simulate it and monitor its performance.
We will install a driver loop in our evaluator machine. This plays the role of the driver_loop function of section \ref{sec:running-eval}. The evaluator will repeatedly print a prompt, read an expression, evaluate the expression by going to eval_dispatch, and print the result. The following instructions form the beginning of the explicit-control evaluator's controller sequence:[1]
"read_eval_print_loop", perform(op("initialize_stack")), perform(op("prompt_for_input"), const("/// EC_Eval input:")), assign("exp", op("read")), assign("env", op("get_global_environment")), assign("continue", label("print_result")), go_to(label("eval_dispatch")), "print_result", perform(op("announce_output"), const(";;; EC_Eval value:")), perform(op("user_print"), reg("val")), go_to(label("read_eval_print_loop")),
When we encounter an error in a
function
(such as the unknown
function
type error
indicated at apply_dispatch), we print an
error message and return to the driver loop.[2]
"unknown_expression_type", assign("val", const("unknown_expression_type_error")), go_to(label("signal_error")), "unknown_procedure_type", restore("continue"), /// clean up stack (from apply_dispatch) assign(val(const("unknown_procedure_type_error"))), go_to(label("signal_error")), "signal_error", perform(op("user_print"), reg("val")), go_to(label("read_eval_print_loop")),
For the purposes of the simulation, we initialize the stack each time through the driver loop, since it might not be empty after an error (such as an undefined variable) interrupts an evaluation.[3]
If we combine all the code fragments presented in sections \ref{sec:eceval-core}–\ref{sec:running-evaluator}, we can create an evaluator machine model that we can run using the register-machine simulator of section \ref{sec:simulator}.
function eceval() { return make_machine(list("exp", "env", "val", "proc", "argl", "continue", "unev"), eceval_operations, list(read_eval_print_loop, ... /* entire machine controller as given above */ )); }
We must define Scheme functions to simulate the operations used as primitives by the evaluator. These are the same functions we used for the metacircular evaluator in section \ref{sec:mc-eval}, together with the few additional ones defined in footnotes throughout section \ref{sec:eceval}.
const eceval_operations = list(list("is_self_evaluating", is_self_evaluating), ... /* complete list of operations for eceval machine */ );
Finally, we can initialize the global environment and run the evaluator:
const the_global_environment = setup_environment(); start(eceval);
Of course, evaluating expressions in this way will take much longer than if we had directly typed them into Scheme, because of the multiple levels of simulation involved. Our expressions are evaluated by the explicit-control-evaluator machine, which is being simulated by a Scheme program, which is itself being evaluated by the Scheme interpreter.
Simulation can be a powerful tool to guide the implementation of evaluators. Simulations make it easy not only to explore variations of the register-machine design but also to monitor the performance of the simulated evaluator. For example, one important factor in performance is how efficiently the evaluator uses the stack. We can observe the number of stack operations required to evaluate various expressions by defining the evaluator register machine with the version of the simulator that collects statistics on stack use (section \ref{sec:monitor}), and adding an instruction at the evaluator's print_result entry point to print the statistics:
Interactions with the evaluator now look like this:
/// EC-Eval input: function factorial (n) { return n === 1 ? 1 n * factorial(n - 1); } (total-pushes = 3 maximum-depth = 3) /// EC-Eval value: ok /// EC-Eval input: factorial(5); (total-pushes = 144 maximum-depth = 28) /// EC-Eval value: 120
Note that the driver loop of the evaluator reinitializes the stack at the start of each interaction, so that the statistics printed will refer only to stack operations used to evaluate the previous expression.
function factorial(n) { function iter(product, counter, max_count) { return counter > max_count ? product : fact_iter(counter * product, counter + 1, max_count); } return iter(1, 1, n); }
function factorial(n) { return n === 1 ? 1 : n * factorial(n - 1); }
function fib(n) { return n < 2 ? n : fib(n - 1) + fib(n - 2); }
overheadconstant $k$ that is independent of $n$. Give the formula, and say what $k$ is. Then show that $S(n)$ can be expressed as $a {\textrm{Fib}}(n+1) + b$ and give the values of $a$ and $b$. } \end{enumerate} \end{Exercise} \stepcounter{ExerciseDisplayNumber} \begin{Exercise} Our evaluator currently catches and signals only two kinds of errors—unknown expression types and unknown function types. Other errors will take us out of the evaluator read-eval-print loop. When we run the evaluator using the register-machine simulator, these errors are caught by the underlying Scheme system. This is analogous to the computer crashing when a user program makes an error.[4] It is a large project to make a real error system work, but it is well worth the effort to understand what is involved here. \begin{enumerate}[a.] \item{ Errors that occur in the evaluation process, such as an attempt to access an unbound variable, could be caught by changing the lookup operation to make it return a distinguished condition code, which cannot be a possible value of any user variable. The evaluator can test for this condition code and then do what is necessary to go to signal-error. Find all of the places in the evaluator where such a change is necessary and fix them. This is lots of work. } \item{ Much worse is the problem of handling errors that are signaled by applying primitive functions, such as an attempt to divide by zero or an attempt to extract the head of a symbol. In a professionally written high-quality system, each primitive application is checked for safety as part of the primitive. For example, every call to head could first check that the argument is a pair. If the argument is not a pair, the application would return a distinguished condition code to the evaluator, which would then report the failure. We could arrange for this in our register-machine simulator by making each primitive function check for applicability and returning an appropriate distinguished condition code on failure. Then the primitive-apply code in the evaluator can check for the condition code and go to signal-error if necessary. Build this structure and make it work. This is a major project. } \end{enumerate} \end{Exercise}
We assume here that read and the various printing operations are available as primitive machine operations, which is useful for our simulation, but completely unrealistic in practice. These are actually extremely complex operations. In practice, they would be implemented using low-level input-output operations such as transferring single characters to and from a device.
dumps core,and in DOS/Windows$^{\textrm{TM}}$ it becomes catatonic. The Macintosh$^{\textrm{TM}}$ displays a picture of an exploding bomb and offers you the opportunity to reboot the computer—if you're lucky.