InterJinn

Development Framework For PHP

Creating Services

Step 1 - Creating the service class

There are three steps to creating a service. The first is to create the class that will contain the service's methods. This is done by extending the JinnBaseService class. We will use an example service which retrieves a logged in user's information. This is a common purpose for many services especially when a user's information needs to be analyzed in many pages such as in an online content management system.

Example:
class ProjectServicesUser extends JinnBaseService
{
    var $filename = __FILE__;
                             
    function execute()       
    {                 
        //
        // Nothing to do.
        //
    }     
// // Returns an information array for the user who is logged into the // current session. // function &getCurrentUserInfo() { $sessionManager = $this->getService( 'sessionManager' ); $session = &$sessionManager->do->getSession();
$loginName = &$session->do->getData( 'login/name' );
return $this->getUserInfo( $loginName ); }
function &getUserInfo( $id ) { $id = addSlashes( $id );
$qString = "SELECT " ." user_id, " ." login, " ." password, " ." first_name, " ." last_name, " ." access_level " ."FROM " ." users " ."WHERE " ." login = '$id' ";
$dbManager = &$this->getService( 'dbManager' ); $db = &$this->unwrapObject( $dbManager->do->getConnection() );
$db->query( $qString );
$user = null; if( $db->nextRow() ) { $user = array();
$user['user_id'] = $db->getField( 'user_id' ); $user['login'] = $db->getField( 'login' ); $user['password'] = $db->getField( 'password' ); $user['first_name'] = $db->getField( 'first_name' ); $user['last_name'] = $db->getField( 'last_name' ); $user['access_level'] = $db->getField( 'access_level' ); }
$db->free();
return $user; } }

This is an extremely simple service and yet it illustrates the power of the InterJinn framework by providing an example of other core services. Just like for components a service can implement an execute() method to be run after when the service has been loaded for the first time. Here our execute() method isn't necessary and could have been completely excluded. After that we just provide methods that can be access by consumers of the service. You may have noticed that a $filename member variable was declared. This is used by the error handling methods that services and components inherit and can be used to help find errors and problems. I strongly advise declaring it verbatim in each service and component class that you create.

Step 2 - Registering the service

To declare your new service you just need to add an entry into the $GLOBALS['interJinn']['services'] array which you should be able to find in your project's configuration file. If not then you can create it, the following is what you would have if this is your only service:

Example:
//
// Resource files for the dynamic loader. All of the following can, and
// should, be loaded via the dynamic loader. The key is the lookup name
// and the value is the path to the resource file.
//
$GLOBALS['interJinn']['services'] = array
(
    'ProjectServicesUser' => '//Project/services/user.inc',
);

The key for the entry can be an arbitrary name that you assign to your service, this name will be used to create aliases and will also be used internally to determine if the service has previously been loaded or not. The value is the path to service's source file. If the path begins with /// then the path will be considered relative to the coreRoot path that was set in the project configuration. If instead it begins with // then the path will be considered relative to the codeRoot path that was set in the project configuration. If the path is preceded by / then the file will be retrieved relative to the root of the filesystem. Last, if neither of the former two cases are true, then the path will be treated as though it had been prefixed with //. You should make sure that read permission is set for the appropriate owners at this location.

Step 3 - Declaring service aliases

You've almost completed your first service. All that remains is to declare some aliases that can be used to access your service from within components. To declare aliases you just need to add an entry into the $GLOBALS['interJinn']['serviceAliases'] array which you should be able to find in your project's configuration file. If not then you can create it, the following is an example of what you might use:

Example:
//
// Aliases for retrieving dynamic resources. The key represents the
// alias and the value must match an entry's key in the services
// structure.
//
$GLOBALS['interJinn']['serviceAliases'] = array
(
    'projectUser' => 'ProjectServicesUser',
    'user'        => 'ProjectServicesUser',
);

With the above aliases you are now ready to use your newly defined service from any other services or from any components. The above example is used as an example to illustrate a wise and not so wise alias for your services. The first is wise because it stems from the project; however, the second is not so wise because if the event ever occurred where two projects needed to use one another's components and services then an alias of user might become ambiguous. The following example provides an example of this new service being used:

Example:
//
// Retrieve the user service.
//
$userService = $this->getService( 'projectUser' );
// // Retrieve the current user's information via the suer service. // $userInfo = $userService->do->getCurrentUserInfo();
// // Perform some action based on the user's access_level. // if( is_null( $userInfo ) || $userInfo['access_level'] < 3 ) { $this->redirect( $this->links['unauthorized'] ); }