Skip to content
This repository was archived by the owner on Jan 16, 2019. It is now read-only.

Apps properties

Frank Kleine edited this page May 5, 2013 · 6 revisions

Apps and properties

Introduction

When you build an application it can be useful to allow certain things to be configurable. That could be pathes where files are stored, or specific settings that influence how the application behaves or what it does. That's where the properties binding module comes into play. In your app class, it can easily be added to the list of bindings:

namespace example;
use net\stubbles\ioc\App;
class MyApplication extends App
{
    /**
     * returns a list of binding modules used to wire the object graph
     *
     * @param   string  $projectPath
     * @return  array
     */
    public static function __bindings($projectPath)
    {
        return array(self::createPropertiesBindingModule($projectPath),
                     new example\StuffRequiredForApplicationBindingModule(),
                     'example\\other\\MoreStuffBindingModule'
        );
    }
}

Here the call to self::createPropertiesBindingModule($projectPath) initializes the properties binding module with the project path.

Properties

Properties are useful to configure application settings. That could be database connection settings, enabling or disabling certain features, or other things that are useful to do via simple configuration files. The properties binding module supports that by reading a file path/to/your/project/config/config.ini and to add a binding for properties which allows other classes in the application to get those properties injected.

There are two ways to get the properties from this file injected: either by receiving an instance of net\stubbles\lang\Properties or by receiving single property values.

Instance of net\stubbles\lang\Properties

To get access to all property values, the class should declare a dependency to net\stubbles\lang\Properties named config:

namespace example;
use net\stubbles\lang\BaseObject;
use net\stubbles\lang\Properties;
class Example extends BaseObject
{
    /**
     * @type  Properties
     */
    private $properties;
    
    /**
     * constructor
     *
     * @param  Properties  $properties
     * @Inject
     * @Named('config')
     */
    public function __construct(Properties $properties)
    {
        $this->properties = $properties;
    }

    ... useful methods to do something ...
}

Now the class has access to all properties via the net\stubbles\lang\Properties instance. See Properties for details on how to access single values.

Receiving single property values

If you require a single property value only it might be too much to receive a whole net\stubbles\lang\Properties instance. Instead you want the single value only. This could be done by using constants:

namespace example;
use net\stubbles\lang\BaseObject;
class AnotherExample extends BaseObject
{
    /**
     * @type  string
     */
    private $roland;
    
    /**
     * constructor
     *
     * @param  string  $roland
     * @Inject
     * @Named('example.roland')
     */
    public function __construct($roland)
    {
        $this->roland = $roland;
    }

    ... useful methods to do something ...
}

Here, the configuration value example.some.setting will be injected. However, it must be in the config section of the path/to/your/project/config/config.ini file:

[config]
example.roland = "TB 303"

Please note that only properties in the config section of the file are available for injection. For configurations in any other section you need to use the instance as described above.

Pathes as properties

Often, it is also useful to get pathes injected so that they are not fixed within classes, which makes them hard to test or even impossible to use on another system when those pathes are not only fixed but also global and not relative.

By default, the properties binding module will provide constants for three different pathes:

  • cache, net.stubbles.cache.path, pointing to $projectPath/cache ( only available in versions < 3.1.0 )
  • config, net.stubbles.config.path, pointing to $projectPath/config
  • log, net.stubbles.log.path, pointing to $projectPath/log

You can add more pathes using the addPathType() method:

namespace example;
use net\stubbles\ioc\App;
class MyApplication extends App
{
    /**
     * returns a list of binding modules used to wire the object graph
     *
     * @param   string  $projectPath
     * @return  array
     */
    public static function __bindings($projectPath)
    {
        return array(self::createPropertiesBindingModule($projectPath)
                         ->addPathType('docroot'),
                     new example\StuffRequiredForApplicationBindingModule(),
                     'example\\other\\MoreStuffBindingModule'
        );
    }
}

Now, a path pointing to $projectPath/docroot becomes available for injection using the net.stubbles.docroot.path constant.

Current working directory

Available since release 2.1.0.

While the current working directory can be retrieved simply by calling the PHP function getcwd() this might not always be desirable, as this makes test cases harder to create so that they run on more than just the developer's machine. The properties binding module provides a way of making the current working directory available for injection:

namespace example;
use net\stubbles\ioc\App;
class MyApplication extends App
{
    public static function __bindings($projectPath)
    {
        return array(self::createPropertiesBindingModule($projectPath)
                         ->withCurrentWorkingDirectory()
        );
    }
}

Now, the current working directory is available as constant binding under the name net.stubbles.cwd.

Hostname

Available since release 2.1.0.

Similar to the current working directory it might not always be desirable to call php_uname('n') in order to retrieve the hostname of the current machine. Also, this only provides a non qualified hostname, whereas sometimes a fully qualified hostname is required. Retrieving this is much harder, as there is no common way to do this regardless of the platform the application is currently running on. The properties binding module provides a way of making the hostname available for injection:

namespace example;
use net\stubbles\ioc\App;
class MyApplication extends App
{
    public static function __bindings($projectPath)
    {
        return array(self::createPropertiesBindingModule($projectPath)
                         ->withHostname()
        );
    }
}

This makes both the non and the fully qualified hostname available as constant bindings. The name for the non qualified hostname is net.stubbles.hostname.nq, whereas the name for the fully qualified hostname is net.stubbles.hostname.fq.

Please note: the method will try different ways to resolve the hostname. While non qualified hostname can be guaranteed to be available, the fully qualified hostname might be empty in case it could not be retrieved. Your application should be able to react on such a situation.

Clone this wiki locally