Documentation

Configuration

Presentation

The configuration of a project using Temma is done by modifying the temma.json file which is placed in the etc/ directory.

It is a file in JSON format, which has several sections that are easy to edit.

In the etc/ directory, you can find two files used to illustrate the configuration of a Temma project:

  • temma-mini.json: Minimal file containing basic directives.
  • temma-full.json: File showing all the available options.

Simple temma.json file

Here is a typical example of a minimal temma.json file:

{
    // application configuration
    "application": {
        "dataSources": {
            "db": "mysql://user:passwd@localhost/mybase"
        },
        "rootController": "HomepageController"
    },
    // definition of log levels
    "loglevels": "ERROR",
    // definition of error pages
    "errorPages": "error404.html",
    // data imported automatically as template variables
    "autoimport": {
        "googleId": "azeazeaez",
        "googleAnalyticsId": "azeazeazeaze"
    }
}

We can see:

  • Line 5: The definition of the DSN which allows to connect to the database.
  • Line 7: The name of the root controller, which will be called when someone logs in without specifying a controller.
  • Line 10: Setting the threshold for writing log messages to the log/temma.log file. Here, with the "ERROR" threshold, only the messages with the ERROR and CRIT thresholds will actually be written to the log file.
  • The definitions of the pages to display if an error occurs. The pages in question must be located in the www/ directory of the project.
    • Line 13: If a 404 error occurs, the error404.html page will be returned.
    • Line 14: If a 500 error occurs, the error500.html page will be returned.
    • Line 15: In all other error cases, the content of the error404.html page will be returned.
  • Automatically imported template variables.
    • Line 19: Google ID, available in the templates with {$conf.googleId} and in the controller with $this['conf']['googleId'].
    • Line 20: Google Analytics ID, available in templates with {$conf.googleAnalyticsId} and in the controller with $this['conf']['googleAnalyticsId'].

Complete temma.json file

Here is another example, which shows all the standard configuration variables:

{
    // General application definition variables
    "application": {
        // data sources
        "dataSources": {
            // MySQL database connection DSN
            //  (cf. object \Temma\Base\Database).
            // Optional
            "db": "mysqli://user:passwd@localhost/mybase",

            // DSN for connection to the Redis database
            //  (cf. object \Temma\Base\NDatabase).
            // Optional
            "ndb": "redis://localhost:6379/0",

            // DSN for connection to the Memcached cache server
            //  (cf. object \Temma\Base\Cache).
            // Optional
            "cache": "memcache://localhost:11211"
        },

        // Indicate whether or not we want to use the sessions.
        // Use to deactivate sessions as needed.
        // Optional: "true" by default.
        "enableSessions": true,

        // Name of the session cookie.
        // Optional: "TemmaSession" by default.
        "sessionName": "TemmaSession",

        // Data source to store sessions.
        // Optional: Use the PHP session management
        // mechanism by default
        "sessionSource": "ndb",

        // Default namespace of the controllers
        // Optional: by default the controllers are in
        // the global namespace.
        "defaultNamespace": "\\MyApp\\Controllers",

        // Name of the controller used for the site root.
        // Optional. By default uses the controller defined by
        // the 'defaultController' variable.
        "rootController": "Homepage",

        // Name of the default controller to use if the requested
        // controller does not exist.
        // Optional. By default, generates a 404 error if you ask
        // for a controller that does not exist.
        "defaultController": "NotFound",

        // Name of the controller to always be called,
        // even if the requested one exists.
        // Optional.
        "proxyController": "Main"

        // Name of the default view.
        // Optional. \Temma\Views\Smarty by default.
        "defaultView": "\\Temma\\Views\\Smarty",

        // Name of the object that will be used as
        // a dependency injection component
        "loader": "MyLoader",

        // Path to the log file.
        // Optional: By default, logs are written into
        // the "log/temma.log" file.
        // Put a false value (null, false, empty string or the
        // number zero) to disable writing to the log file.
        "logFile": "log/temma.log",

        // Name of the log management object, or list of object names.
        // Optional: No log manager is enabled by default.
        "logManager": [ "ElasticLogManager", "SentryLogManager" ]
    },
    // Definition of log levels
    "loglevels": {
        "Temma/Base": "ERROR",
        "Temma/Web": "WARN",
        "myapp": "DEBUG",
        "default": "NOTE"
    },
    // Routing: We indicate the names of virtual controllers,
    // by associating a real controller (or virtual, in cascade),
    //  which will handle the requests.
    "routes": {
        "sitemap.xml": "SitemapController",
        "sitemap.extended.xml": "sitemap.xml",
        "robert": "BobController"
    },
    // Plugin management
    "plugins": {
        // Plugins executed for all controllers
        // - plugins executed before the controller
        "_pre": [
            "CheckRequest",
            "UserGrant"
        ],
        // - plugins executed after the controller
        "_post": [ "AddCrossLinks" ],
        // Definition of plugins specific to the Article controller
        "Article": {
            // plugins executed before and after the controller
            "_pre": [ "Something" ],
            "_post": [ "SomethingElse" ],
            // plugins specific to the index action
            "index": {
                "_pre": [ "Aaa" ],
                "_post": [ "Bbb" ]
            },
            // plugin executed before the setData action
            "setData": {
                "_pre": [ "CccPlugin" ]
            }
        },
        // Plugin for the BobController controller, but
        // only when called by its route "robert"
        "robert": {
            "_pre": [ "AnotherPlugin" ]
        }
    },
    // Definition of error pages
    "errorPages": {
        "404":     "error404.html",
        "500":     "error500.html",
        "default": "error404.html"
    },
    // List of inclusion paths
    "includePaths": [
        "/opt/some_library/lib",
        "/opt/other_lib"
    ],
    // List of inclusion paths for namespace prefixes
    "namespacePaths": {
        "\\Acme\\Log":      "/path/to/acme-log/lib",
        "\\MyLib\\Feature": "/path/to/vendors/feature"
    },
    // Data imported automatically as template variables
    "autoimport": {
        "googleId": "azeazeaez",
        "googleAnalyticsId": "azeazeazeaze"
    },
    // Extended configuration
    "x-homepage": {
        "title": "Titre du site",
        "description": "Description of the site"
    },
    // Another extended configuration
    "x-email": {
        "senderAddress": "admin@localhost.localdomain",
        "senderName": "Administrator"
    }
}

Comments

As you can see above, temma.json files can contain comments (in the form of double-slashes, or in the form /* … */).

application

The main section of the file is the one named application. It is used to define the most important configuration variables of the project.
Here are the different variables it can contain:

  • dataSources: Used to define the DSNs (Database Source Name) for data source connections (MySQL, Redis, Memcached).
  • enableSessions: This variable must be set to false if you do not want to manage the sessions. This can be useful when you do not want to track user visits, such as for an API.
  • sessionName: Name of the cookie that will contain the session identifier.
  • defaultNamespace: In the event that the controllers' PHP files are not saved in the controlers/ directory, this variable contains the default namespace of the controllers.
    For example, if this variable contains the value \App\Ctrl, and we connect to the URL www.mysite.com/home, Temma will load the \App\Ctrl\Home object.
  • rootController: Name of the controller to run when a connection is made to the site root.
  • defaultController: Name of the controller to execute when a controller that does not exist is requested.
  • proxyController: Name of the controller to execute all the time, even if the requested controller exists.
  • defaultView: Name of the default view, which will be used to generate the output stream (unless another view is explicitly requested in the controller or a plugin).
  • loader: Name of the object that will be used as the dependency injection component.
  • logFile: Path to the log file. Put a false value (null, false, empty string or the number zero) to disable writing to the log file (this can be useful if you want to use only a log manager; see the next directive). Any path not starting with a slash (/) will be relative to the root of the project.
  • logManager: This variable can contain the name of a log management object, or a list of object names. See the log documentation for more details.

DSN (Data Source Name)

To define a connection to a data source, you must write a character string that contains all the parameters.

Several formats are possible:

  • Environment variable
    It is possible to indicate the name of an environment variable.
    env://VAR_NAME
    This variable must be correctly defined, and its content must be a DSN supported by Temma (see the cases below).
  • Relational database
    protocol://user:password@host[:port][/db_name]
    • protocol : Database type, as defined by PDO (mysql, pgsql, cubrid, sybase, mssql, dblib, firebird, ibm, informix, sqlsrv, oci, odbc, 4D)
    • user : User name used to connect to the server
    • password : Password used to connect to the server
    • host : Name of the machine hosting the database server
    • port : Network connection port number (optional, uses the usual port number by default)
    • db_name : Name of the base instance to connect to (optional)
    Examples:
    • mysql://db_user:db_password@localhost/app_db
    • pgsql://db_user:db_password@db_server.mydomain.com:3307/app_db
    It is possible to connect to a MySQL server using local Unix sockets, rather than network sockets: mysql://user:password@localhost/db_name#/var/run/mysqld/mysqld.sock
    Compared to a classic MySQL configuration, you must add a hash character (#), followed by the path to the Unix socket file. The host machine name must be localhost. There cannot be a port number.
    Example: mysql://db_user:db_password@localhost/app_db#/var/run/mysqld/mysqld.sock
  • Local relational database (SQLite)
    sqlite:/path/to/file.sq3
  • Non-relational database (Redis)
    redis://host[:port][/db_number]
    • host : Name of the machine hosting the Redis server
    • port : Network connection port number (optional, uses port 6379 by default)
    • db_number : Number of the base to connect to (optional, uses base 0 by default)
    Examples:
    • redis://localhost
    • redis://db_server.mydomain.com:6380/2
    It is possible to connect to a Redis server using local Unix sockets, rather than network sockets:
    redis-sock:///path/to/unix/socket[#base]
    Compared to a classic Redis configuration, you must indicate the path to the Unix socket file, instead of the server name. If a base number is specified, it must be indicated at the end, after a hash character (#); otherwise base 0 is used by default.
    Examples:
    • redis-sock:///var/run/redis/redis-server.sock
    • redis-sock:///var/run/redis/redis-server.sock#2
  • Cache server (Memcached)
    memcache://host[:port]
    • host : Name of the machine hosting the Memcached server
    • port : Network connection port number (optional, uses port 11211 by default)
    Example: memcache://localhost
    It is possible to configure the client to connect to several Memcached servers (the distribution of data on several Memcached servers is managed on the client side). To do this, you must indicate the servers one after the other, separated by a semicolon (;); each server can be accompanied by a specific port number.
    Example: memcache://localhost;serv1:11212;serv2

loglevels

The loglevels section is used to define the different log levels. You will find information on its use in the documentation page dedicated to the log.

You can define multiple log "classes", each with a different display threshold. The threshold determines the messages that will appear in the etc/temma.log file. When a code tries to write a log message, the message in question will only appear if its level of criticality is greater than or equal to that of the corresponding threshold.

The different possible threshold values are:

  • DEBUG : debugging message (lowest criticality)
  • INFO : information message (default level for messages whose level is not specified)
  • NOTE : notification; normal but meaningful message (default threshold)
  • WARN : alert message; the application does not work normally but it can continue to work.
  • ERROR : error message; the application is not functioning normally and should stop.
  • CRIT : critical error message; the application risks damaging its environment (filesystem or database).

You can define your own log "classes", depending on your application needs. In addition to that, you can use the following classes:

  • Temma/Base: Logs concerning Temma base objects (database, autoloader, sessions, etc.).
  • Temma/Web: Logs concerning the objects of the framework itself.
  • default: Used to set the default threshold, for all classes that are not defined.

If the loglevels directive does not contain an associative array, but simply a string representing a log threshold, this will be used for all messages, regardless of their specific "class".

routes

Routes are used to define "virtual controllers", serving as aliases for real controllers. This is particularly useful for allowing access to controllers under file names (such as the classic robots.txt and sitemap.xml). This also makes it possible to have the same controller which responds on several different URLs, possibly doing different processing depending on the controller name requested.

plugins

Plugins are used to execute code before and/or after controller execution. You will find detailed information on the dedicated documentation page.

The _pre variable is used to list the plugins that will be executed before the controllers.
The _post variable is used to list the plugins that will be executed after the controllers.

Controllers can be listed by name, specifying specific _pre and _post directives for each. It is also possible to specify plugins for a particular action of a controller.

errorPages

In some cases, your site will need to send an HTTP error code. And if an error occurs in your code itself (due to an incorrect SQL query, for example), the framework will decide to send a 500 error.

It is possible to display a different static HTML page for each type of HTTP error, and to define a default page for all types of errors that are not explicitly configured.

To not define all possible error pages, you can use the "default" key to define the default page.
If you want to use the same page, regardless of the error, you can just provide a string, not an associative array.

includePaths

This section is used to add inclusion paths in which PHP is likely to fetch the objects to include.

Basically, Temma adds the lib/ directory of the project to the include path. So, if you write in your code: include('Toto.php');
The lib/Toto.php file will be loaded.

Or, thanks to the autoloader, if you write: new \Aaa\Bbb();
PHP will load the lib/Aaa/Bbb.php file automatically.

But if you add the following configuration in your temma.json file:

{
    includePaths: [
        "/path/to/lib1",
        "/path2"
    ]
}

If you write in your code require_once('titi.php');
PHP will try to load successively several paths, until it finds the file. In order, it will try:

  • /path/to/lib1/titi.php
  • /path2/titi.php
  • lib/titi.php

Using the autoloader, if you write new \Aa\Bb(); PHP will try the following paths:

  • /path/to/lib1/Aa/Bb.php
  • /path2/Aa/Bb.php
  • lib/Aa/Bb.php

namespacePaths

There may be times when you need to specify specific include paths for certain namespace prefixes. Let's say your temma.json file contains the following configuration:

{
    namespacePaths: {
        "\\Acme\\Log": "/path/to/acme-log/lib",
        "\\Aa\\Bb": "/path/to/Bb"
    }
}

If you write the code new \Acme\Log\Writer();
PHP will try to load the file /path/to/acme-log/lib/Writer.php

On the other hand, if you write new \Aa\Bb\Cc();
PHP will load the file /path/to/Bb/Cc.php

autoimport

All directives placed in the autoimport section are automatically loaded inside the template variable $conf.

Template variables can be accessed in controllers by writing $this['variable'].
They can also be created (or overwritten) by writing $this['variable'] = $ value;.

Extended configuration

The configuration file can contain extended configuration sections. Their purpose is to group additional parameterization variables, classifying them by functionality. Thus, a controller or a plugin can easily retrieve the values that interest it, without needing to know all the existing configuration variables.

To retrieve an entire extended configuration section, you have to go through the configuration object which is available via the dependency injection component:
$this->_loader->config

For example, to retrieve the entire x-homepage extended configuration, you must write:
$data = $this->_loader->config->xtra('homepage');

To retrieve the senderName variable from the x-email section:
$data = $this->_loader->config->xtra('email', 'senderName');

It is also possible to specify a default value which will be used if the requested variable does not exist:
$data = $this->_loader->config->xtra('email', 'recipient', 'contact@host.domain');

Previous: Installation
Next: Routing

Table of Contents