InterJinn

Development Framework For PHP

Properties

InterJinnTM packages a versatile property management system for configuring and customizing components. The property system enables a hierarchy of property definitions either via the file system configuration or with the SQL configuration. You can configure your project to use whichever suits your needs. The SQL base property system depends on the database service which by default connects to a MySQL database server.

Property fields

There are seven fields that are used to define a property. These fields are: group, name, type, value, extra, modify, and comment. Depending on whether you are using properties defined in a file or in a database the group field will be named by group and g_name respectively. The g_name field is used because a field name of group conflicts with the keyword of the same name in some database servers.

Path

The path is used to provide a hierarchy to property definitions. All components declare a property path which is used to resolve their member properties. The path used by the component is traversed one piece at a time and all variables at each level are accumulated and overwritten by variables of the same name and group further along the path. This means that a given property path may not need to declare a property if the property is already defined at a lower level in the path. While this is great, it may be the case that the component wants to inherit some properties and override others. This is fine since properties defined along a longer will override those with the same group and name defined along a shorter path.

For multilingual sites (multilingual enabled in the configuration), when the property is resolved the current language of the page will be used to add a final step to the property path. Thus the component can have language independent code and let the property resolution process do the work. Since this is a heavy process all resolved property paths are cached for future access. If you update a property then you will need to clear the cache. For the file based caching system this will mean deleting the directory hierarchy named propertyManager under the path defined for $GLOBALS['interJinn']['cacheDataPath'] in the project configuration. To do the same for a database caching system you must delete all entries from the general_cache table that have a group_id of propertyManager.

Group

This defines a grouping for the property. If this is set then all properties in this group will be collected together into an associative array member variable of the inheriting component. This is also useful for tracking down properties of a specific type when using the properties defined in the database. A good example of a grouping might be fonts, labels, or urls. If no group is specified then the property becomes a direct member variable of the object.

Name

This is the name of the property. When accessing the property in a component you will refer to this name as either a member variable of the object or, if a grouping was set, as the index to the associative array member variable of the module.

Type

Many different types of properties are supported. So that the property manager knows how to build a property you must set this value accordingly. The following types are currently available:

  • boolean/bool
  • integer/int
  • float
  • string
  • array/hash
  • font
  • link/url
  • image
  • query
  • file

Value

The content of this field is largely dependent on the what type of property we are dealing with. Given that a valid type is used from the list shown in the above type section, then the value will be as described in the appropriate section below. Note that values should be encased in single or double quotes when using file based properties -- regardless of the type.

boolean

You can set the value to either true or false.

Example:
false

integer

Exactly the same as in your PHP scripts. You may also use int to declare this type.

Example:
42000999

float

Exactly the same as in your PHP scripts.

Example:
150.12345

string

The string datatype works the same as if you had created it in PHP between two single quotes. Nothing is interpolated.

Example:
Please enter your login and password below.

array

Unlike arrays when writing PHP code, you can just set the entries of the array for this type. If you choose to do further nesting then you MUST use the first style presented here.

Example:
1 => 'hasLock',
2 => 'closed',
3 => 'locked',
4 => 'pickproof',
5 => 'trapped'
Alternate Example::
array
(
    1 => 'hasLock',
    2 => 'closed',
    3 => 'locked',
    4 => 'pickproof',
    5 => 'trapped'
)

font

This property type produces a font object which is the same kind of font object that can be created from the htmlFont service. The value of this field should contain the appropriate parameters for creating a font object from an array. See the documentation describing the HTML library for more details.

Example:
'class'  => 'fixed-content',
'colour' => '#000000',
'size'   => '-1'
Alternate Example::
array
(
    'class'  => 'fixed-content',
    'colour' => '#000000',
    'size'   => '-1'
)

link

This type is used to create a link or URL. If you have declared a pageBase in your configuration and this value begins with a a double forward slash (//), then the value will be rewritten so that it is relative to the pageBase directory. If the value does not have the leading double slashes then no processing will occur. In general using the double slash notation is best since it makes your Web site more portable.

Example:
//documentation/properties.php

image

This is very similar to the link type. It is used to denote the path to an image resource. If you have declared an imageBase in your configuration and this value begins with a double forward slash (//), then the value will be rewritten so that it is relative to the imageBase directory. If the value does not have the leading double slashes, then no processing will occur. In general using the double slash notation is best since it makes your Web site more portable.

Example:
//avatars/trollWarrior.jpg

query

The query type packs a lot of punch into one little property. The value for this field is a database query which will be performed on the default database (see extra field for other options). The actual value a component will get is an enumerated list of arrays representing each row of the result set (this behaviour can be changed by using the extra field as described later in this document).

Example:
SELECT
    name,
    level
FROM
    saved_players
WHERE
    level > 60
ORDER BY
    name

file

This is another powerful type. The value of the field for this type can be any file path recognized by PHP's readfile() function. The property value will be set to the contents of the file.

Example:
http://www.someweathercompany.org/weatherfeed.xml

Modify

The modify field is used to denote some special characteristics about the property and how it's data can or cannot be modified. The next few sections describe each of the values that may exits for this field.

Cache

This is the default type of modify value. If you do not set the modify field or the chosen value is invalid then the property will default to the cache type. This type means that the calculated value of the property will be cached and no processing will be performed on it for subsequent requests. This type of property is very quick to retrieve after the initial load.

Volatile

This type is currently only applicable to the query and file property types. If it is set as the modify type then at each property retrieval the query will be re-issued or the file contents will be re-retrieved. This type is perfect for data sources that change frequently.

Session

When this type of property is created the visitor's session is checked for a pre-existing property of the same definition. If one does not exist then a new session variable is created for the visitor and it's value is set to the value of the property. On subsequent retrievals the value of the session variable will be retrieved and used. The important thing to note is that the component's member variable will contain a direct reference into the session structure which means if you modify the variable in the component then the value will change for the duration of the session. This is a convenient and clean way to manage session data provided you do not unset() the component's member variable or try to assign it another reference via the & operator. Note also that there are obvious unresolved issues with respect to race conditions. Do not use this for race condition sensitive operations.

Profile

This type works similar to the session type. When this property is created the visitor's profile is checked for a pre-existing property of the same definition. If one does not exist then a new profile variable is created for the visitor and it's value is set to the value of the property. On subsequent retrievals the value of the profile variable will be retrieved and used. The important thing to note is that the component's member variable will contain a direct reference into the profile structure which means if you modify the variable in the component then the value will change for the duration of the profile. This is a convenient and clean way to manage profile data provided you do not unset() the component's member variable or try to assign it another reference via the & operator. Note also that there are obvious unresolved issues with respect to race conditions. Do not use this for race condition sensitive data.

Propagate

Once again this type works similar to the session type. When this property is created the cache is checked for a pre-existing property of the same definition. If one does not exist then a new permanent cache variable is created for the visitor and it's value is set to the value of the property. On subsequent retrievals the value of the cache will be retrieved and used. The reason for the name propagate is because the cache is global to all page accesses. This means the updated value will propagate to all future page accesses. The important thing to note is that the component's member variable will contain a direct reference into the propagate structure which means if you modify the variable in the component then the value will change for the duration of the cache entry (forever unless manually flushed). This is a convenient and clean way to manage site-wide global data provided you do not unset() the component's member variable or try to assign it another reference via the & operator. Note also that there are obvious unresolved issues with respect to race conditions. Do not use this for race condition sensitive data.

Extra

The extra field is used to provide extra information about a property. The format of the extra field is exactly the same as for the value field of the array datatype which is just the entries of an associative array where the key corresponds to one of the following extra options:

sessionPath

Available to all datatypes which are of the session modify type.

This can be set to an arbitrary session path to use instead of the property path and property name which are used by default to set up the session entry. For more information see the Session Documentation.

profilePath

Available to all datatypes which are of the profile modify type.

This can be set to an arbitrary profile path to use instead of the property path and property name which are used by default to set up the profile entry. For more information see the Profile Documentation.

language

Available to ALL datatypes.

If the table upon which you are making your query contains language selectable data and your site is multilingual, then you won't want to create a query property for every language type available. To extend upon the power of the query property this field enables the current language to be substituted into the query string before the query is made to the database. The value of the language extra is the text upon which to make the substitution.

dbLookup

Only used in query datatypes.

A database lookup keyword as you would define in the project configuration for database connections.

host

Only used in query datatypes.

The host IP or domain name of a database server to use as an alternative to the default.

db

Only used in query datatypes.

The name of a database to use as an alternative to the default.

user

Only used in query datatypes.

The name of a user to use as an alternative to the default.

password

Only used in query datatypes.

The password of a user to use as an alternative to the default.

keyField

Only used in query datatypes.

This is used in conjunction with valueField.

valueField

Only used in query datatypes.

When used in conjunction with the keyField extra value then the result is an associative array of keyField values to valueField values created from the corresponding fields of the result set of the query.

To make everything a little clearer the following example is used to illustrate all of the extras described for the query property.

Example Query Value:
SELECT
    author,
    quote
FROM
    famous_quotes
WHERE
    language = '[[language]]'
ORDER BY
    RAND()
LIMIT
    10
Example Query Extra:
'host'       => '127.0.0.1',
'db'         => 'compendium',
'user'       => 'Saskwatch',
'password'   => 'bigSecret',
'keyField'   => 'author',
'valueField' => 'quote',
'language'   => '[[language]]'

Comment

The comment field is a place for you to input a free style comment about a property. Sometimes this can be extremely useful if the purpose of the property is not immediately apparent from any of the other fields.

Example:
Auto login status for user profile.

Creating Properties

Database Properties

The database method of creating properties is quite trivial. You can use your favourite database table editor (perhaps PHPMyAdmin) and just input the data for the fields as described above, or you can create the query yourself.

Example:
INSERT INTO properties
(
    path,
    g_name,
    name,
    value,
    type,
    modify,
    extra,
    comment
)
VALUES 
(
    'InterJinn/news/feed',
    'urls',
    'feedSource',
    'http://www.somenewsprovider.org/newsFeed.xml',
    'url',
    'cache',
    '',
    'URL from which to retrieve XML formatted news.'
);

Filesystem Properties

Creating filesystem based properties are a little more involved, though once you get a feel for it you'll have no trouble at all. First off all the properties need to be created in a subdirectory of the properties path you defined in your project configuration -- $GLOBALS['interJinn']['propertyDataPath'].

From the properties directory the system is fairly simple. Each part of the path you would define for the path field is a nested subdirectory. For instance a property path of InterJinn/news/feed would require you to do something like the following:

Example:
mkdir InterJinn
cd InterJinn
mkdir news
cd news
mkdir feed
cd feed

Having created the path you are now ready to create the property file which is name by the joining the group name and the property name with a period. If you had a property group of urls and a property name of feedSource then the filename would be urls.feedSource. If you did not wish to set a group name then you can omit the group anem portion and the period.

The final part of the process is setting the values of the other fields. Namely the type, value, modify, extra, and comment fields. To continue with our example I might use the following contents for the property file:

Example:
'value'     => 'http://www.somenewsprovider.org/newsFeed.xml',
'type'      => 'url',
'modify'    => 'cache',
'extra'     => '',
'comment'   => 'URL from which to retrieve XML formatted news.',

Where can I learn more about the property service?

It may not be apparent in the above documentation, but the property management system is controlled to a large degree by the property service. This service is used by the dynamic loading mechanism to bind properties to components; however, the property service can be invoked manually just like any other service. You can learn more about the property service by reading the Property Service Documentation. The same documentation will provide you with a list of methods and functionality that must exist in your own property service should you choose to create a custom one. You might also find the general Service Documentation useful.