## Getting Started

Composer has become the de facto standard for installing libraries in the php world. Aura does the same.

### Installation

There are 3 types of skeletons

• aura/web-project : only web application, no cli support built in.
• aura/cli-project : only for command line applications.
• aura/framework-project : supports both web and cli

We are going to install aura/framework-project, so we can show command line examples also.

### Config File Location

Project-level configuration files are located in the project-level config/ directory. Each configuration file is a class that extends Aura\Di\Config, and represents a configuration mode. Each configuration class has two methods:

• define(), which allows you to define params, setters, and services in the project Container; and
• modify(), which allows you to pull objects out of the Container for programmatic modification. (This happens after the Container is locked, so you cannot add new services or change params and setters here.)

The two-stage configuration system loads all the configuration classes in order by library, kernel, and project, then runs all the define() methods, locks the container, and finally runs all the modify() methods.

### Mapping Config Modes To Classes

The config modes are mapped to their related config class files via the project-level composer.json file in the extra:aura:config block. The entry key is the config mode, and the entry value is the class to use for that mode.

Config classes are autoloaded via a PSR-4 entry for that project namespace.

The “common” config class is always loaded regardless of the actual config mode. For example, if the config mode is dev, first the Common class is loaded, and then the Dev class.

### Changing Config Settings

First, open the config file for the related config mode. To change configuration params, setters, and services, edit the define() method. To programmatically change a service after all definitions are complete, edit the modify() method.

If you want to add a new configuration mode, say qa, you need to do three things.

First, create a config class for it in config/:

Next, edit the project-level composer.json file to add the new config mode with its related class:

Finally, run composer update so that Composer makes the necessary changes to the autoloader system.

## Routing

Configuration of routing and dispatching is done via the project-level config/ class files. If a route needs to be available in every config mode, edit the project-level config/Common.php class file. If it only needs to be available in a specific mode, e.g. dev, then edit the config file for that mode (config/Dev.php).

The modify() method is where we get the router service (‘aura/web-kernel:router’) and add routes to the application.

The aura/web-kernel:router is an object of type Aura\Router\Router . So if you are familiar with Aura.Router then you are done with this chapter, else read on.

Aura framework can act both as a micro framework or full stack framework. If you are using it as a micro framework, you can set a Closure as the action value, else set the same name of the action in the dispatcher. Don’t worry, we will cover dispatching in next chapter.

Note: This chapter gives you a basic understanding of the different types of methods available in router.

We will not be showing the whole config file to reduce the space used. This document assumes you are adding the route in the modify() method after getting the router service.

To create a route, call the add() method on the Router. Named path-info params are placed inside braces in the path.

You can create a route that matches only against a particular HTTP method as well. The following Router methods are identical to add() but require the related HTTP method:

• $router->addGet() • $router->addDelete()
• $router->addOption() • $router->addPatch()
• $router->addPost() • $router->addPut()

### Extended Route Specification

You can extend a route specification with the following methods:

• addTokens() – Adds regular expression subpatterns that params must match.

Note that setTokens() is also available, but this will replace any previous subpatterns entirely, instead of merging with the existing subpatterns.

• addServer() – Adds regular expressions that server values must match.

Note that setServer() is also available, but this will replace any previous expressions entirely, instead of merging with the existing expressions.

• addValues() – Adds default values for the params.

Note that setValues() is also available, but this will replace any previous default values entirely, instead of merging with the existing default value.

• setSecure() – When true the $server['HTTPS'] value must be on, or the request must be on port 443; when false, neither of those must be in place. • setWildcard() – Sets the name of a wildcard param; this is where arbitrary slash-separated values appearing after the route path will be stored. • setRoutable() – When false the route will be used only for generating paths, not for matching (true by default). • setIsMatchCallable() – A custom callable with the signature function(array$server, \ArrayObject $matches) that returns true on a match, or false if not. This allows developers to build any kind of matching logic for the route, and to change the $matches for param values from the path.
• setGenerateCallable() – A custom callable with the signature function(\ArrayObject $data). This allows developers to modify the data for path interpolation. Here is a full extended route specification named read: ### Default Route Specifications You can set the default route specifications with the following Router methods; the values will apply to all routes added thereafter. ### Simple Routes You don’t need to specify an extended route specification. With the following simple route … … the Router will use a default subpattern that matches everything except slashes for the path params. Thus, the above simple route is equivalent to the following extended route: ### Automatic Params The Router will automatically populate values for the action route param if one is not set manually. ### Optional Params Sometimes it is useful to have a route with optional named params. None, some, or all of the optional params may be present, and the route will still match. To specify optional params, use the notation {/param1,param2,param3} in the path. For example: With that, the following routes will all match the ‘archive’ route, and will set the appropriate values: Optional params are sequentially optional. This means that, in the above example, you cannot have a “day” without a “month”, and you cannot have a “month” without a “year”. Only one set of optional params per path is recognized by the Router. Optional params belong at the end of a route path; placing them elsewhere may result in unexpected behavior. ### Wildcard Params Sometimes it is useful to allow the trailing part of the path be anything at all. To allow arbitrary trailing params on a route, extend the route definition with setWildcard() to specify param name under which the arbitrary trailing param values will be stored. ### Attaching Route Groups You can add a series of routes all at once under a single “mount point” in your application. For example, if you want all your blog-related routes to be mounted at /blog in your application, you can do this: Each of the route names will be prefixed with ‘blog.’, and each of the route paths will be prefixed with /blog, so the effective route names and paths become: • blog.browse => /blog{format} • blog.read => /blog/{id}{format} • blog.edit => /blog/{id}/edit{format} You can set other route specification values as part of the attachment specification; these will be used as the defaults for each attached route, so you don’t need to repeat common information. (Setting these values will not affect routes outside the attached group.) ### Attaching REST Resource Routes The router can attach a series of REST resource routes for you with the attachResource() method: That method call will result in the following routes being added: Route Name HTTP Method Route Path Purpose blog.browse GET /blog{format} Browse multiple resources blog.read GET /blog/{id}{format} Read a single resource blog.edit GET /blog/{id}/edit The form for editing a resource blog.add GET /blog/add The form for adding a resource blog.delete DELETE /blog/{id} Delete a single resource blog.create POST /blog Create a new resource blog.update PATCH /blog/{id} Update part of an existing resource blog.replace PUT /blog/{id} Replace an entire existing resource The {id} token is whatever has already been defined in the router; if not already defined, it will be any series of numeric digits. Likewise, the {format} token is whatever has already been defined in the router; if not already defined, it is an optional dot-format file extension (including the dot itself). The action value is the same as the route name. If you want calls to attachResource() to create a different series of REST routes, use the setResourceCallable() method to set your own callable to create them. The example will cause only four CRUD routes, using hexadecimal resource IDs, to be added for the resource when you call attachResource(). ## Dispatching Aura web/framework projects can handle different variations of dispatching with the help of Aura.Dispatcher. So if your application starts small and grows, it is easy to modify the application routes acting as a micro framework to a full-stack style. ### Microframework The following is an example of a micro-framework style route, where the action logic is embedded in the route params. In the modify() config method, we retrieve the shared aura/web-kernel:request and aura/web-kernel:response services, along with the aura/web-kernel:router service. We then add a route names blog.read and embed the action code as a closure. ### Modified Micro-Framework Style We can modify the above example to put the action logic in the dispatcher instead of the route itself. Extract the action closure to the dispatcher under the name blog.read. Then, in the route, use a action value that matches the name in the dispatcher. ### Full-Stack Style You can migrate from a micro-framework style to a full-stack style (or start with full-stack style in the first place). First, define a action class and place it in the project src/ directory. Next, tell the project how to build the BlogRead through the DI Container. Edit the project config/Common.php file to configure the Container to pass the aura/web-kernel:request and aura/web-kernel:response service objects to the BlogRead constructor. After that, put the App\Actions\BlogRead object in the dispatcher under the name blog.read as a lazy-loaded instantiation … … and finally, point the router to the blog.read action object: ## Request The Request object describes the current web execution context for PHP. Note that it is not an HTTP request object proper, since it includes things like $_ENV and various non-HTTP $_SERVER keys. You can get the Request object from the DI, The Request object contains several property objects. Some represent a copy of the PHP superglobals … • $request->cookies for $_COOKIES • $request->env for $_ENV • $request->files for $_FILES • $request->post for $_POST • $request->query for $_GET • $request->server for $_SERVER … and others represent more specific kinds of information about the request: • $request->client for the client making the request
• $request->content for the raw body of the request • $request->headers for the request headers
• $request->method for the request method • $request->accept for content negotiation
• $request->params for path-info parameters • $request->url for the request URL

The Request object has only one method, isXhr(), to indicate if the request is an XmlHttpRequest or not.

### Superglobals

Each of the superglobal representation objects has a single method, get(), that returns the value of a key in the superglobal, or an alternative value if the key is not present. The values here are read-only.

### Client

The $request->client object has these methods: • getForwardedFor() returns the values of the X-Forwarded-For headers as an array. • getReferer() returns the value of the Referer header. • getIp() returns the value of $_SEVER['REMOTE_ADDR'], or the appropriate value of X-Forwarded-For.
• getUserAgent() return the value of the User-Agent header.
• isCrawler() returns true if the User-Agent header matches one of a list of bot/crawler/robot user agents (otherwise false).
• isMobile() returns true if the User-Agent header matches one of a list of mobile user agents (otherwise false).

The $request->method object has these methods: • get(): returns the request method value • isDelete(): Did the request use a DELETE method? • isGet(): Did the request use a GET method? • isHead(): Did the request use a HEAD method? • isOptions(): Did the request use an OPTIONS method? • isPatch(): Did the request use a PATCH method? • isPut(): Did the request use a PUT method? • isPost(): Did the request use a POST method? You can also call is*() on the Method object; the part after is is treated as custom HTTP method name, and checks if the request was made using that HTTP method. Sometimes forms use a special field to indicate a custom HTTP method on a POST. By default, the Method object honors the _method form field. ### Params Unlike most Request property objects, the Params object is read-write (not read-only). The Params object allows you to set application-specific parameter values. These are typically discovered by parsing a URL path through a router of some sort (e.g. Aura.Router). The $request->params object has two methods:

• set() to set the array of parameters
• get() to get back a specific parameter, or the array of all parameters

For example:

The $request->url object has two methods: • get() returns the full URL string; or, if a component constant is passed, returns only that part of the URL • isSecure() indicates if the request is secure, whether via SSL, TLS, or forwarded from a secure protocol ## Response The Response object describes the web response that should be sent to the client. It is not an HTTP response object proper. Instead, it is a series of hints to be used when building the HTTP response with the delivery mechanism of your choice. Setting values on the Response object does not cause values to be sent to the client. The Response can be inspected during testing to see if the correct values have been set without generating output. You can get the Response object from the DI, The Response object is composed of several property objects representing different parts of the response: • $response->status for the status code, status phrase, and HTTP version
• $response->headers for non-cookie headers • $response->cookies for cookie headers
• $response->content for describing the response content, and for convenience methods related to content type, charset, disposition, and filename • $response->cache for convenience methods related to cache headers

The $response->headers object has these methods: • set() to set a single header, resetting previous values on that header • get() to get a single header, or to get all headers Setting a header value to null, false, or an empty string will remove that header; setting it to zero will not remove it. ### Cookies The $response->cookies object has these methods:

• setExpire() sets the default expiration for cookies
• setPath() sets the default path for cookies
• setDomain() sets the default domain for cookies
• setSecure() sets the default secure value for cookies
• setHttpOnly() sets the default for whether or not cookies will be sent by HTTP only.
• set() sets a cookie name and value along with its meta-data. This method mimics the setcookie() PHP function. If meta- data such as path, domain, secure, and httponly are missing, the defaults will be filled in for you.
• get() returns a cookie by name, or all the cookies at once.

The cookie descriptor array looks like this:

The $response->content object has these convenience methods related to the response content and content headers: • set() sets the body content of the response (this can be anything at all, including an array, a callable, an object, or a string – it is up to the sending mechanism to translate it properly) • get() get the body content of the response which has been set via set() • setType() sets the Content-Type header • getType() returns the Content-Type (not including the charset) • setCharset() sets the character set for the Content-Type • getCharset() returns the charset portion of the Content-Type header • setDisposition() sets the Content-Disposition type and filename • setEncoding() sets the Content-Encoding header ### Cache The $response->cache object has several convenience methods related to HTTP cache headers.

• reset() removes all cache-related headers
• disable() turns off caching by removing all cache-related headers, then sets the following:
• setAge() sets the Age header value in seconds
• setControl() sets an array of Cache-Control header directives all at once; alternatively, use the individual directive methods:
• setPublic() and setPrivate() set the public and private cache control directives (each turns off the other)
• setMaxAge() and setSharedMaxAge() set the max-age and s-maxage cache control directives (set to null or false to remove them)
• setNoCache() and setNoStore() set the no-cache and no-store cache control directives (set to null or false to remove them)
• setMustRevalidate() and setProxyRevalidate() to set the must-revalidate and proxy-revalidate directives (set to null or false to remove them)
• setEtag() and setWeakEtag() set the ETag header value
• setExpires() sets the Expires header value; will convert recognizable date formats and DateTime objects to a correctly formatted HTTP date
• setLastModified() sets the Last-Modified header value; will convert recognizable date formats and DateTime objects to a correctly formatted HTTP date
• setVary() sets the Vary header; pass an array for comma-separated values

The $response->redirect object has several convenience methods related to status and Location headers for redirection. • to($location, $code = 302, phrase = null) sets the status and headers for redirection to an arbitrary location with an arbitrary status code and phrase • afterPost($location) redirects to the $location with a 303 See Other status; this automatically disables HTTP caching • created($location) redirects to $location with 201 Created • movedPermanently($location) redirects to $location with 301 Moved Permanently • found($location) redirects to $location with 302 Found • seeOther($location) redirects to $location with 303 See Other; this automatically disables HTTP caching • temporaryRedirect($location) redirects to $location with 307 Temporary Redirect • permanentRedirect($location) redirects to $location with 308 Permanent Redirect ## Dependency Injection Aura.Di is a dependency injection container system with the following features: • constructor and setter injection • explicit and implicit auto-resolution of typehinted constructor parameter values • configuration of setters across interfaces and traits • inheritance of constructor parameter and setter method values • lazy-loaded services, values, and instances • instance factories We will concentrate on constructor and setter injection in this chapter for easiness. It is recommend you should read Aura.Di documentation ### Setting And Getting Services A “service” is an object stored in the Container under a unique name. Any time you get() the named service, you always get back the same object instance. That usage is great if we want to create the Example instance at the same time we set the service. However, we generally want to create the service instance at the moment we get it, not at the moment we set it. The technique of delaying instantiation until get() time is called “lazy loading.” To lazy-load an instance, use the lazyNew() method on the Container and give it the class name to be created: Now the service is created only when we we get() it, and not before. This lets us set as many services as we want, but only incur the overhead of creating the instances we actually use. ### Constructor Injection When we use the Container to instantiate a new object, we often need to inject (i.e., set) constructor parameter values in various ways. ### Default Parameter Values We can define default values for constructor parameters using the $di->params array on the Container.

Let’s look at a class that takes some constructor parameters:

If we were to try to set a service using $di->lazyNew('ExampleWithParams'), the instantiation would fail. The $foo param is required, and the Container does not know what to use for that value.

To remedy this, we tell the Container what values to use for each ExampleWithParams constructor parameter by name using the $di->params array: Now when a service is defined with $di->lazyNew('ExampleWithParams'), the instantiation will work correctly. Each time we create an ExampleWithParams instance through the Container, it will apply the $di->params['ExampleWithParams'] values. ### Instance-Specific Parameter Values If we want to override the default $di->params values for a specific new instance, we can pass a $params array as the second argument to lazyNew() to merge with the default values. For example: This will leave the $foo parameter default in place, and override the $bar parameter value, for just that instance of the ExampleWithParams. ### Lazy-Loaded Services As Parameter Values Sometimes a class will need another service as one of its parameters. By way of example, the following class needs a database connection: To inject a shared service as a parameter value, use $di->lazyGet() so that the service object is not created until the ExampleNeedsService object is created:

This keeps the service from being created until the very moment it is needed. If we never instantiate anything that needs the service, the service itself will never be instantiated.

### Setter Injection

This package supports setter injection in addition to constructor injection. (These can be combined as needed.)

## View

Aura web framework doesn’t come packaged with any templating. The reason is love for templating differs from person to person.

With the help of foa/responder-bundle, we can integrate

The advantage of using foa/responder-bundle is you have a common method render, which helps you to switch between template engine with less overhead.

It also helps integrating the Action Domain Responder which we will cover on a different chapter.

### Installation

Choose your templating engine and install the same. In this example we are going to make use of foa/html-view-bundle which integrates aura/view and aura/html.

### Configuration

Add the below lines in {PROJECT_PATH}/config/Common.php in the define method.

Setting the paths to Aura\View\TemplateRegistry will only work for version >= 2.1

### Integration with actions

Let us integrate the above renderer to the full stack framework example shown in previous chapter.

### Validating User Input

You can validate the form via the filter() method.

### Rendering

Inorder to render the form, we need to pass the ContactForm object and use the Aura.Html helpers.

Assuming you have passed the ContactForm object, and the variable assigned is contact_form you can use the get method on the form object to get the hints of field, and pass to input helper.

An example is given below :

Read more on form helpers here.

In the session chapter we will learn how to set flash message when the form submission was success.

## Validation

Aura.Filter is a tool to validate and sanitize data.

We are going to look into version 1 of Aura.Filter.

### Installation

We have already installed aura/filter in the previous chapter about forms. If you have not installed please do the same.

### Applying Rules to Data Objects

#### Soft, Hard, and Stop Rules

There are three types of rule processing we can apply:

• The addSoftRule() method adds a soft rule: if the rule fails, the filter will keep applying all remaining rules to that field and all other fields.
• The addHardRule() method adds a hard rule: if the rule fails, the filter will not apply any more rules to that field, but it will keep filtering other fields.
• The addStopRule() method adds a stopping rule: if the rule fails, the filter will not apply any more filters to any more fields; this stops all filtering on the data object.

### Validating and Sanitizing

We validate data by applying a rule with one of the following requirements:

• RuleCollection::IS means the field value must match the rule.
• RuleCollection::IS_NOT means the field value must not match the rule.
• RuleCollection::IS_BLANK_OR means the field value must either be blank, or match the rule. This is useful for optional field values that may or may not be filled in.

We sanitize data by applying a rule with one of the following transformations:

• RuleCollection::FIX to force the field value to comply with the rule; this may forcibly transform the value. Some transformations are not possible, so sanitizing the field may result in an error message.
• RuleCollection::FIX_BLANK_OR will convert blank values to null; non-blank fields will be forced to comply with the rule. This is useful for sanitizing optional field values that may or may not match the rule.

Each field is sanitized in place; i.e., the data object property will be modified directly.

### Blank Values

Aura Filter incorporates the concept of “blank” values, as distinct from isset() and empty(). A value is blank if it is null, an empty string, or a string composed of only whitespace characters. Thus, the following are blank:

Integers, floats, booleans, and other non-strings are never counted as blank, even if they evaluate to zero:

### Available Rules

• alnum: Validate the value as alphanumeric only. Sanitize to leave only alphanumeric characters. Usage:
• alpha: Validate the value as alphabetic only. Sanitize to leave only alphabetic characters. Usage:
• between: Validate the value as being within or equal to a minimum and maximum value. Sanitize so that values lower than the range are forced up to the minimum; values higher than the range are forced down to the maximum. Usage:
• blank: Validate the value as being blank. Sanitize to null. Usage:
• bool: Validate the value as being a boolean, or a pseudo-boolean. Pseudo-true values include the strings ‘1’, ‘y’, ‘yes’, and ‘true’; pseudo-false values include the strings ‘0’, ‘n’, ‘no’, and ‘false’. Sanitize to a strict PHP boolean. Usage:
• creditCard: Validate the value as being a credit card number. The value cannot be sanitized. Usage:
• dateTime: Validate the value as representing a date and/or time. Sanitize the value to a specified format, default 'Y-m-d H:i:s'. Usage (note that this is to sanitize, not validate):
• email: Validate the value as being a properly-formed email address. The value cannot be sanitized. Usage:
• equalToField: Validate the value as loosely equal to the value of another field in the data object. Sanitize to the value of that other field. Usage:
• equalToValue: Validate the value as loosely equal to a specified value. Sanitize to the specified value. Usage:
• float: Validate the value as representing a float. Sanitize the value to transform it into a float; for weird strings, this may not be what you expect. Usage:
• inKeys: Validate that the value is loosely equal to a key in a given array. The value cannot be sanitized. Usage:
• inValues: Validate that the value is strictly equal to at least one value in a given array. The value cannot be sanitized. Usage:
• int: Validate the value as representing an integer Sanitize the value to transform it into an integer; for weird strings, this may not be what you expect. Usage:
• ipv4: Validate the value as an IPv4 address. The value cannot be sanitized. Usage:
• locale: Validate the given value against a list of locale strings. If it’s not found returns false. The value cannot be sanitized. Usage:
• max: Validate the value as being less than or equal to a maximum. Sanitize so that values higher than the maximum are forced down to the maximum. Usage:
• min: Validate the value as being greater than or equal to a minimum. Sanitize so that values lower than the minimum are forced up to the minimum. Usage:
• regex: Validate the value using preg_match(). Sanitize the value using preg_replace().
• strictEqualToField: Validate the value as strictly equal to the value of another field in the data object. Sanitize to the value of that other field. Usage:
• strictEqualToValue: Validate the value as strictly equal to a specified value. Sanitize to the specified value. Usage:
• string: Validate the value can be represented by a string. Sanitize the value by casting to a string and optionally using str_replace(). Usage (note that this is to sanitize, not validate):
• strlen: Validate the value has a specified length. Sanitize the value to cut off longer values at the right, and str_pad() shorter ones. Usage:
• strlenBetween: Validate the value length as being within or equal to a minimum and maximum value. Sanitize the value to cut off values longer than the maximum, longer values at the right, and str_pad() shorter ones. Usage:
• strlenMax: Validate the value length as being no longer than a maximum. Sanitize the value to cut off values longer than the maximum. Usage:
• strlenMin: Validate the value length as being no shorter than a minimum. Sanitize the value to str_pad() values shorter than the minimum. Usage:
• trim: Validate the value is trim()med. Sanitize the value to trim() it. Optionally specify characters to trim. Usage:
• upload: Validate the value represents a PHP upload information array, and that the file is an uploaded file. The value cannot be sanitized. Usage:
• url: Validate the value is a well-formed URL. The value cannot be sanitized. Usage:
• word: Validate the value as being composed only of word characters. Sanitize the value to remove non-word characters. Usage:
• isbn: Validate the value is a correct ISBN (International Standard Book Number). Usage:
• any: Validate the value passes at-least one of the rules. These rules are the ones added in rule locator.
• all: Validate the value against a set of rules. These rules are should be added in rule locator. You will not get seprate error messages for which all rules it failed.

### Custom Messages

By default when a rule fails, the messages you will be getting are from the intl/en_US.php. But you can also provide a single custom message for all the failures.

Example:

As you have used useFieldMessage you will see

### Creating and Using Custom Rules

There are three steps to creating and using new rules:

1. Write a rule class
2. Set that class as a service in the RuleLocator
3. Use the new rule in our filter chain

### Writing a Rule Class

Writing a rule class is straightforward:

• Extend Aura\Filter\AbstractRule with two methods: validate() and sanitize().
• Add params as needed to each method.
• Each method should return a boolean: true on success, or false on failure.
• Use getValue() to get the value being validated, and setValue() to change the value being sanitized.
• Add a property $message to indicate a string that should be translated as a message when validation or sanitizing fails. Here is an example of a hexadecimal rule: ### Set The Class As A Service Now we set the rule class into the RuleLocator. ### Apply The New Rule Finally, we can use the rule in our filter: That is all! ## Internationalization The Aura.Intl package provides internationalization (I18N) tools, specifically package-oriented per-locale message translation. ### Installation ### Service In your modify method you can get the service intl_translator_locator like ### Setting Localized Messages For A Package We can set localized messages for a package through the PackageLocator object from the translator locator. We create a new Package with messages and place it into the locator as a callable. The messages take the form of a message key and and message string. ### Setting The Default Locale We can set the default locale for translations using the setLocale() method: ### Getting A Localized Message Now that the translator locator has messages and a default locale, we can get an individual package translator. The package translator is suitable for injection into another class, or for standalone use. You will neeed to create a tanslator helper which can return the service. You can get a translator for a non-default locale as well: ### Replacing Message Tokens With Values We often need to use dynamic values in translated messages. First, the message string needs to have a token placeholder for the dynamic value: Then, when we translate the message, we provide an array of tokens and replacement values. These will be interpolated into the message string. ### Pluralized Messages Usually, we need to use different messages when a value is singular or plural. The BasicFormatter is not capable of presenting different messages based on different token values. The IntlFormatter is capable, but the PHP intl extension must be loaded to take advantage of it, and we must specify the 'intl' formatter for the package in the catalog. When using the IntlFormatter, we can build our message strings to present singular or plural messages, as in the following example: Note that you can use other tokens within a pluralized token string to build more complex messages. For more information, see the following: http://icu-project.org/apiref/icu4j/com/ibm/icu/text/MessageFormat.html ## Session Provides session management functionality, including lazy session starting, session segments, next-request-only (“flash”) values, and CSRF tools. ### Installation We are going to install aura/session. ### Service Aura.Session already have aura/session:session service which is an object of Aura\Session\Session . You can get inject the service to responder or view helper and make use of the Aura\Session\Session object. ### Segments In normal PHP, we keep session values in the $_SESSION array. However, when different libraries and projects try to modify the same keys, the resulting conflicts can result in unexpected behavior. To resolve this, we use Segment objects. Each Segment addresses a named key within the $_SESSION array for deconfliction purposes. For example, if we get a Segment for Vendor\Package\ClassName, that Segment will contain a reference to $_SESSION['Vendor\Package\ClassName']. We can then set() and get() values on the Segment, and the values will reside in an array under that reference.

The benefit of a session segment is that we can deconflict the keys in the $_SESSION superglobal by using class names (or some other unique name) for the segment names. With segments, different packages can use the $_SESSION superglobal without stepping on each other’s toes.

To clear all the values on a Segment, use the clear() method.

### Lazy Session Starting

Merely instantiating the Session manager and getting a Segment from it does not call session_start(). Instead, session_start() occurs only in certain circumstances:

• If we read from a Segment (e.g. with get()) the Session looks to see if a session cookie has already been set. If so, it will call session_start() to resume the previously-started session. If not, it knows there are no previously existing $_SESSION values, so it will not call session_start(). • If we write to a Segment (e.g. with set()) the Session will always call session_start(). This will resume a previous session if it exists, or start a new one if it does not. This means we can create each Segment at will, and session_start() will not be invoked until we actually interact with a Segment in a particular way. This helps to conserve the resources involved in starting a session. Of course, we can force a session start or reactivation by calling the Session start() method, but that defeats the purpose of lazy-loaded sessions. ### Saving, Clearing, and Destroying Sessions To save the session data and end its use during the current request, call the commit() method on the Session manager: To clear all session data, but leave the session active during the current request, use the clear() method on the Session manager. To clear all flash values on a segment, use the clearFlash() method: To clear the data and terminate the session for this and future requests, thereby destroying it completely, call the destroy() method: Calling destroy() will also delete the session cookie via setcookie(). If we have an alternative means by which we delete cookies, we should pass a callable as the second argument to the SessionFactory method newInstance(). The callable should take three parameters: the cookie name, path, and domain. ### Session Security #### Session ID Regeneration Any time a user has a change in privilege (that is, gaining or losing access rights within a system) be sure to regenerate the session ID: #### Cross-Site Request Forgery A “cross-site request forgery” is a security issue where the attacker, via malicious JavaScript or other means, issues a request in-the-blind from a client browser to a server where the user has already authenticated. The request looks valid to the server, but in fact is a forgery, since the user did not actually make the request (the malicious JavaScript did). http://en.wikipedia.org/wiki/Cross-site_request_forgery ##### Defending Against CSRF To defend against CSRF attacks, server-side logic should: 1. Place a token value unique to each authenticated user session in each form; and 2. Check that all incoming POST/PUT/DELETE (i.e., “unsafe”) requests contain that value. For this example, the form field name will be __csrf_value. In each form we want to protect against CSRF, we use the session CSRF token value for that field: When processing the request, check to see if the incoming CSRF token is valid for the authenticated user: ##### CSRF Value Generation For a CSRF token to be useful, its random value must be cryptographically secure. Using things like mt_rand() is insufficient. Aura.Session comes with a Randval class that implements a RandvalInterface, and uses either the openssl or the mcrypt extension to generate a random value. If you do not have one of these extensions installed, you will need your own random-value implementation of the RandvalInterface. We suggest a wrapper around RandomLib. ### Flash Values Segment values persist until the session is cleared or destroyed. However, sometimes it is useful to set a value that propagates only through the next request, and is then discarded. These are called “flash” values. #### Setting And Getting Flash Values To set a flash value on a Segment, use the setFlash() method. Then, in subsequent requests, we can read the flash value using getFlash(): Using setFlash() makes the flash value available only in the next request, not the current one. To make the flash value available immediately as well as in the next request, use setFlashNow($key, $val). Using getFlash() returns only the values that are available now from having been set in the previous request. To read a value that will be available in the next request, use getFlashNext($key, $alt). #### Keeping and Clearing Flash Values Sometimes we will want to keep the flash values in the current request for the next request. We can do so on a per-segment basis by calling the Segment keepFlash() method, or we can keep all flashes for all segments by calling the Session keepFlash() method. Similarly, we can clear flash values on a per-segment basis or a session-wide bases. Use the clearFlash() method on the Segment to clear flashes just for that segment, or the same method on the Session to clear all flash values for all segments. ## Authentication Authentication is made possible with the help of aura/auth. Aura.Auth supports below adapters : • Apache htpasswd files • SQL tables via the PDO extension • IMAP/POP/NNTP via the imap extension • LDAP and Active Directory via the ldap extension • OAuth via customized adapters We will concentrate on authentication via PDO adapter. ### Building Service class ### Configuration Consider reading adapters if you need changes/improvements. ### Calling Auth Methods You can retrieve authentication information using the following methods on the AuthService instance : • getUserName(): returns the authenticated username string • getUserData(): returns the array of optional arbitrary user data • getFirstActive(): returns the Unix time of first activity (login) • getLastActive(): return the Unix time of most-recent activity (generally that of the current request) • getStatus(): returns the current authentication status constant. These constants are: • Status::ANON – anonymous/unauthenticated • Status::IDLE – the authenticated session has been idle for too long • Status::EXPIRED – the authenticated session has lasted for too long in total • Status::VALID – authenticated and valid • isAnon(), isIdle(), isExpired(), isValid(): these return true or false, based on the current authentication status. You can also use the set*() variations of the get*() methods above to force the Auth object to whatever values you like. ### Eg : Calling methods inside action ## Action Domain Responder It is recommend to read Action Domain Responder in short ADR. Aura framework v2 promote the usage of one action per class. In ADR there are 3 components. 1. Action is the logic that connects the Domain and Responder. It uses the request input to interact with the Domain, and passes the Domain output to the Responder. 2. Domain is the logic to manipulate the domain, session, application, and environment data, modifying state and persistence as needed. 3. Responder is the logic to build an HTTP response or response description. It deals with body content, templates and views, headers and cookies, status codes, and so on. Basically 1. The web handler receives a client request and dispatches it to an Action. 2. The Action interacts with the Domain. 3. The Action feeds data to the Responder. (N.b.: This may include results from the Domain interaction, data from the client request, and so on.) 4. The Responder builds a response using the data fed to it by the Action. 5. The web handler sends the response back to the client. ### Responder Bundle We have FOA.Responder_Bundle which helps to render different template engines like Aura.View, Twig, Mustache etc. See full list. #### Installation Note : Current version 0.4 Let us modify our previous example of BlogRead action class to render the contents via BlogRead responder. Save at {$PROJECT_PATH}/src/App/Responder/BlogRead.php

Now modify the actions class {$PROJECT_PATH}/src/App/Actions/BlogRead.php to inject the BlogRead responder. You also need to inject a Domain service which can fetch the details of the id. We are skipping the service and assume you have some way to get the data. Remove the View and Response objects from the action class because the responder is responsible for rendering the view and set the response. Now your modified action class will look like Modify our Closure as a view file and save in {$PROJECT_PATH}/src/App/Responders/views/read.php.

Time to edit your configuration file {$PROJECT_PATH}/config/Common.php . Modify the class params for App\Actions\BlogRead to reflect the changes made to the constructor. Browse the http://localhost:8000/blog/read/1 . #### Questions What have we achieved other than creating lots of classes ? That is really a good question. We are moving the responsibility to its own layers which will help us in testing the application. Web applications get evolved even we start small, so testing each and every part is always a great way to move forward. This help us in to test the action classes, services etc. ## Command line / cli / console In this chapter we assume you have installed either aura/framework-project or aura/cli-project. Both aura/framework-project and aura/cli-project make use of the aura/cli library. Aura.Cli can be used as standalone library. Please refer getting started if you looking for standalone usage. ### Features of Aura.Cli #### Context Discovery The Context object provides information about the command line environment, including any option flags passed via the command line. (This is the command line equivalent of a web request object.) Please have a look at services You can access the $_ENV, $_SERVER, and $argv values with the $env, $server, and $argv property objects, respectively. (Note that these properties are copies of those superglobals as they were at the time of Context instantiation.) You can pass an alternative default value if the related key is missing. #### Getopt Support The Context object provides support for retrieving command-line options and params, along with positional arguments. To retrieve options and arguments parsed from the command-line $argv values, use the getopt() method on the Context object. This will return a GetoptValues object for you to use as as you wish.

##### Defining Options and Params

To tell getopt() how to recognize command line options, pass an array of option definitions. The definitions array format is similar to, but not exactly the same as, the one used by the getopt() function in PHP. Instead of defining short flags in a string and long options in a separate array, they are both defined as elements in a single array. Adding a * after the option name indicates it can be passed multiple times; its values will be stored in an array.

Use the get() method on the returned GetoptValues object to retrieve the option values. You can provide an alternative default value for when the option is missing.

If you want alias one option name to another, comma-separate the two names. The values will be stored under both names;

If you want to allow an option to be passed multiple times, add a ‘*’ to the end of the option name.

If the user passes options that do not conform to the definitions, the GetoptValues object retains various errors related to the parsing failures. In these cases, hasErrors() will return true, and you can then review the errors. (The errors are actually Aura\Cli\Exception objects, but they don’t get thrown as they occur; this is so that you can deal with or ignore the different kinds of errors as you like.)

##### Positional Arguments

To get the positional arguments passed to the command line, use the get() method and the argument position number:

Defined options will be removed from the arguments automatically.

#### Standard Input/Output Streams

The Stdio object allows you to work with standard input/output streams. (This is the command line equivalent of a web response object.)

Please have a look at services

It defaults to using php://stdin, php://stdout, and php://stderr, but you can pass whatever stream names you like as parameters to the newStdio() method.

The Stdio object methods are …

• getStdin(), getStdout(), and getStderr() to return the respective Handle objects;
• outln() and out() to print to stdout, with or without a line ending;
• errln() and err() to print to stderr, with or without a line ending;
• inln() and in() to read from stdin until the user hits enter; inln() leaves the trailing line ending in place, whereas in() strips it.

You can use special formatting markup in the output and error strings to set text color, text weight, background color, and other display characteristics. See the formatter cheat sheet below.

#### Exit Codes

This library comes with a Status class that defines constants for exit status codes. You should use these whenever possible. For example, if a command is used with the wrong number of arguments or improper option flags, exit() with Status::USAGE. The exit status codes are the same as those found in sysexits.h.

#### Writing Commands

The Aura.Cli library does not come with an abstract or base command class to extend from, but writing commands for yourself is straightforward. The following is a standalone command script, but similar logic can be used in a class. Save it in a file named hello and invoke it with php hello [-v,--verbose] [name].

#### Writing Command Help

Sometimes it will be useful to provide help output for your commands. With Aura.Cli, the Help object is separate from any command you may write. It may be manipulated externally or extended.

For example, extend the Help object and override the init() method.

Then instantiate the new class and pass its getHelp() output through Stdio:

• We keep the command name itself outside of the help class, because the command name may be mapped differently in different projects.
• We pass a GetoptParser to the Help object so it can parse the option defintions.
• We can get the option definitions out of the Help object using getOptions(); this allows us to pass a Help object into a hypothetical command object and reuse the definitions.

The output will look something like this:

#### Formatter Cheat Sheet

On POSIX terminals, <<markup>> strings will change the display characteristics. Note that these are not HTML tags; they will be converted into terminal control codes, and do not get “closed”. You can place as many space-separated markup codes between the double angle-brackets as you like.

For example, to set bold white text on a red background, add <<bold white redbg>> into your output or error string. Reset back to normal with <<reset>>.

### Services

Aura.Cli_Kernel defines the following service objects in the Container:

• aura/cli-kernel:dispatcher: an instance of Aura\Dispatcher\Dispatcher
• aura/cli-kernel:context: an instance of Aura\Cli\Context
• aura/cli-kernel:stdio: an instance of Aura\Cli\Stdio
• aura/cli-kernel:help_service: an instance of Aura\Cli_Kernel\HelpService
• aura/project-kernel:logger: an instance of Monolog\\Logger

### Quick Start

The dependency injection Container is absolutely central to the operation of an Aura project. Please be familiar with the DI docs before continuing.

You should also familiarize yourself with Aura.Dispatcher, as well as the Aura.Cli Context, Stdio, and Status objects.

### Project Configuration

Every Aura project is configured the same way. Please see the shared configuration docs for more information.

### Logging

The project automatically logs to {$PROJECT_PATH}/tmp/log/{$mode}.log. If you want to change the logging behaviors for a particular config mode, edit the related config file (e.g., config/Dev.php) file to modify the aura/project-kernel:logger service.

### Commands

We configure commands via the project-level config/ class files. If a command needs to be available in every config mode, edit the project-level config/Common.php class file. If it only needs to be available in a specific mode, e.g. dev, then edit the config file for that mode.

Here are two different styles of command definition.

### Micro-Framework Style

The following is an example of a command where the logic is embedded in the dispatcher, using the aura/cli-kernel:context and aura/cli-kernel:stdio services along with standard exit codes. (The dispatcher object name doubles as the command name.)

You can now run the command to see its output.

(If you do not pass an ID argument, you will see an error message.)

### Full-Stack Style

You can migrate from a micro-controller style to a full-stack style (or start with full-stack style in the first place).

First, define a command class and place it in the project src/ directory.

Next, tell the project how to build the FooCommand through the DI Container. Edit the project config/Common.php file to configure the Container to pass the aura/cli-kernel:context and aura/cli-kernel:stdio service objects to the FooCommand constructor. Then put the AppCommandFooCommand object in the dispatcher under the name foo as a lazy-loaded instantiation.

You can now run the command to see its output.

(If you do not pass an ID argument, you will see an error message.)

## Setting up your virtual host

### Apache

We are going to point the virtual host to aura.localhost. If you are in a debain based OS, you want to create a file /etc/apache2/sites-available/aura2.localhost.conf with the below contents.

path/to/project is where you installed the aura/web-project or aura/framework-project.

NOTE: Apache 2.4 users might have to add Require all granted below AllowOverride all in order to prevent a 401 response caused by the changes in access control.

Enable the site using

Before we go and check in browser add one more line in the /etc/hosts
In ubuntu 12.04 the configuration file is under /etc/nginx/sites-available