Table of Contents
Without using Atomik, one way of doing things would have been to create a file per page. The page logic (i.e. connecting to a database, handling form data...) would have been at the top of the file followed by the HTML.
Example 7.1. A php script, the old way
<?php
if (count($_POST)) {
echo 'Form data received!';
}
?>
<form>
<input type="text" name="data" />
<input type="submit" value="send" />
</form>
This is BAD!! The application logic and the presentation layer should always be separated.
Now let's imagine that rather than directly doing both part in the same file we split it. We would have three file: one with the logic, one with the HTML and one that include both.
Example 7.2. Splitting into multiple files
page_logic.php
<?php
if (count($_POST)) {
echo 'Form data received!';
}
page_html.php
<form> <input type="text" name="data" /> <input type="submit" value="send" /> </form>
page.php
<?php include 'page_logic.php'; include 'page_html.php';
Now replace the third file (the one with the includes) with Atomik and you'll have the concept behind Atomik. The logic script is named an action and the html a view.
Actions are stored in the app/actions directory. Both the action and the
view filename must be the same. Action files must have the “php” extension.
If the action or view filename starts with an underscore, the action won't be accessible using an url.
There are no requirements for the content of an action file. It can be anything you want. So you just do your logic as you used to.
Variables declared in the action are forwarded to the view. If you want to keep some variables private (i.e. which will only be available in your action) prefixed them with an underscore.
Example 7.3. Private variables in actions
<?php $myPublicVariable = 'value'; $_myPrivateVariable = 'secret';
You shouldn't use echo or write any HTML code inside an action.
As said before, the goal of an action is to separate the logic from the presentation.
If you would like to exit the application, avoid using exit() and prefer
Atomik::end() so Atomik can smoothly exit your application.
You can use folders to organize your actions. In this case, views must follow the same
directory structure. You can create an “index” action (index.php)
inside a folder and it will be use as the folder's default page. Views follow the same principle.
Example 7.4. Actions and folders
app/actions/users.php <- will be used if url = /users app/actions/users/index.php <- will be used if url = /users AND if app/actions/users.php does not exist app/actions/users/messages.php <- will be used if url = /users/messages whatever the default page is
Atomik allows you to create multiple files for one action, each of them targeting a specific HTTP method. This enables RESTful websites to be build.
Method specific action files must be suffixed with the method name. So for example, if you have
a “user” action and you would like to target the POST method, you would create a
file named user.post.php. With the PUT method it would have been
user.put.php. These files must be located in the actions folder.
You can still create a global action file (in the previous example: user.php)
which will be executed before any method specific action. Variables from the global action are
available in the specific one.
The current http method is available in the “app/http_method” configuration key.
Allowed HTTP methods are defined in “app/allowed_http_methods”. By default, all methods available in the protocol are listed but you may want to reduce that list.
Some clients does not handle well HTTP methods (Flex for example...). Thus, it is possible to override the request's method using a route parameter (which can be a GET parameter). The default parameter name is “_method”. This can be changed in “app/http_method_param”. It can also be disabled by setting false instead of a string.
Since Atomik 2.2, you can use classes in your action files. This allow for complex actions to be better organized.
When executing your action, Atomik will check if a class named “{actionName}Action”
exists. If it does and has a static method called execute(), it will call it.
Example 7.5. Using a class in your action
In an action file named index.php.
class IndexAction
{
public static function execute()
{
}
}
If your action file is located in a sub folder, the class name must follow the PEAR convention.
If the action is targeting a specific HTTP method, the method name should be appended before the Action keyword in the class name.
Example 7.6. Using a class in an action located in a sub folder or targeting an HTTP method
In an action file located at users/list.php, the class name would be
Users_ListAction.
If the action is targeting the POST method, the class name would be
Users_ListPostAction.
To define view variables, you have two possibilities. Atomik will automatically make available
all the public static class properties (unless they start with an underscore).
The execute() method can also return an array of key/value paris that will
be available as variables in the view.
Example 7.7. Setting view variables with action classes
class IndexAction
{
public static $foo = 'foo';
public static function execute()
{
return array('bar' => 'bar');
}
}
$foo and $bar will be available into the view.
When executing a request, the action and/or the view associated to it are automatically called. You can however call other actions using Atomik's API.
To execute an action use the Atomik::execute() method. It takes
as first argument the action name.
By default, if a view with the same name is found, it is rendered and the return value
of the execute() method is the view output.
If no view is found, an empty string is returned. If false is used as second argument,
the return value is an array containing all “public” variables from the action.
Example 7.8. Calling an action programmatically
$viewOutput = Atomik::execute('myAction');
$variables = Atomik::execute('myAction', false);
Calling an action using Atomik::execute() does not mean an action file
must exist. However, in this case, a view file with the same name must exists. Otherwise,
false is returned.
Actions executed this way will also be influenced by the HTTP method. You can specify a specific method by appendinf it to the action name. The global action will also be executed.
Example 7.9. Calling an action for a specific method programmatically
$viewOutput = Atomik::execute('myAction.post');