Anda di halaman 1dari 70

Roadsend PHP SiteManager

Shannon Weyrick
Roadsend, Inc.

Jon Michel
Roadsend, Inc.

Roadsend PHP SiteManager by Shannon Weyrick and Jon Michel 2.2.x Production Series Edition Copyright 2001 by Roadsend, Inc.

Table of Contents
1. Introduction......................................................................................................................................................................................6 Overview....................................................................................................................................................................................6 Feature Summary .......................................................................................................................................................................6 About Roadsend.........................................................................................................................................................................8 2. General Information ......................................................................................................................................................................10 Version Numbering ..................................................................................................................................................................10 File Extensions for SiteManager Resource Files .....................................................................................................................10 Security Concerns ....................................................................................................................................................................10 Directory Layout......................................................................................................................................................................11 3. SiteManager Fundamentals ..........................................................................................................................................................12 SiteManager Global Variables .................................................................................................................................................12 SiteManager Root Object ($SM_siteManager) .......................................................................................................................13 loadSite Method ...........................................................................................................................................................13 loadModule Method.....................................................................................................................................................13 includeModule Method................................................................................................................................................14 rootTemplate Method...................................................................................................................................................14 loadTemplate Method ..................................................................................................................................................14 loadCodePlate Method.................................................................................................................................................15 dbConnect Method.......................................................................................................................................................15 startSessions Method ...................................................................................................................................................15 addPersistent Method...................................................................................................................................................15 completePage Method..................................................................................................................................................15 fatalDebugPage Method...............................................................................................................................................16 Global Conguration System...................................................................................................................................................16 getVar Method..............................................................................................................................................................17 getSection Method .......................................................................................................................................................17 setVar Method ..............................................................................................................................................................18 Variable Replacement ..................................................................................................................................................18 Section IDs..................................................................................................................................................................19 SM_Object Base Class.............................................................................................................................................................20 ......................................................................................................................................................................................20 Internationalization Support.........................................................................................................................................20 Directive Scripts.......................................................................................................................................................................21 Modules....................................................................................................................................................................................22 Overview......................................................................................................................................................................22 moduleCong Method .................................................................................................................................................22 moduleThink Method...................................................................................................................................................25 canModuleLoad Method..............................................................................................................................................26 Database Connectivity .................................................................................................................................................27 Session Functionality ...................................................................................................................................................28 Module within Modules...............................................................................................................................................29 Extending Your Modules .............................................................................................................................................29 preThinkList and postThinkList ..................................................................................................................................30 InVar Propagation (read-write inVars) .........................................................................................................................33 Multilingual Support....................................................................................................................................................33 Module Design Tips.....................................................................................................................................................34 Templates .................................................................................................................................................................................34

Templates within Templates (sub-templates)...............................................................................................................36 CodePlates................................................................................................................................................................................36 SmartForms..............................................................................................................................................................................39 Usage............................................................................................................................................................................39 Create a New Form ......................................................................................................................................................39 Congure Form............................................................................................................................................................40 Add Elements...............................................................................................................................................................40 Loading a SmartForm ..................................................................................................................................................41 Conguring Elements ..................................................................................................................................................42 Run Form and Input Validation Check ........................................................................................................................42 Form Templates............................................................................................................................................................43 Hidden Variables..........................................................................................................................................................44 Session Aware Forms...................................................................................................................................................45 Session Management ...............................................................................................................................................................45 Conguring Sessions ...................................................................................................................................................45 Using Sessions .............................................................................................................................................................46 Member Login Sessions...............................................................................................................................................47 Database Connectivity .............................................................................................................................................................49 Database Connection Settings......................................................................................................................................50 Multiple Database Connections ...................................................................................................................................50 Error Handling and Debugging................................................................................................................................................51 DebugOnVar ................................................................................................................................................................51 JavaScript Debug Window ...........................................................................................................................................52 Helpful Debug Routines ..............................................................................................................................................53 Miscellaneous Routines ...........................................................................................................................................................53 4. Designing a SiteManager Site By Example .................................................................................................................................54 Assess Site Needs ....................................................................................................................................................................54 Determine Separation of Static Layout from Dynamic Content..............................................................................................55 Determine Method of Splitting Dynamic Content Into Modules ............................................................................................56 Determine Site Plan .................................................................................................................................................................56 Implement Site Plan.................................................................................................................................................................57 Site Conguration ........................................................................................................................................................57 Template Design ..........................................................................................................................................................57 Module Design:............................................................................................................................................................57 5. Using The Test Site.........................................................................................................................................................................59 6. Extending SiteManager .................................................................................................................................................................60 7. Frequently Asked Questions .........................................................................................................................................................61 8. Getting More Help .........................................................................................................................................................................62 A. Directive Lists ................................................................................................................................................................................63 Module Directives....................................................................................................................................................................63 Template Directives .................................................................................................................................................................64 SmartForm Directives ..............................................................................................................................................................64 Input Entity Directives .................................................................................................................................................66 Filter Directives............................................................................................................................................................66 B. File Formats ...................................................................................................................................................................................67 .XSM Resource Files ...............................................................................................................................................................67 SMARTFORM.............................................................................................................................................................67 SMLANGUAGE..........................................................................................................................................................67

SMOBJECT .................................................................................................................................................................67 SMCONFIG.................................................................................................................................................................67 SMRESOURCE...........................................................................................................................................................67 Tag Descriptions ..............................................................................................................................................68

Chapter 1. Introduction
Overview
SiteManager is an Open Source Web Application Framework that leverages the power of PHP and its Object Oriented features to create a powerful base library for all types of web applications. SiteManager was designed with PHP programmers and development teams in mind. It allows them to separate the process of web site design into four steps: code creation, layout design, site implementation and site management. Step 1. Code Creation. During code creation developers construct modules of reusable source code. The modules can be shared easily between projects and developers. SiteManager simplies creating, conguring, and maintaining code modules by providing a common framework and an integrated library of tools. The library includes database connectivity, user session management, error handling, security, SmartForms, and much more. Step 2. Layout Design. During layout design, standard HTML tags, style sheets, and SiteManager XML Area Tags combine to form a powerful template engine. This engine lets developers keep the HTML layout separate from the code modules that power it. SiteManager Area Tags are used to identify important sections of the layout to the template engine. Layout based templates give designers and graphic artists freedom to create and change the appearance of the entire site without worrying about breaking the sites functionality. Advanced SiteManager developers can take reusable layout design even further through the implementation of CodePlates. Step 3. Site Implementation. During implementation developers use directive scripts to assemble modules of code and template layouts into the completed web site that clients will see. Only a few line of code are required to select which template is used, add modules into specic areas of the template, and customize each module. Step 4. Site Management. In order to facilitate maintenance of the site, almost all of the top level settings are stored in global (system wide) and local (site specic) XML conguration les. These settings include database connection information, directory locations and all of the conguration options for sessions, debugging and default extensions. Once the site has been created you can utilize the Global Conguration System to make changes and upgrades safely. As a truly Open Source project, Roadsend PHP SiteManager includes full source code, which is clean and well documented.

Feature Summary
Module System Modules are the nucleus of a SiteManager web application. They are the functional blocks of code such as a search engine, tree menu, or data driven news display that make a web site interactive or original. SiteManagers powerful object-oriented system helps programmers to design reusable modules for their websites by allowing for run time conguration. This lets the same module do different things depending on the context in which it was called or the page that loaded it. Modules even can decide not to load at all. Modules also have embedded support for cascading style sheets, client side scripting and for the extensive library of SiteManager object functions such as database access, sessions, and SmartForms. While many PHP web programmers are busy reinventing the wheel, users of the SiteManager system will have access to a growing library of modules developed by the Open Source community. Template System To support team-oriented development of web applications, SiteManager uses a powerful template engine which separates HTML, graphics and layouts from functionality. The SiteManager template engine gives developers much more than a simple "search and replace" template variable system. Using SiteManager tags, a template denes arbitrary "areas" in which to place modules of code. These tags are interpreted by the SiteManager system. A template can load specic modules into areas or

Chapter 1. Introduction

use Directive Scripts and CodePlates to extend modularity even further. Templates can also be used recursively (sub-templates), or even used inside of a module. CodePlates CodePlates take the template system a step further. CodePlates solve the problem of having to duplicate code when you use a similar template/module layout scheme in multiple pages. CodePlates are templates that already have certain modules associated with their areas. These modules are congured inside of the CodePlate. A CodePlate can be loaded as the main layout template or added to an area in another CodePlate or Template. This functionality makes creating co brands with SiteManagers template engine fantastically easy. SmartForms To truly create a "dynamic" website, input must be continually gathered from the user. This creates the need for a consistent, structured way to setup an input form, validate input, and gather the information. Creating form elements and validating input by hand is always slow and tedious. SmartForms were created as a way to rapidly create an input form using predened input entities, validate the input using predened lters, and gather the information in a structured way. SmartForms includes all the standard input types (textbox, checkbox, select list, etc) as well as some not so standard, but still often used types (date select,combo box, state list, country list, etc). It also includes many predened lters (required, number, email, credit card, phone, regexp + more) that you can attach to any input entity. You can attach any number of lters to any input entity. And, SmartForms are "database-aware" - we include entities such as DB Select list, which populates a list from a database. All entities and lters are pluggable modules of code, where all you have to do to add a new entity to the system is drop it into the correct directory. When using a SmartForm, you never have to worry about creating elements or checking for input validity by hand. You dont even have to worry about outputting the form its all handled by SmartForms. All you do is dene the form, run it, and ask it if all input was valid. Database Connectivity Roadsend SiteManager uses the PEAR Database abstraction layer for database connectivity. It is included with all versions of PHP (v4 and above). It allows connectivity to a number of different databases through a common API. SiteManager includes a middle layer of functionality that allows the PEAR DB system to be integrated within the SiteManager system. Database settings and creation of the database object are consistent with the framework for SiteManager and the Global Conguration System. Once a database connection is dened in the GCS, it is usable by all SiteManager objects. Global Conguration System All core classes in SiteManager have access to the SiteManager Global Conguration System or GCS. Stored in XML les for easy access, the default options are rst set on a global level in the Global Conguration le. When you create a new site, you can override or augment the default options in a local conguration le. User Sessions SiteManager includes its own user session management routines. The session manager can use a database or the URL to store information on each session. Sessions are maintained with cookies or a session ID passed with all internal links. Session variables are automatically included when passing information through SmartForms and regular HTTP links. Session management is available with or without a database. All session variables can be serialized, allowing complex objects to be kept persistent. Related to the session management is the Member system. SiteManager includes full support for allowing members to "log in" to the site, and all modules know if the current session is a Guest or Member session.

Chapter 1. Introduction

Security SiteManager adds a layer of protection when accessing variables coming in from a web client. A module designer is able tell SiteManager what type of variable its expecting (for example, an integer), and SiteManager will fail to run the script if the value passed for that variable doesnt match the type expected. This limits the amount of damage a user can do by passing or changing passed script variables. Support Routines Many supporting routines are included with SiteManager to help create your web application. These include: Authorization Routines Data Manipulation Routines Error Handling / Debug Routines Security Routines Misc Support Routines Object Oriented Framework The SiteManager framework is extensively object oriented, to promote reusable code and easy maintenance. The SiteManager source code is clean and well documented. Open Source Roadsend SiteManager is an Open Source project. The entire system may be distributed and used freely. The source is freely available for all to learn, review and change. Please read the license agreement available in the le LICENSE in the /doc directory, or on the web at http://www.roadsend.com/license/rpl1.txt We actively encourage all hackers to help us maintain and grow the project. Please see CONTRIBUTE in the /doc directory for more information. We continue to build our community of developers who are activity creating Modules, SmartForm Entities and Filters, example sites, and helping with maintenance of the project. In this way we will ensure SiteManagers continued growth as the leading Web Application Framework for PHP.

About Roadsend
Roadsend, Inc. is based in Fishkill, NY. We provide hosting and consulting services for Web business applications. Our website is http://www.roadsend.com, and you can reach us at <info@roadsend.com> Roadsend made the switch from PERL to PHP as its main web programming language back in 1998 around the time 3.0 was coming out. From then on it was obvious PHP would make a quick rise to the top as the best (and of course freely available) website development language. Over the course of 3 years, Roadsend developed many websites and libraries to support them. Eventually it became necessary to switch to a more structured, modularized framework. SiteManager has grown out of that system. Commercial support is available. Please see the main Roadsend website, or send us mail. The primary authors of Roadsend SiteManager are: Shannon Weyrick (<weyrick@roadsend.com>) Jon Michel (<pym@roadsend.com>)

Chapter 1. Introduction

Roadsend would like to thank all who have contributed to the project. For a full list of contributors, please see doc/THANKS in the distribution.

Chapter 2. General Information


Version Numbering
SiteManager follows a version scheme that consists of three numbers - for example, 2.1.11 The rst number (MAJOR) indicates the version of the underlying architecture. All releases with the same rst number have the same underlying architecture. Releases with different MAJOR numbers are not guaranteed to be 100% compatible with each other. The second number (MINOR) indicates the development state. If the second number is even, the version is a "stable" release. If odd, its a development release and should not be used for production quality sites. The third number (RELEASE) indicates the version within this release level. Different versions in the same release level may contain bug xes or new features, but should be back wards compatible with previous versions in the same release level.

File Extensions for SiteManager Resource Files


The following le extensions are used in SiteManager:

File Extension List


Extension: .inc File Type: PHP Library Code Extension: .mod File Type: SiteManager Module Extension: .tpt File Type: SiteManager HTML Layout Template Extension: .stp File Type: SmartForm Layout Template Extension: .xsm File Type: XML Conguration/Denition File Extension: .php File Type: Web Page Loadable PHP Script (Directive Script) Extension: .cpt File Type: CodePlate Object

Security Concerns
We recommend you make all of the SiteManager Resource Files unreadable by the webserver, except ".php" les. The rest are not meant to be seen by users. The following line will accomplish this in Apache:
# dont allow access to SiteManager files <FilesMatch "\.(inc|tpt|stp|mod|xsm|cpt)$"> Order allow,deny

10

Chapter 2. General Information

Deny from all </FilesMatch>

Check your web servers documentation for more information.

Directory Layout
Every site run by SiteManager has a common directory structure (on UNIX, this is commonly found in /var/www/myProject or /home/httpd/html/myProject)
/ /admin /modules /templates /smartForms /config /codePlates /locale /home (root) (admin / config directory) (local site modules) (local site templates) (local site smartForms) (local site configuration files) (local site codePlates) (localization files) (main page directory)

All les in /admin should be protected from reading by the webserver. None of these les located in this directory or its subdirectory should be readable by a user requesting them through the web. The best way to stop this is the stop the webserver from reading the le types found in these directories. Alternatively, you can tell the webserver not to serve any les under the admin/ directory. For even better security, you can move the directories underneath admin/ to a directory outside of the web document root. This is the most secure, as conguration les will then be unavailable to web clients. The only required le in the web root will be common.inc, which will be accessed by the directive scripts. If you need to, common.inc can be renamed to common.inc.php (just make sure your directive scripts access it this way!). SiteManager itself contains the following directory structure (on UNIX, this is commonly found in /usr/local/lib/php/)
/ /bin /cache /config /doc /lib /sfFilters /sfInputEntities /modules /skeletonSite /smartForms /tables /templates /testSite - (root) - (binary files/scripts for maintenance and automation) - (resource cache directory) - (configuration files, ie globalConfig.xsm) - (documentation, LICENSE, etc) - (main lib directory) - (SmartForm filters) - (SmartForm input entities) - (SiteManager core modules) - (skeleton site used for template when creating new site) - (site wide SmartForms) - (SQL table creation scripts) - (SiteManager core templates) - (Fully functional test site)

11

Chapter 3. SiteManager Fundamentals


SiteManager Global Variables
The following are global variables and objects setup and used by SiteManager. Remember that since they are global, PHP requires that you declare them as such within functions and class methods.
$SM_siteManager

The root SiteManager class. Use this class for high level control of the site, such as starting the Database and Session systems, Loading a Module, or Loading the Root Template. You will use this object frequently throughout your SiteManager site.
$SM_siteID

This is the unique site ID for your project. It should be dened in admin/common.inc. It is used for conguration and debug purposes. It is arbitrary, but all capital by convention. It can only contain letters and numbers, and can not contain white space. An example siteID is TESTSITE. Note that this siteID MUST match the <SITE NAME=> tag from your projects config/localConfig.xsm le!
$SM_siteName

This is the site name for your project. It is arbitrary free-text, used for debugging purposes. It may contain white space. An example $SM_siteName is Test Site 1
$SM_sessionVars

A string that contains the current valid session parameters, useful for using as GET parameters to a script. All registered persistent variables will show up here. See also SM_session::getSessionVars(), which will update this variable to the latest session values and return a copy of itself.
$SM_debugOutput

An array with debug information. Each time a call to SM_debugLog is made, and new item is added to the array. You shouldnt need to access this array directly. See the ERROR HANDLING section for more information.
$SM_rootDir

If you dont want to - or cant - place the SiteManager directory into the PHP include path, you can set this variable in
siteManager.inc. Point it to the main SiteManager root directory, and SiteManager will be able to nd its library les. $SM_develState

The current value (true or false) of the develState ag from the GCS variable "debug" SECTION of the GCS. Use this ag in an if block when you want debug information to show up only when the develState ag is on. This is useful for limiting the amount of debug information that shows up on a production server.
$SM_defaultLocale

The current value of the defaultLocale variable from the GCS variable "localization" SECTION the GCS. It determines the site wide default locale.

12

Chapter 3. SiteManager Fundamentals

$SM_clientLocale

A string (or possibly an array of strings) of the values retrieved from the HTTP_ACCEPT_LANGUAGE server variable. It will contain a list of locales the current client is using. It can used to determine which language should be used for output, for example. It is automatically used by the getText() method of SM_object to determine the default language.
$SM_debug

If debugOnVar is true in the GCS, and this variable is set to (int) 1, SiteManager will generate debug output before the main page output. See the Error Handling and Debugging section for more information.

SiteManager Root Object ($SM_siteManager)


When a project includes siteManager.inc for use in the site, a global object named $SM_siteManager is created automatically. You will use this object to perform high level functions in your site, such as:

Loading a Module Loading Layout Templates Starting the Database System Starting the Session System Accessing the Global Conguration System Debugging

What follows is a partial list of methods you may access from $SM_siteManager. For further documentation on these methods and others available through $SM_siteManager, consult the SiteManager API Documentation, available on the web at http://www.roadsend.com/siteManager

Return By Reference
Several methods in the SiteManager system return values by reference: you must use the reference assignment operator ( =& ) as in the examples shown in order to congure and use the objects returned properly. For more information on this, see the PHP documentation: References Explained (http://php.net/manual/en/language.references.php)

loadSite Method
loadSite($file)

Call this method to load in local conguration settings for your site. This is usually done in admin/common.inc See the next section, Global Conguration System, for more information on this. Also, have a look at the example common.inc in skeletonSite/admin/ directory. Note, you may call this more than once to load multiple conguration les.
Note: The <SITE NAME=siteID> tag in this le must match the $SM_siteID you dene in admin/common.inc!

The conguration les will be cached if caching is turned on.

13

Chapter 3. SiteManager Fundamentals

loadModule Method
&loadModule($moduleFile, $moduleName=)

Call this method when you wish to load and create an instance of a module. See the Directive Script and Module sections for more information on why and when you would want to do this. This function will look through your module paths (as dened in the Global Cong System) for the le named $moduleFile (automatically adding a ".mod" extension). If the actual class name of the module is different from the le name of the module, you must specify its name in $moduleName. For example, if the module le name youre loading is testModule.mod, but the module class is myTestModule, you must use the following command:
$module =& $SM_siteManager->loadModule(testModule,myTestModule);

If you wish to load a module thats contained in the le testModule, and the class name is also named testModule, you may use simply:
$module =& $SM_siteManager->loadModule(testModule);

The one exception to this rule are modules that are prexed with "SM_". These modules are part of the SiteManager package, such as "SM_rawHTML". The le is located in <SM_DIR>/modules/rawHTML.mod, but the class name is SM_rawHTML. Normally you would have to solve this discrepancy by using both parameters of loadModule(), but in this case, it will nd and load them correctly without. For example, to use the SM_rawHTML module you need simply:
$htmlMod =& $SM_siteManager->loadModule(rawHTML);

See the Module System section and example scripts for more information.

includeModule Method
includeModule($moduleFile)

Call this method when you wish to load a modules denition, but not create an instance of it. This is generally used when you need a modules denition available because you are extending it to create a new module. See the Module System section for information on Extending Modules.

rootTemplate Method
&rootTemplate($fName)

Call this method to set the root HTML layout template for use. It will search the template paths (as dened in the Global Cong System) for the template le $fName (automatically adding .tpt extension for you) Example:
$rootTemplate =& $SM_siteManager->rootTemplate(basicTemplate);

The root template may also be a CodePlate. See the Template System section and example scripts for more information.

loadTemplate Method
&loadTemplate($fName)

14

Chapter 3. SiteManager Fundamentals

Call this method to load an HTML layout template. You should only call this method directly if you plan of loading a template to place inside of another template (see the Templates section for more information on templates within templates) or from inside a module. Otherwise, you should be using rootTemplate() to load a single root template. This method will search template paths.

loadCodePlate Method
&loadCodePlate($fName)

Load a CodePlate for use. CodePlates are extensions of regular templates see the CodePlate section for more information. This method will search the codePlates paths.

dbConnect Method
dbConnect()

This method sets up database connection(s) for the rest of the system to use. It will use the database settings found in the Global Conguration System. This method does not take parameters, nor does it return anything. It should simply be called once (usually in common.inc) to create the database connection(s). See the Database Connectivity section for more information.

startSessions Method
startSessions()

This method starts sessions. It should be used when you wish to keep certain variables persistent between links and forms, or to use the member system. You almost always want to use this, and it should be called in common.inc. See the Sessions section for more information.

addPersistent Method
addPersistent($varName)

Use this method to specify that a variable should be kept persistent throughout the system. It should be called only after startSessions() is called. For example, if you would like to keep the variable "userName" persistent for a user:
$SM_siteManager->startSessions(); $SM_siteManager->addPersistent(userName);

All session-aware modules will now keep this variable intact automatically, as soon as it gets a value. Note, you may also setup persistent variables in the Local Site Conguration le. They should be in the "pVars" SECTION see the Global Conguration System section, or the testSite/admin/config/localConfig.xsm example le for more information. Depending on your session conguration, the variable type of the persistent variable value can be any valid PHP type (string, int, array, object, etc). See the Sessions section for more information.

15

Chapter 3. SiteManager Fundamentals

completePage Method
completePage()

This method should be the last method called in a Directive Script. It runs all modules, collects their output, and inserts it into the templates. See the Directive Script section for more information, or look at the example scripts in skeletonSite/ and testSite/ directories.

fatalDebugPage Method
fatalDebugPage()

This method will generate a very informative debug page. It should be called in place of completePage() ie, AFTER all modules have been added and congured. Instead of showing the nal HTML output as completePage() does, it will show all information on how the page WOULD have been generated. That is, it will list all Global Conguration data, what templates are in use, which modules are loaded, how the modules are congured, what SmartForms are in use in these modules, and how the SmartForms are congured. This function should not be used on live production sites.

Global Conguration System


SiteManager uses (at least) two conguration les to congure paths, ags, and a variety of other options. You may also add your own sections and variables to the local conguration le, or create an entirely new one. The values in these les are the basis for the SiteManager Global Conguration System, or GCS. GLOBAL settings are the default settings that will be used for all sites that use SiteManager. If a conguration value requested for a particular SITEID doesnt exist, the GLOBAL setting will be used instead (if found). When siteManager.inc is included, the GLOBAL settings are read in by the root $SM_siteManager object. It reads it into an SM_config object accessible through $SM_siteManager->siteConfig. LOCAL settings are read from a le in the sites admin/config directory of every site. The main le is usually localConfig.xsm but is denable in common.inc If you add other XSM conguration les, they should also be located in the admin/config directory.
admin/common.inc will generally tell $SM_siteManager to read in the LOCAL settings using the $SM_siteManager->loadSite() method. At least one call to loadSite() should be made - but you may load as many local

conguration les as you like. Conguration les can be cached - see the section on caching for more information. Every site that uses SiteManager is assigned a SITEID ($SM_siteID). This ID is used by the conguration system to determine which settings to use for this site. It is also used by the debug system when outputting errors and warnings.
$SM_siteID should be assigned in admin/common.inc BEFORE siteManager.inc is included.

SiteManager uses a custom XML le to describe conguration values. Conguration is basically a list of key/value pairs, broken up into various sections. Section examples include:
dirs localization db flags directory settings localization settings database settings misc flags

16

Chapter 3. SiteManager Fundamentals

sessions pVars

- session settings - persistent variables

The easiest way to explain the settings is to take a look at the XML le that actually stores the variables:
<SITE name="GLOBAL"> <SECTION name="dirs"> <VAR name="base" value = "/usr/local/lib/php/siteManager"/> <VAR name="libs" value = "/usr/local/lib/php/siteManager/lib"/> <VAR name="modules" value = "/usr/local/lib/php/siteManager/modules"/> <VAR name="modules" value = "/usr/local/lib/php/siteManager/modules/test" /> </SECTION> <SECTION name="db"> <VAR name="dbType" value = "mysql"/> <VAR name="persistent" value = "true" /> </SECTION> <SECTION name="pVars"> <VAR name="SMuserName" value = "" /> <VAR name="SMaddDate" value = "" /> </SECTION> </SITE>

This excerpt from globalConfig.xsm shows 1) how the XML structure is laid out 2) how variables are dened. To access a variable from $SM_siteManager->siteConfig in module code, you would use one of two function calls:

getVar Method
$SM_siteManager->siteConfig->getVar($section, $name, $mergeGlobal=false, $sectionID=)

This function should be used when a single variable is required. For instance, to retrieve the main lib directory from section dirs, you would use:
$libDir = $SM_siteManager->siteConfig->getVar(dirs,libs); $libDir would then be a single string variable that contains the main lib directory.

Notice you can list VAR names more than once in the cong le (such as the modules VAR in the example above). When this happens, an array is created. For example, to get the two modules directories from the global cong you would use:
$moduleDirs = $SM_siteManager->siteConfig->getVar(dirs,modules); $moduleDirs is now an array of values that contains the two values listed in the conguration le.

The $mergeGlobal option is used to tell the SM_config object whether you want to just use the LOCAL settings, or both the GLOBAL and LOCAL settings. Usually, you want the local settings to override global settings, but sometimes youd like to have both. Use this option to control that. When set to TRUE, you will receive an array of values that consists of all values set for that variable name in both GLOBAL and LOCAL context. The $sectionID is used when a section denes itself multiple times, with different IDs. If you need to, you can use this parameter to specify which ID youre accessing. Normally, you can leave this parameter off. See the section below regarding multiple IDs.

17

Chapter 3. SiteManager Fundamentals

getSection Method
$SM_siteManager->siteConfig->getSection($section, $sectionID=)

Use this function to retrieve an entire section at a time. For example:


$dbSettings = $SM_siteManager->siteConfig->getSection(db);

This will return a hash that can be used in the following way:
$dbType = $dbSettings[dbType]; $pers = $dbSettings[persistent];

This function automatically merges GLOBAL and LOCAL settings. The $sectionID is used when a section denes itself multiple times, with different IDs. If you need to, you can use this parameter to specify which ID youre accessing. Normally, you can leave this parameter off. See the section below regarding multiple IDs.

setVar Method
You may also SET a variable through the global conguration system. This can be used to override a value read in from the cong le.
$SM_siteManager->siteConfig->setVar(dbSettings,dbType,mysql);
Note: You cannot change GLOBAL variables this way (only those LOCAL to this siteID)

Variable Replacement
To increase maintenance and portability, you can use variable replacement in all SMCONFIG les. Once you dene a VAR name/value pair, you may substitute the value in at a later time, by accessing much the same way you do as PHP variables. This is the way the globalConfig.xsm and localConfig.xsm les are done in the "dirs" SECTION:
<SECTION name="dirs"> <VAR name="smRoot" <VAR name="base" <VAR name="config" <VAR name="libs" <VAR name="modules" <VAR name="templates" <VAR name="smartForms" <VAR name="sfEntities" <VAR name="sfFilters" </SECTION>

value value value value value value value value value

= = = = = = = = =

"/usr/local/lib/php/siteManager/" /> "{$smRoot}"/> "{$base}config/"/> "{$base}lib/"/> "{$base}modules/"/> "{$base}templates/"/> "{$base}smartForms/"/> "{$base}lib/sfInputEntities/"/> "{$base}lib/sfFilters/"/>

You could use this feature in the following way:


<VAR name="mySiteName" value="Bobs Site" /> <VAR name="errorHeader" value="{$mySiteName}: There was an error" />

18

Chapter 3. SiteManager Fundamentals

By default, variable substitution only works for variables dened within the current SECTION. To reference a variable from another section, use the format:
<SECTION name="firstSection"> <VAR name="testVar" value = "value of testVar" /> </SECTION> <SECTION name="secondSection"> <VAR name="otherTestVar" value = "{$firstSection.testVar}" desc="sets value to value of testVar from SECTION firstSection" /> </SECTION>

In addition, if you try to use a variable that wasnt dened beforehand in this le, it will automatically attempt to substitute the current global PHP value of that variable. that means you can substitute in any PHP or server environment variable. You can also use an associative array (hash) in this context. For example:
<SECTION <VAR <VAR <VAR

name="dirs"> name="base" name="config" name="libs"

value = "{$HTTP_SERVER_VARS[DOCUMENT_ROOT]}/siteManager/"/> value = "{$DOCUMENT_ROOT}config/"/> value = "{$base}lib/"/>

... etc

Section IDs
It is possible for SECTIONs to be dened multiple times, if you specify an additional attribute (id). You may then either 1) Specify a sectionID when accessing that section (or a variable in the section), in which case you would receive only the value from the variable in the sectionID you requested or 2) Dont specify a sectionID, in which case you would receive the value of the variable you requested from all IDs, merged into one array (so that it appeared that there was only one section with multiple variables specied with the same name). This is used, for example, by the db section to dene multiple database connections:
<SECTION name="db" id="default"> <VAR name="dbType" value="mysql" /> <VAR name="defaultConnection" value="true" /> <VAR name="DSN" value = "mysql://testUser:testPass@localhost/test" /> <VAR name="persistent" value = "true" /> </SECTION> <SECTION name="db" id="secondary"> <VAR name="dbType" value="mysql" /> <VAR name="DSN" value = "mysql://testUser:testPass@localhost/test" /> <VAR name="persistent" value = "true" /> </SECTION>

If youre not accessing a section with multiple ids, you dont have to worry about this feature (leave that parameter blank when calling getVar() or getSection())

19

Chapter 3. SiteManager Fundamentals

SM_Object Base Class


Several SiteManager objects extend the SM_object base class. This class gives a set of methods used for a common conguration system, database access, session access, language independence, and caching. All classes that extend this class receive the follow methods. Check the SiteManager API for more information on how to use them.
addDirective($key, $val) - add a key/value pair configuration directive configure($cDir) configure the object all at once with an array of key/values loadConfig($configFile) - load configuration data from XML file loadLanguage($langFile) - load language independent text definition XML file dumpInfo() - debug class info dump debugLog($msg) - add text to the class debug log getClassLog() - return output of class debug log getText($id) - get a string of text by a language independent id saveSerial($file, $prefix, &$data) - cache PHP data to the SiteManager cache directory loadSerial($file, $prefix, &$data) load cached PHP data from SiteManager cache directory

They also include the following class variables:

$directive. $directive is a standard associative array ie, a list of key/value pairs. It is used to congure the object. addDirective(), configure(), and loadConfig() all work to setup this array. Therefore, any object that inherits this class, such as SM_modules, can be congured through:
$module->addDirective(key,value);

This system is used extensively throughout SiteManager, and we recommend using it as an alternative to class variables when creating modules and other code. There are benets to doing so: 1. Its easier to create reusable code, because classes that have several parent classes are easier to maintain and congure 2. Common, expandable system for dening a conguration scheme for objects 3. Key/value pairs can be loaded from an XML le using built in methods 4. You can pass and receive directives easily from other objects that descend from SM_object $dbH. This variable is a reference to the current database handle. This is used by the module system, SmartForms, etc. as a common way to access the default database connection. $dbHL. This variable is a hash of all available database connections, indexed by the connection ID. If database support is on, there should be at least one entry with the index default. See the Database Connectivity section for more information on using this. $sessionH. This variable is a reference to the current session manager, if available. Its is an object of type SM_session. See Session Management section for more information. $classLog. This variable is an array that contains a list of debug messages for the class. It is populated with the SM_object::debugLog() method, and displayed with the SM_object::getClassLog() method. $liText. This variable is a multidimensional hash that stores different translations of text the object will use for output. It has two keys: [$locale][$textID]. It is populated with the SM_object::loadLanguage() method, which reads information from an XML le. You should not access this directly, however use the getText() method instead.

20

Chapter 3. SiteManager Fundamentals

Internationalization Support
All SM_object descendants (include Modules, SmartForm entities, etc) include support for internationalization - currently, the ability to support multiple languages for output. This is done by loading an XML based language description le. The le is organized so that each block of text to be displayed is assigned an arbitrary ID string, and then listed multiple times in the le in different language sections, translated accordingly. The text may then be retrieved with the getText() method, in the desired (or default) language, by its ID string, and nally written for output. Because of the format of the XML le, translations can be added at any time, allowing for great scalability. The code need not change at all when a translation is added, since the block of text will still be accessed by the same ID string. For the le format of the XML language le, see Appendix B. For an explanation of using the loadLanguage() and getText() methods, see the Module section under Multilingual Support.

Directive Scripts
Directive scripts are the high level link between Modules and Templates. They are described here so that as you go through the Modules and Template section, you can better understand the parts they play. A directive script is an actual "page". It will be the script that the webserver loads rst when an URL is accessed. The directive script is generally very short - in fact, as a general rule, you want to do as little logic here as possible. Its job is to: 1. Include the sites common.inc, which in turn sets up the conguration for this site and includes the SiteManager libraries 2. Load the modules to be included in this page 3. Congure the modules 4. Load the template(s) or CodePlate(s) to be used for this page 5. Add the modules to the correct areas in the correct order 6. Output the nal page Generally, depending on the amount of conguration to be done to the modules, this can be done in 10-15 lines of code. When the command is given to "run" the page and output it, the following happens: 1. All modules run through their conguration routines (moduleConfig()) 2. All modules run through their "think" routines (moduleThink()) 3. HTML and JavaScript output is collected from each module 4. The output from the modules is placed in the proper areas in the template A sample, annotated directive script follows (yes this is the entire page):

<?php

// include site configuration file, which includes siteManager libs include(../admin/common.inc); // create a new module. notice, returns a reference!!

21

Chapter 3. SiteManager Fundamentals

$mod1 =& $SM_siteManager->loadModule(rawHTML,SM_rawHTML); // configure the module $mod1->addDirective(output,<B>Hello World</B>); // create root template. notice, returns a reference!! $layout1 =& $SM_siteManager->rootTemplate("basicTemplate"); // add our module to area areaOne $layout1->addModule($mod1, "areaOne"); // finish display $SM_siteManager->completePage(); ?>

Modules
Overview
Modules are pieces of code that get executed so that their output is placed into a template. All modules are extended from the same base class, and have a common structure. The base class for all objects is SM_module Extending this class to create a module gives that object several important features: 1. It allows the new object to be added to a template or codePlate, where its output will be added into an area of the template 2. It sets up the object to receive input from SmartForms and other modules 3. It allows the object to create and use a SmartForm 4. It allows JavaScript code to be taken from this module and included with the main JavaScript output section of the template this module will show up in 5. It allows code to use the database and session systems available through SiteManager All modules, upon creation, are assigned a Module Prex. This prex is used by the system to differentiate between modules. It is used, for example, to avoid variable naming conicts when using modules that congure for themselves variables of the same name. The module prex is used behind the scenes, and generally should not have to be referenced at all. There is only one required method that must be implemented for the module to work:
moduleThink() - the "brains" of the module

Although not required, generally a module will also implement:


moduleConfig() - congure the module

moduleCong Method
For a module to be reusable in different contexts, it should be able to change its output and/or the way it looks when it outputs on the y. This means it needs to be congurable at run time through directive scripts (pages). Enter the moduleConfig() method.

22

Chapter 3. SiteManager Fundamentals

One important difference between moduleConfig() and moduleThink() is that the moduleConfig() method is automatically run when a module is loaded through $SM_siteManager->loadModule(), and the moduleThink() method generally isnt run until $SM_siteManager->completePage() is called. This allows the user to re-congure any defaults that were dened in moduleConfig() before running the actual module. There are three main conguration options to be done in moduleConfig(). Of course, the module designer may do any conguration code they need in this space whats important is that this function is executed BEFORE the moduleThink() function. Here is a sample moduleConfig() method:
function moduleConfig() { // load base configuration files $this->loadConfig("moduleSettings");

// load some directives from XML file

// directives // these are defined and overridden by DIRECTIVE SCRIPTS $this->addDirective(tableName,); // table name to operate on $this->addDirective(maxVisibleSize,30); // max size of a form element (default) $this->addDirective(dataField,); // field to operate with (primary key) $this->addDirective(siteName,Test Site); // site name // variables this module will use for configuration (these are all made up and arbitrary) // thee are setup by GET and POST vars $this->addInVar(widgetType,0); // which widget type should we use? $this->addInVar(format,basic); // which "format" to use // styles we will use in this module $this->addStyle(linkText); $this->addStyle(baseText);

// style used when outputting HTTP links // style used for plain text

// if this module requires database functionality, // check for a proper connection if (!isset($this->dbH)) { SM_fatalErrorPage("this module requires a database connection, which wasnt present!"); } }

Directives. Often a module designer wishes to let the user congure how the module should act, such as whether it should output in a table, whether it should be run in "advanced" or "basic" mode, whether it should end the script after a form loads or transfer to another page, etc (all arbitrary examples). These settings are done through the $directive variable and addDirective() method. Setting a directive involves using the functionality inherited from SM_object. For example, to add a directive to a module:
$mod1->addDirective(siteName,Test Site);

Using a directive in the module code is as easy as referencing the $directive hash variable. For example, the code:
$this->say("Welcome to {$this->directive[siteName]}!");

23

Chapter 3. SiteManager Fundamentals

is much more reusable in a module than hard-coding:


$this->say("Welcome to Test Site!");

It allows others to use the module and congure it without ever having to look at the internals of the way it works. You may also use the loadConfig() method inherited from SM_object. It allows you to have an external le that denes directives. If you are going to use loadConfig(), you should call this rst in moduleConfig(), so that later addDirectives will override those loaded in the external cong le. Using loadConfig(), you can setup certain directives that ALL modules should use such as "tableBorder" or other cosmetic options. Then, simply call loadConfig() in each of your modules. This way you only have to dene those options in one place, and when they need to change, you can change them all in one place. See the SM_object section for more information on
loadConfig()
Tip: Directives are different from INVARS (described below) in that they are meant to be congured and overridden by a programmer who is using the module to create a page.

inVars. If the module is to take any input (ie, from HTTP_POST_VARS of HTTP_GET_VARS) it must declare which variables it will be looking for using the class variable $inVar and method addInVar() It must declare inVars for several reasons:

SiteManager will be able to check the inVar for correct typeness. This allows SiteManager to (for example) make sure the integer variable youre expecting in variable foo wasnt actually passed as a string. This is a good security measure when youre taking a integer variable that will be used as an index in an SQL query, and you want to make sure someone isnt intentionally making the value a string of SQL commands. SiteManager will be able to check for conicts with other modules in the page. If you happen to be using two modules with the same inVar, but they are meant for different uses, SiteManager can warn you SiteManager will be able to keep variables from different modules who werent designed to work with each in tact. This allows you to place modules into a page without the modules worrying about passing variables they werent designed to know about. You access persistent session variables from your module by declaring an inVar with the same name as the declared persistent. You can access SmartForm variables passed from your forms in your module.

For example, if a module is expecting a "widget type" to be passed to it, through the "widgetType" variable such as: http://localhost/testScript.php?widgetType=5 then it should declare that it will use this variable in moduleConfig():
$this->addInVar(widgetType,0,int);

The second parameter is the default value to use, if one wasnt passed to the script. If this parameter is left blank, the default value is blank. The optional third parameter tells SiteManager that widgetType should be a number. If the script is called and widgetType is set, but its actually a string value, SiteManager will not let the script load. This is a security measure. Also see the section below about Propagating InVars.
Note: Variables passed to scripts should NOT be accessed directly, as in:
global $widgetType; - or -

24

Chapter 3. SiteManager Fundamentals

$HTTP_GET_VARS[widgetType];

The example above is incorrect - use the getVar() function as follows:


$widgetType = $this->getVar(widgetType);

Again, using this system lets the module system handle naming conicts, session variables, and other behind the scenes voodoo.
Tip: INVARS are different from Directives in that they are meant to be variables that change based on how the script was accessed, ie they get setup either through GET or POST variables passed to the script, or through session code.

Styles. In order to promote re-usability, and module should be able to output itself in a manner thats congurable without touching the internals of the module. One way to do this is by using CSS Style Sheets when outputting HTML. This allows a user to use the module and change the way it looks simply by dening certain style sheet elements in their template. This way, they never have to touch the module code. All styles to be used in a module should be declared, in much the same way as INVARS, but with the addStyle() method:
$this->addStyle(headingText); // style used when outputting section headings $this->addStyle(linkText); // style used when outputting HTTP links

A module has a hash called $style. It contains a key/value pair that links two properties: 1. Internally named style sheet element 2. Externally named style sheet element This is done so that the module can reference a particular style sheet element name that may change later, when the module is congured. For example, if the module is to output a text or a link:
$this->say(<A HREF="test.php" CLASS=".$this->getStyle(linkText).">Test Link</A>);

$this->getStyle and $this->say reference the internal name of the style but later on, when the module is congured, the actual style sheet name it outputs may change. For example, then the user congures the variable in the Directive Script (page), they may wish to change "headingText" to be "boldRed", which is what they have dened in their style sheet:
$mod1->setStyle(headingText,boldRed); $this->say("Section One: Test Information","headingText");

When the module is run the following is displayed: <SPAN CLASS="boldRed">Section One: Test Information"</SPAN>

moduleThink Method
The required method to implement for a module is called moduleThink(). This method is what gives the module functionality. Here is a simple example:
function moduleThink() {

25

Chapter 3. SiteManager Fundamentals

// output whats contained in the directive output $this->say($this->directive[output]); }

When this module is run, it will buffer output. NO MODULE SHOULD EVER USE echo or print! This is because the module must save its output for later when it will be placed into the correct area of the template.

Warning
A Module should never echo or print output!

Instead of echoing output, use the method say() or saybr() thats part of the SM_module class:
$this->saybr("This is module output");

DO NOT use:
echo "This is module output";

All output in SiteManager is buffered, so you wont see echoed output unless you have Debugging output turned on. See the Debugging section for more information on that. Another (special) method of output is the sayJS() function. This is used for the module to output JavaScript code. It requires its own function so that the JavaScript code shows up in the correct JavaScript area of the template. sayJS() works just like say(). You do NOT have to include any <SCRIPT> tags when using sayJS, the module system does this for you. See the Template section for more information on this. Other than that, the moduleThink() code may do anything youd like. You of course have the full power of PHP and all its extensions at your disposal. Here is a list of SiteManager helper functions that will be useful when designing modules. See the SiteManager API for more information on each method.
$this->say(); $this->saybr(); $this->sayJS(); $this->getVar(); $this->newSmartForm(); $this->getStyle(); $this->getText(); $this->directive[];

- use to buffer module output - use to buffer module output with a <br> tag - use to buffer JavaScript output - use to access a variable declared as an INVAR - create a new SmartForm for this module (see SmartForm section) - retrieve a style sheet element name - use to retrieve language independent text by ID - retrieve a directive

canModuleLoad Method
Sometimes a site designer will want to load and display a module only under certain circumstances - for example, if a particular variable was passed to the page. One way to do this is add logic code either to a directive script or a CodePlate that decides when to load and add the module to the template.

26

Chapter 3. SiteManager Fundamentals

It can be more convenient, however, to always load the module in the directive script, and let the module itself decide whether it should display itself or not. This is a more portable method, as the module has full access to inVars and session variables, and you wont need to worry about adding display logic to every directive script you use this module in. For a module to decide not to display, it must implement the canModuleLoad() method. If this method exists, it is run after moduleCong, but before moduleThink. This allows it to be congured through directives, and allows access to declared inVars. The method should return either true or false. If it returns true, the module will run its moduleThink() code as normal. If it returns false, the moduleThink code will not run, and no output will be displayed by the module. Here is an example (module excerpt):
/** * configure the module. run before moduleThink */ function moduleConfig() { // Directives $this->addDirective(tableBorder,1); $this->addDirective(tableBgColor,#eeeeee); $this->addInVar(menuID,0,int); } /** * * only load if our inVar is set to 8 * */ function canModuleLoad() { return ($this->getVar(menuID) == 8); }

In this example, the module would only display itself if menuID were passed to the script, it was a number, and the value was 8.

Database Connectivity
Accessing a database in the modules is easy. When you extend the SM_module class, a class variable called $dbH is available automatically. Either this variable is NULL, in which case there is currently no available database connection, or it is a reference to the current default database connection. There is no need to make a connection by hand in a module. If your module requires access to a database, you should check for connectivity in moduleConfig, using:
// if this module requires database functionality, // check for a proper connection if (!isset($this->dbH)) { SM_fatalErrorPage("this module requires a database connection, which wasnt present!"); }

27

Chapter 3. SiteManager Fundamentals

Then, in moduleThink(), you are guaranteed access to the database. You may use $this->dbH as a normal PEAR Database object. For example:
$SQL = "SELECT * FROM testTable"; $rh = $this->dbH->simpleQuery($SQL); if (DB::isError($rh)) { SM_debugLog($SQL,$this); SM_fatalErrorPage("There was a problem with the query!"); } while ($rr = $this->dbH->fetchRow($rh)) { $this->say($rr[firstName].<br>); } $this->dbH->freeResult($rh);

Youve now just written a data aware module that can be used in any SiteManager system, and on any database system that PEAR supports. Multiple Database Connections. SiteManager has the ability to have more than one active database connection. $this->dbH is always a pointer to the default database connection. If you wish to access a database connection handle other than the default, you use the $this->dbHL hash, and reference the database ID, such as:
$SQL = "SELECT * FROM testTable"; $rh = $this->dbHL[secondary]->simpleQuery($SQL); if (DB::isError($rh)) { SM_debugLog($SQL,$this); SM_fatalErrorPage("There was a problem with the query!"); } while ($rr = $this->dbHL[secondary]->fetchRow($rh)) { $this->say($rr[firstName].<br>); } $this->dbHL[secondary]->freeResult($rh);

See the Database Connectivity section for more information on setting up and accessing multiple database connections.

Session Functionality
Much like the database functionality, session functionality is contained automatically in the variable $this->sessionH To make your modules "session-aware", you should use the hLink() method.
hLink($link, $text, $class=, $extra=) hLink() will make a <A HREF> link to $link, around text $text. It will use a style of $class (from your $this->style array) if specied. $extra will place extra text into the <A> tag if you need it (such as TARGET="") hLink will automatically append the current session variables onto your link (even if $link contains variables of its own).

It should be used in the following way:


$this->say($this->hLink("newScript.php?user=1","Link To New Script"));

Using hLink() instead of hard coded $this->say("<A HREF=" .. tags will make your module session-aware. There are other session functions you may use in your modules, such as puLink() which will make your link show up in a JavaScript pop-up window. See the SiteManager API reference for the full list of available methods.

28

Chapter 3. SiteManager Fundamentals

Take a look at the /modules directory for some examples of modules. Accessing Persistent Variables. To access a variable that has been declared as persistent variables with the session system, simply declare an inVar with the same variable name as the persistent variable. Then, use $this->getVar() method to retrieve it. Using this method, you can access strings, arrays, objects and any other variable you would like to keep persistent.

Module within Modules


Inside of the moduleThink() method, you can of course use any standard PHP functions, as well as function libraries you may have written and included. But another way to increase the re-usability of your code is to write SiteManager modules that are to be used specically inside of other modules. The benets of doing this instead of writing normal functions and including them is that you receive the same Global Conguration System abilities as other modules, plus you have access to the current Database and Session handles. To use a module within a module:
// declare $SM_siteManager to be global global $SM_siteManager; // load the module through SM_siteManager like normal (make sure youve // defined it as global though!) $testModule = $SM_siteManager->loadModule("testModule"); // call the run() method on the module $tOutput = $testModule->run(); // gather its output, and say() it into your own $this->say($tOutput); $this->sayJS($testModule->getJS());

The code for the module to be loaded can be any normal module code. However, when designing a module to be run within other modules, make sure you turn off the outputInTable directive otherwise youll get two module tables inside of one module.
// (in sub-modules moduleConfig()) $this->addDirective(outputInTable,false);

Extending Your Modules


All modules extend the base SM_module class, which gives them a common framework for integrating into SiteManager sites. To promote reuse of code, you can also extend your own modules to provide other modules with common functionality. To do this, you create a normal SiteManager module, but instead of extending SM_module, you will extend your new base module (which of course extends SM_module itself).
<? class testModule extends SM_module {

function moduleConfig() { // configure module }

29

Chapter 3. SiteManager Fundamentals

function moduleThink() { // base think code, possibly blank } function extraFunction() { // extra base functionality } } class extendedModule extends testModule { function moduleThink() { // override custom base modules think function // call function from base module $this->extraFunction(); } } ?>

Normally, however, you wouldnt want to keep both the base module and the extended module in the same le. You might put the base module in a le called testModule.mod and the extended module in a le called extendedModule.mod - both in your sites modules/ directory. Note that when you do this, you must make sure that when you dene your extended module, it already knows the denition of your base module. You do this through the $SM_siteManager->includeModule() method. It will search your current module paths for the base module you specify. Note, however, you must declared $SM_siteManager global rst.
<? global $SM_siteManager; $SM_siteManager->includeModule(testModule); class extendedModule extends testModule {

function moduleThink() { // override custom base modules think function // call function from base module $this->extraFunction(); } } ?>

You can now call $SM_siteManager->loadModule() on your extended module in the normal way. For an example of extending modules, look in the testSite/admin/modules directory at base.mod and extendedMod.mod

30

Chapter 3. SiteManager Fundamentals

preThinkList and postThinkList


A common way to use extended modules is to create a base module that denes how the module will look once its output is complete (ie, by wrapping it in a table of some sort), and then extending that module every time you would like the functionality of a module to wrapped in the same table. This is common in Portal systems, for example, where all the modules might be in a common table layout: a table header the same color, a title in the header, and button in the header for "closing" that module. One way to do this is create a module with two extra methods: moduleHeader() and moduleFooter(). The header would contain the code to output the top of the common TABLE, the footer would contain the code to close it. If you extended this module, you could then call $this->moduleHeader() at the start of your moduleThink(), and $this->moduleFooter() at the end. This would wrap the output of your extended module in the table from the base module, keeping the two separate which will aid maintenance and modularity. However, the module designer who is extending the base module is still required to know which methods to call at the start and end of his moduleThink() to make the module output correctly. If the designer of the extended module is not the same as the designer of the base module, it might not be clear which methods he is to use. To solve this problem, SiteManager allows the designer of the base module to have certain class methods run automatically when the module is extended. In the above example, the designer of the base module would have moduleHeader() run automatically before moduleThink(), and moduleFooter() run automatically AFTER moduleThink(). This allows the designer of the extended module to not have to call them at all, and therefore not have to worry about which methods he needs to call the make his extended module output properly. SiteManager handles this through two arrays: preThinkList and postThinkList. They are simply an array of strings. The values of the strings should be the function names to run before and after moduleThink() (respectively). The functions do not take arguments, and will be run in the order they were added to the array. You can add as many functions to each list as you would like. Here is an example of a base module that illustrates the example above:

/** * a base module. extends base SM_module class. * */ class baseMod extends SM_module { /** * configure the module. run before moduleThink */ function moduleConfig() { // configure which methods will be run automatically $this->preThinkList[] = moduleHeader; $this->postThinkList[] = moduleFooter; } /** * this function contains the core functionality entry point for the module. */ function moduleThink() {

// virtual - this will be written by the extending module designer

31

Chapter 3. SiteManager Fundamentals

} // this function will run automatically before moduleThink() // the designer of the extended module need not call it directly function moduleHeader() { // notice you can use directives here that may be setup by the extended module $this->say("<TABLE BORDER=1><TR><TD ALIGN=CENTER>{$this>directive[title]}</TD></TR><TD>"); } // this function will run automatically after moduleThink() // the designer of the extended module need not call it directly function moduleFooter() { $this->say("</TD></TR></TABLE>"); } }

and here is the extended class

/** * an extended module. extends baseMod class. * */ // include base module global $SM_siteManager; $SM_siteManager->includeModule(baseMod); class extendedMod extends baseMod { /** * configure the module. run before moduleThink */ function moduleConfig() { // configure parent::moduleConfig(); // other configuration here... $this->directive[title] = Extended Module Test; } /** * this function contains the core functionality entry point for the module. */ function moduleThink() { $this->saybr("This output is being displayed by the extended module. It is wrapped in a table generated by the base module");

32

Chapter 3. SiteManager Fundamentals

$this->saybr("The generation of the table was done automatically through preThinkList and postThinkList methods"); } }

InVar Propagation (read-write inVars)


While designing modules you may nd it necessary to have not only "read-only" type inVars, where your module is simply reading a value that was passed to the script, but also "read-write" type inVars, where you want your module to not only read the current value of a variable, but make that value available to other modules on the current page. Propagated inVars were designed so that modules placed together on a page that werent designed to work together still function correctly. The best way to illustrate this is by example. Say you have three modules on a page. The rst one is a menu, the second is a text viewer. When you click on an item in the menu, it displays some text in the viewer on the right. The viewer module declares an inVar called "id". When you click on a menu item, it reloads the page with the proper "id" set which the textViewer uses to display the correct content. Now, the third module isnt related to the modules above. Its a login box with a SmartForm. Since its a SmartForm it has to reload itself, which means it will post to PHP_SELF. So lets say someone comes to this page, and selects an item in the menu, with id=5. Now, once they do that, they decide to login, so they type in their username and password in the third module, and hit submit. Now heres the trouble. They had previously clicked on a menu item, which set id to 5. But the login module doesnt know anything about "id", it wasnt built to use it, and therefore wouldnt have added it as a hidden on its own. So once they click submit, the id variable would have been erased, and the user would no longer be on the page they selected from the menu. Lets say they typed the wrong password, so the page reloads a couple times. It would be nice if id stayed 5 the whole time because the SmartForm added a hidden for the id variable, even though the login module doesnt know anything about it. This is what propagated (ie, "read-write") inVars do. The login SmartForm will automatically add a hidden called id and set it to 5, because it knew that another module on the same page was using this inVar. There is a conguration variable propagateInVarDefault in the ags section of the GCS. This determines the default settings of when inVars will propagate. If this is set to false, you must explicitly set which inVars to propagate. If this is set to true, all inVars will propagate by default and you must explicitly tell SiteManager which NOT to propagate. You most likely want to keep the default setting of not propagating by default, and only turning on propagation for specic variables that should. You can also turn set inVar propagation either for a whole module, or on an inVar by inVar basis. Consult the Module section or the API docs for more information.

Multilingual Support
Because the Internet is a global network, your sites (and modules) need the ability to display in multiple languages. SiteManager handles this by allowing you to dene and load an XML language description le. The language XML le format is described in Appendix B. Once you have a language le dened, you load it into your module with the loadLanguage() method, which is inherited from SM_object. This method will search your "locale" paths. It may be called in either moduleConfig() or moduleThink(). After loading your language denitions, you use the getText() method to retrieve your text in the desired language, by the ID dened in the language le.

33

Chapter 3. SiteManager Fundamentals

If you dont specify which language getText() should use, it will default to either 1) the preferred language of the current user on the site 2) the default for the site 3) the default for the module. To dene a default for the module, add a directive defaultLocale in the moduleConfig() section of your site. Once you have retrieved it, you may then say() the text as normal.
$this->loadLanguage(testSite.lang); $bText = $this->getText(text1); // browser detected language

$eText = $this->getText(text1,en_US); // test specification of English $dText = $this->getText(text1,da_DK); // test specification of danish $this->saybr("English: $eText"); $this->saybr("Danish: $dText");

See the Internationalization Support section of SM_object and Appendix B for more information.

Module Design Tips


moduleThink()

should never exit, unless its a fatal error (and even then, call SM_fatalErrorPage()) or your transferring

to another script.

if calling header("Location: http://sampleUrl.com"), from within moduleThink(), make sure you exit(); afterwords dont use echo or print to output text for your module, use $this->say() or $this->saybr() use $this->hLink() for A HREF links to make your module "session-aware" make use of directives instead of hard coding conguration values into your module, so they can be congured later make use of loadLanguage() and getText() methods to add language independence to your modules

Templates
The template system is used to separate the module code from the way the nal page will look to the end user. SiteManager allows you to take a "template" of static HTML, dene arbitrary "areas", and dene which modules should go in which areas, and in what order. You may have as many areas as you like, and any number of modules in any area. You can also add other templates to areas (see Templates in Templates). A "template" is really just a static HTML le with a custom <SM> tag placed in them:
<SM TYPE="area" NAME="areaName"> <SM TYPE="module" NAME="moduleName" DIRECTIVES="key1=val1,key2=val2"> directly replace this tag with a module <SM TYPE="javaScript"> replace with JavaScript code collected from modules <SM TYPE="htmlTitle" NAME="Default Title"> replace with directive htmlTitle, or use default if undefined

- define an area -

34

Chapter 3. SiteManager Fundamentals

<SM TYPE="htmlBody"> replace with HTML BODY tag, using directives bodyBGCOLOR, bodyLINK, etc @@sessionVars@@ special tag. directly replaces itself with current session variables

Here is a simple example template:


<html> <head> <SM TYPE="javaScript"> </head> <body bgcolor="#ffffff"> <a href="staticLink.php?@@sessionVars@@">Test Link With Session Variables</a> <table> <tr><td><SM TYPE="area" NAME="areaOne"></td><td><SM TYPE="area" NAME="areaTwo"></td></tr> </table> <SM TYPE="module" NAME="footerModule"> </body> </html>

This simple template sets up 2 areas, a JavaScript area, and a footer module call. All area names are arbitrary. Here weve used "areaOne" and "areaTwo", we could just as easily have used "leftArea", "rightArea". The area name will be reference in the directive script, when you are adding modules. The javascript tag is optional, but if it appears it should be in the <HEAD> section of the HTML. This will allows modules and SmartForms to plug in javascript functionality.
@@sessionVars@@ is a direct search-and-replace convenience tag. It will replace itself with the current list of session variables (if

any). It exists so that one does not have to create a module merely to output static links with session variables included. If an area is listed in a template, but a module is not added to it by the time the page is displayed, the area tag is removed from the template and ignored. A template is loaded in the following fashion (usually in a directive script):
$template =& $SM_siteManager->rootTemplate(templateName);

This will search your template path for the requested template, and load it once found. From there you may add a previously loaded and congured module to the template using the addModule() method:
$template->addModule($modulePointer, areaOne);

This adds the module created into $modulePointer to area areaOne, and will cause its output to show up in the corresponding area.

35

Chapter 3. SiteManager Fundamentals

Finally, the completeDisplay() method is called to run the modules and output the nished page. See the Directive Script section for more information on creating a template and adding modules to it. Direct Area Replacement. Another way to use templates is for direct text replacement. This allows you to replace an area you dene with an arbitrary block of text.
$template->addText(Hello there, world., areaOne);

Templates within Templates (sub-templates)


Templates can act recursively - that is, you can have templates within templates. To do this, you use the $SM_siteManager root object method loadTemplate(). Then add the template that gets returned into another template through the addTemplate() method (in much the same way as adding a module). For example (directive script excerpt):
// create root template. notice, returns a reference!! $layout1 =& $SM_siteManager->rootTemplate("welcome"); // add our module to root template area $layout1->addModule($mod1, "leftDirectory"); // load subtemplate, returns reference! $layout2 =& $SM_siteManager->loadTemplate("subTemplate"); // add module to subtemplate $layout2->addModule($mod2, "areaOne"); // add sub template to root template $layout1->addTemplate($layout2, "intro"); // finish display $SM_siteManager->completePage();

Every loaded template has an addTemplate() method, which allows you to add an entire template (modules and all) into an area in another template. When a root template displays, if it encounters a template inside one of its areas, and it run recursively, gathering and returning output. Computer resources are the only limit to the depth of recursion. Also note, you can use CodePlates instead of templates, which also act recursively. See the next section on CodePlates.

CodePlates
CodePlates take templates a step further. They are templates that have modules associated with them. Often, youll want to use a template that has the same (or almost the same) module layout in several pages. For example, on a typical website you might have one main layout that includes a menu on the top, another menu in a left column, and the content in the center changes depending on the page loaded. One way to do this in SiteManager is to create a directive script for each page, and load and add the same menu modules on each page, then load a different module to place in the center section. But what if, at a

36

Chapter 3. SiteManager Fundamentals

later date, you wanted to change which module gets loaded in the left column? You would have to go through each directive script to change it by hand. CodePlates solve this problem. To handle the above example, you would create a CodePlate that always has the menu in the top and left areas of the template. Then, instead of loading the template and modules in the directive scripts, you would load just the code plate, and the center module. Place the center module in the code plate, and youre all done. Since the menu modules were automatically added by the code plate, you dont have to worry about them (although you can still congure them if you wish, per directive script). CodePlates are actually a descendant of the SM_layoutTemplate class they have all the same methods and functionality of a regular template. You associate a CodePlate with an HTML template, and you can add modules to the areas in the same way. However, CodePlates have extra methods which are used to congure and dene which modules get loaded, and where they get placed. To use a CodePlate, you must create a class that extends the SM_codePlate class. This piece of code may be in an external le, and loaded in your sites common.inc Here is an example CodePlate:

/** * a test code plate * */ class mainLayout extends SM_codePlate { /** * * pre-configure the CodePlate * */ function codePlateConfig() { // configure a directive $this->addDirective(testDirective,testValue); // load and parse basic.tpt for my template // this will search my template paths // THIS CALL IS REQUIRED! $this->setMyTemplate(basic); }

/** * * define which modules i want where in my template * */ function codePlateThink() { // load a new module, and place it into area leftBar $mod1 =& $this->loadModule(menu,leftBar); // load another module, place it into area main $mod2 =& $this->loadModule(runTestModule,main);

37

Chapter 3. SiteManager Fundamentals

// configure the menu $mod1->addDirective(menuStyle,sp); $mod1->addDirective(menuSpaces,5); // load more modules, for subtemplate $mod3 =& $this->loadModule(rawHTML); $mod4 =& $this->loadModule(rawHTML); // configure the module $mod3->addDirective(output,Module 2, Sub Template); $mod4->addDirective(output,Module 3, Sub-Sub Template); // load subtemplate, add it to main area of my codeplate $layout2 =& $this->loadTemplate("subTemplate",main); // add module to subtemplate $layout2->addModule($mod3, "areaOne"); // load subsubtemplate $layout3 =& $this->loadTemplate("subTemplate"); // add module to subsubtemplate $layout3->addModule($mod4, areaOne); // add subsubtemplate to subtemplate $layout2->addTemplate($layout3, areaTwo); } codePlateConfig() is required, because the call to $this->setMyTemplate() is required. By calling this method, you are

telling SiteManager which template this CodePlate will be based on. Once it loads and parses the template, it will know what areas are available to load modules (and possibly other templates or CodePlates) into. codePlateThink() is then used to load, congure, and add modules and templates to areas of the CodePlate. This is similar to a directive script, except when loading a module or template, you can specify which area it should be located in immediately. Also, you use built in methods rather than the global $SM_siteManager object to do so. Check the SiteManager API for the list of methods available to SM_codePlate decedents. CodePlates behave like any other template, and therefore can have any number of modules or templates (or even other CodePlates!) added to any area, and to any depth of recursion. Once you have a CodePlate dened and included in your site, you use it in your directive scripts much like a template. For example (this is a full directive script):
// include load site common include ("../admin/common.inc"); // load a module $mod1 =& $SM_siteManager->loadModule(detailedForm); // load code plate as root template $layout =& $SM_siteManager->rootTemplate("mainLayout.cpt"); // add form module into codeplate $layout->addModule($mod1, "intro");

38

Chapter 3. SiteManager Fundamentals

// finish display $SM_siteManager->completePage();

As you can see, you can set a CodePlate to be the rootTemplate, in the same way as setting a normal template. You can also add modules to a CodePlate in the exact same manner.
Note: When using a CodePlate as a rootTemplate, you must include the extension (.cpt) so that the SiteManager system knows youre loading a CodePlate and not a regular template (which has a .tpt extension).

SmartForms
With SmartForms, you create an HTML form by programatically telling it exactly what you need and how the information needs to be formatted. SmartForms handles all other aspects of outputting, gathering, and validating the information from the form. SmartForm Feature List: 1. Generation of all HTML tags and other code, including all form elements, the table the form appears in for layout, and javascript functions. 2. Handles "enter information->submit->correct information->submit" loop automatically, highlighting which elements need to be corrected and why 3. Handles checking for valid input based on a list of lters for each for entity 4. Ability to use a template for form output, so the layout of the form elements are to your exact specication 5. Expandable library of common Input Entities: Check Box, Combo Box, Country List, Date Picker, DB Combo Box, DB Select, Static Text, Radio, Select List, State List, Switch Box, Text Area, Text 6. Ability to create new drop in Input Entities and lters, or use entities and lters designed by others by doing nothing more than placing a .inc le in the correct directory. 7. Expandable library of Filters: Credit Card, Email, User Function, Number, Phone, Regular Expression, Required, Variable Comparison 8. Can add any number of lter requirements to any entity 9. Filters and entities can contain optional JavaScript output for increased functionality. Javascript will go to correct JavaScript section of output template 10. Load a precreated SmartForm from an XML conguration le Now that you know a little more about what a SmartForm can do, heres how to use them.

Usage
1. Create or Load a Smart Form 2. Congure The Form 3. Add Elements 4. Congure Elements (setup options, add lters) 5. Run Form

39

Chapter 3. SiteManager Fundamentals

6. Data Verication Test

Create a New Form


First is to create a new SmartForm. This is done in a module through the modules newSmartForm() method:
$myForm =& $this->newSmartForm(); $myForm is now a SmartForm object.

Return By Reference
The object returned from this function is returned by reference: you must use the reference assignment operator ( =& ) as in the example above in order to congure and use the SmartForm properly. For more information on this, see the PHP documentation: References Explained (http://php.net/manual/en/language.references.php)

Congure Form
You can congure SmartForm directives through the standard addDirective() method call. You can, for example, tell the SmartForm that the value of the Reset button on the form should be "RESET FORM":
$myForm->addDirective(resetButton,RESET FORM);

Since a SmartForm extends SM_object, you can use loadConfig() to load directives from an external le. See the SM_object section for more info.
Tip: A full commented list of directives is available in the library lib/smartForm.inc. You can also check the Appendix section for an annotated directive list, which will describe all the ways in which you can congure a SmartForm.

Add Elements
If you are loading the form from an external le, you can skip this step, as the elements will be created for you from the XML conguration le. See the LOADING A SMARTFORM section below. Otherwise, add some elements. This is done through the add() method.
$myForm->add(varName,Input Title,text);

There are many parameters, but the rst three are all that are required. They are: 1. The variable name to use in the form 2. The title to use, which will tell the user what they are expected to enter 3. The type of input entity to create (in the above case, a text box) Here is another example, illustrating how to access methods of an input entity once its been added to a form. Notice how the input entity is returned as an object from the call to add():

40

Chapter 3. SiteManager Fundamentals

$selectList =& $myForm->add(sList,Select A Color,select); $selectList->addOption(Red); $selectList->addOption(Blue); $selectList->addOption(Green);

This nal example shows a more complicated call to add(). Note that it makes use of the optional parameters. For a full, documented list of parameters, see the API documentation.
$selectList =& $myForm>add(sizeList,Select Your Size(s),select,true,large,array(multiple=>true,size=>5)); $selectList->addOption(XX-Large,xxlarge); $selectList->addOption(X-Large,xlarge); $selectList->addOption(Large,large); $selectList->addOption(Medium,medium); $selectList->addOption(Small,small); $selectList->addOption(X-Small,xsmall);

Return By Reference
The object returned from this function is returned by reference: you must use the reference assignment operator ( =& ) as in the example in order to congure and use the entity properly.

Loading a SmartForm
Instead of manually add()ing the elements to the SmartForm in your module, you can call the SM_smartForm::loadForm() method. It will read in an SmartForm XML denition le and congure the form as indicated in that le. The XML format is described in Appendix B, or you may check the testSite for examples. In that example, the form and its directives are congured all externally. Once you call the loadForm() method in your module, you can still congure and override all settings, using the addDirective() method as normal. For example:
// create form $myForm =& $this->newSmartForm(); // load from external file $myForm->loadForm("smTest.xsm"); // override configuration directives that // were loaded in from the XML form // one of the variables loaded in from the file // was userName. well configure that here. $myForm->setArgs(userName,array(size=>20)); $myForm->addFilter(userName,number,Must be a number); // run the form

41

Chapter 3. SiteManager Fundamentals

$myForm->runForm(); $this->say($myForm->output());

Conguring Elements
You may also use the input entity returned from the add() call to setup directives for this entity:
$myPW = $myForm->add(passWord,Pass Word,text); $myPW->addDirective(passWord,true); // this tells the text entity to be of type PASSWORD // so it will show asterisk when someone types $myPW->addDirective(size,20); // make it size 20 characters

To verify the data coming into your script from the form, use lters. Adding lters to an element is easy. To make the above eld match a phone number pattern, we would:
$myPW->addFilter(phone,Must be in the form of a phone number); $myPW->setFilterArgs(phone,array(format=>(XXX) XXX-XXXX));

This would add the phone lter, and if the lter didnt pass, it would display the above message to the user as to why it didnt. You may add any number of lters to any entity. For the current list of lters included with the library, look in the lib/sfFilters directory.

Run Form and Input Validation Check


Once the form is dened and congured, you must run the form:
$myForm->runForm();

This applies all lters and does some background magic. After the form has been run, you will know if the data has been veried or not. The check would be:
if ($myForm->dataVerified()) { // the form has all required input, and the input has been validated // against all filters // send email, write data to database, or do whatever necessary with // form data. access the variables with ->getVar function: $this->say($myForm->getVar(passWord). was passed and verified!); // or, dump all form input $this->say($myForm->dumpFormVars()); // how about looping through the form variables... $varList = $myForm->getVarList(); foreach ($varList as $formVar) {

42

Chapter 3. SiteManager Fundamentals

$this->saybr("form variable $formVar had a value of: ".$myForm->getVar($formVar)); } } else { // the form either does not have all required input, or some filters // did not pass // display the form $this->say($myForm->output()); }

Here is a simple, complete SmartForm (when copied and pasted into a siteManager module, it should run correctly):

// create form $myForm =& $this->newSmartForm(); // configure form $myForm->addDirective("requiredStar","***"); // add a new text entity $myForm>add(userName,User Name,text,true,,array(size=>20,maxLength=>25),0); // add a couple more $myForm->add(firstName,First Name,text,false,,undef,1,"RIGHT"); $myForm->add(phone,Phone Number,text,false,,undef,2); // add filter $myForm->addFilter(phone,phone,Not a valid phone number,array(format=>(XXX) XXXXXXX)); // run the form $myForm->runForm(); // was data verified? if ($myForm->dataVerified()) { // yes! $this->say("thanks for the input!!<Br><br>"); } else { // no! output the form $this->say($myForm->output()); }

43

Chapter 3. SiteManager Fundamentals

Form Templates
SmartForms by default will generate the table and layout for the form. There are many options for formatting the output of this table (see Appendix A for more information on SmartForm conguration directives). However, sometime you want your form to be in a specic layout - SmartForms handles this with templates. Here is a sample SmartForm template:
<TABLE border=0> <TR><TD>{userName.title}</td><td>{userName.input}</td> <TD>{firstName.title}</td><td>{firstName.input}</td> <TD>{lastName.title}</td><td>{lastName.input}</td> <td>{submit.Enter Data}</td></tr> </TABLE>

You tell a SmartForm to use a template by calling the method:


$myForm->setTemplate(templateName.stp);

You should call this before you call runForm() There are two parts to setting up the template: you must tell SmartForms where to place the Title and the Input for each form entity. The format to do so is
{varName.title} {varName.input}

"varName" should be the same variable name you used when call the add() method to add your elements. The {submit} tag is a special tag which will place the Submit button. The text that shows up after the "." in the submit tag will be the text on the Submit button (in the example above, the submit button would read "Enter Data") Please note, there are many other options and conguration settings for SmartForms. Please reference the JavaDoc documentation in the following les (see the API documentation les):
lib/smartForm.inc lib/sfInputEntities.inc lib/sfFormEntity.inc lib/sfFilters.inc lib/sfFilters/* lib/sfInputEntities/*

Hidden Variables
To add hidden variables to your form, make an associative array. When passed, the key of the array will be the "NAME" and the value of the array will be the "VALUE" of the HIDDEN FORM tag. Setup your hidden by creating the array as follows:
$myHiddens = array ("hidden1" => "val1", "hidden2" => "val2");

44

Chapter 3. SiteManager Fundamentals

Once its created, pass the array as the "hiddens" directive of your smartForm:
// add hiddens via addDirective... $myForm->addDirective(hiddens,$myHiddens);

Note that since your hidden variables will have their module prex attached to their name, you must use SM_smartForm::getVar() (or declare a module inVar) to retrieve their value. If you want your hiddens to use the variable name you specify, and NOT to attach the module prex, set the directive cleanHiddens to true.

Session Aware Forms


All forms are automatically "session-aware". That is, if persistent variables have been setup using the SiteManager session code, they will automatically be included as HIDDEN elds in the form when necessary. In addition to adding persistent variables, SmartForms will also propagate "read-write" inVars. See the Module section for more information on this.

Session Management
Sessions are used to maintain "states" for users when they access your site. For example, if a client accesses your site and enters a user name, it would be nice if next time they came to the site, they didnt have to enter the username again. This is where the SiteManager sessions system comes in. There are several ways to congure the sessions system, but there is always one common element: the persistent variables. These are the variables you would like to keep persistent between sessions for each user. It is possible to use persistent variables of any valid PHP type - this includes strings, integers, oats, arrays (multidimensional) and objects. To use a variable other than a string, however, you must be using a database and have serialization turned on (which it is by default). If you dont use serialization, you will only be able to keep strings persistent. For example, "userName" could be a persistent variable that gets dened in a SmartForm. If you make this variable persistent, once the user submits the SmartForm, the value will keep throughout their session. To access this variable through a module, simply declare "userName" as a module InVar (see the Module section). Depending on if you use cookies and/or a database for session storage, their session might last for as long their browser is open, or even until they come back next time, potentially days later. Possible ways to congure the session system: 1. Dont use database or cookies to store variables. This is the simplest method. In this system, all declared persistent variables are passed around throughout all the links on the site (through the hLink function). This method would let the user see all of the persistent variables in the URL of the script. You will not be able to keep arrays or objects persistent, only strings. 2. Use database to store variables, optionally using a cookie to store session ID. This method will store all declared persistent variables in a database. The session ID is passed around in all links throughout the site (through the hLink function). This method would let the user see their sessionID in the URL links, but not the different variables being kept for their session. If you use a cookie for session ID, the session will be maintained even after the user closes their browser. You can keep arrays and objects persistent with this method.

45

Chapter 3. SiteManager Fundamentals

DATABASE NOTICE
Even though the session code uses the same PEAR database functionality as the rest of the SiteManager system, database structures and therefore SQL queries vary with each database type. Currently, MySQL and PostgreSQL are the only tested database engines. The code is written in such a way as to easily be able to handle other database structures. If you add support for another database layout, please submit it to us. The current sessions table format can be found in the tables/ directory.

Conguring Sessions
There are several options for conguring the sessions system to work with your site. Look in config/globalConfig.xsm in the "sessions" SECTION, for a commented list of all available options.

Using Sessions
To use the session system, simply call $SM_siteManager->startSessions() in your sites admin/common.inc. Then, use the addPersistent() method to tell SiteManager which variables you would like to keep persistent. For Example (from common.inc):
// use sessions $SM_siteManager->startSessions(); // add a variable to keep persistent $SM_siteManager->addPersistent("userName"); $SM_siteManager->addPersistent("firstName");

You may also set which variables you want to keep persistent in the local site conguration le (localConfig.xsm). See the Global Conguration System section for more info, or take a look at testSite/admin/config/localConfig.xsm in the pVars SECTION. Now, when "userName" or "rstName" get passed to a script (either through command line GET or from a SmartForm) the value will be remembered and passed around between links and forms in the site. To accomplish this, modules need to me "session-aware". See the Module System section for more information on this. If you would like to change the value of a persistent, so that at the end of the page load it saves a new value to the database, use the SM_session::setPersistent() method. For example (module excerpt):
function moduleThink() { // change the value of a persistent variable so that // at the end of this page load, a new value is written // to the database $this->sessionH->setPersistent(userName,testUser); }

One caveat to persistent variables is that if you are using a database to store the values, once the values get set and written to the database, they will not change until you call setPersistent (as above). If a SmartForm passes a value for that persistent, or a value is set on the URL, it will be overridden from the value retrieved from the database.

46

Chapter 3. SiteManager Fundamentals

Note: If youre using sessions with a database, SiteManager will not automatically clean your session table of old session variables. You must do this yourself with cron and a script. You can use the dateCreated eld to see how long ago session variables were written.

Member Login Sessions


Member Logins are a sub-system of the main Sessions code. It allows you to easily implement a method for users to become "members" of the site (with a username and password) whereby they login to potentially receive more information or functionality than guests, or simply for tracking purposes. To use the member system, you must congure it and turn it on in the Global Cong System. This is done by setting the useMemberSystem variable in the sessions SECTION to true, and conguring the variables in the members SECTION. You can copy and paste the defaults from globalCong.xsm into your localCong.xsm
<SECTION name="members"> <VAR name="memberTable" value = "members" ble name" /> <VAR name="memberSessionsTable" value = "memberSessions" ber session table" /> <VAR name="userNameField" value = "userName" name field" /> <VAR name="passWordField" value = "passWord" word field" /> <VAR name="uIDField" value = "uID" <VAR name="sIDField" value = "sID" sion id field" /> <VAR name="dcField" value = "dateCreated" desc="DATETIME field of session creation" /> <VAR name="loginTTL" value = "2678400" gin session valid for" /> <VAR name="maintainTables" value = "false" ager will delete old sessions. performance hit, so defaults to false. ter to run a crond script." /> </SECTION>

desc="member tadesc="logged in memdesc="the userdesc="the passdesc="the unique user id field" /> desc="the unique ses-

desc="how long is a lodesc="if true, SiteManbet-

Note: loginTTL is the number of seconds a member login session is valid for. After their session expires, they will have to login to reset it. Note the actual memberSessions entry isnt removed when their session expires unless you set maintainTables to true, but theres a performance hit by using this so we recommend you maintain your tables with a cron script.

The member system requires two tables: the member table, and the memberSessions table. Both are included in the tables/ directory of the main distribution. The members table is for keeping the actual information on a member. You dont have to use the included members table - it may have as many elds as youd like, but it must have a userName, passWord, and UID eld. The actual eld names are congurable (see above). UID is an identier string used by the sessions system. It should be a CHAR(32) eld. Username and Password are self explanatory - they should be CHAR elds. The memberSessions table must be as per the denition in the tables/ directory. After creating these tables in your database and conguring the appropriate variables in the GCS, all you need to do is add a mechanism for users to be able to login and out. For logging in, weve provided a simple generic module that creates a SmartForm

47

Chapter 3. SiteManager Fundamentals

and calls the appropriate methods in the session system for logging in a user. Its a good starting point for creating a custom login form the module is called userLogin.mod and is in the main modules/ directory. For logging out, you need to setup a page that calls the SM_sessions::attemptLogout() method. For an example of this, and also an example of how to check to see if the current session is a member session, see the testMembers.mod module in the testSite/admin/modules directory. To use the member system in your modules, you have the following methods available to you, all of them available through the $this->sessionH variable:
isGuest() isMember() getMemberData() attemptLogin() attemptLogout() - returns true if the current session is a GUEST session - returns true if the current session is a MEMBER session - returns an associative array of all fields in your members table for the current member who is logged in - attempt to create a member session with the passed username and password this is to be used in login modules - attempt to remove a valid member login session

Here is an example of a module that displays the status of the current member system, and allows the option of logging out if they are currently logged in:
class loginCheck extends SM_module { /** * configure the module. run before moduleThink */ function moduleConfig() { // flag to single logout request $this->addInVar(l,0,int); } /** * this function contains the core functionality entry point for the module. */ function moduleThink() { global $PHP_SELF; // if they want to logout, do so here if ($this->getVar(l) == 1) { $this->sessionH->attemptLogout(); } // display status if ($this->sessionH->isGuest()) { $this->say("You are currently NOT logged in"); } else { // they are logged in, get their information! $member = $this->sessionH->getMemberData(); $this->say("You are logged in as: ".$member[userName]);

48

Chapter 3. SiteManager Fundamentals

$this->say(" [".$this->sessionH->hLink($PHP_SELF.?l=1,logout).]); } } }

Custom Member Load Function. You can also specify a custom function to run when member data is loaded. This function can load additional information from a database, for example, or run whatever other code you need it to. The function will only be run if the session system determines the user is a member who is currently logged in. It will be run directly after loading the current members information. The function must take one parameter, $memberData. It will be the hash of data loaded from this member. You can use it to perform other database lookups based on this members information. The $memberData parameter can be taken by reference, and if so, changes made to it will be visible by modules using $this->sessionH->getMemberData() method. To create a custom member load function, dene the function either in common.inc or a le included therein. The name of the function can be any valid PHP function name (you will specify it later). As mentioned above, the function should take exactly one variable as a parameter (possibly by reference). The code inside the function can be any valid PHP code. If you need to access the current SiteManager database connection inside of the function, declare $SM_siteManager as global and use $SM_siteManager->dbH. The nal step is to tell the session system the name of the function youve created, and to use it. Both of these tasks are accomplished by specifying a variable in your localConfig.xsm called memberLoadFunction in the sessions SECTION. The value of the variable should be set to the name of the function you have declared. Here is an example custom load function:
// hook for grabbing extra member information // this is run when the member system loads the member information from the main table // (or from a persistent variable) function testMemberLoad(&$memberData) { // alter the main users memberData for other modules and code to see $memberData[testMemberLoad] = ran testMemberLoad; // could be looking up more info in a database, or whatever else... // to access the SiteManager database settings, use // $SM_siteManager->dbH // after declaring $SM_siteManager as a global }

This line would appear in the sites localConfig.xsm, in the sessions SECTION.
<VAR name="memberLoadFunction" value = "testMemberLoad" ning a custom function to load additional member information" />

desc="a hook for run-

49

Chapter 3. SiteManager Fundamentals

Database Connectivity
Database connectivity in SiteManager uses the PEAR database abstraction library (http://pear.php.net). This keeps the interface to the database routines the same, while allowing multiple database engines to power the site. Connecting to a database should be done through the $SM_siteManager variable. Doing it this way allows other parts of the SiteManager system (modules, SmartForms, input entities, etc) to be database aware. Starting the database system using the database settings found in the Global Cong System is a simple matter of calling $SM_siteManager->dbConnect() in your sites common.inc. See skeletonSite/admin/common.inc for an example. Once connected, you may directly access the PEAR database object using $SM_siteManager->dbH, which points to the default database connection. You rarely directly access $SM_siteManager->dbH, however, since most of the database work is done inside of modules. See the Module section on how to make a module database aware.

Database Connection Settings


The settings that may be dened in the cong les are:
<SECTION name="db" id="default"> <VAR name="dbType" value <VAR name="persistent" value <VAR name="userName" value <VAR name="passWord" value <VAR name="hostName" value <VAR name="dataBase" value <VAR name="DSN" value </SECTION>

= = = = = = =

"mysql" /> "true" /> "userName" /> "passWord" /> "hostName" /> "dataBaseName" /> "mysql://userName:passWord@hostName/dataBaseName" />

This may be dened in EITHER the globalConfig.xsm or per site in localConfig.xsm Note that you can dene either (userName, passWord, hostName, dataBase) OR use DSN. If DSN is available, it will always use that. The id tag lets SiteManager know which database connection this is. For information on multiple database connections, see the section below. dbType should match up to one of the valid PEAR database types. See the PEAR DB documentation for more information on that. For more help with the PEAR Database layer, see http://pear.php.net or /usr/local/lib/php/DB.php and
/usr/local/lib/php/DB/*

Multiple Database Connections


SiteManager allows you to setup an arbitrary number of database connections for use in your site. This is accomplished by having multiple "db" SECTIONs in your localConfig.xsm le, each with a different id. For example:
<SECTION name="db" id="default"> <VAR name="defaultConnection" value="true" /> <VAR name="dbType" value = "mysql" /> <VAR name="persistent" value = "true" /> <VAR name="DSN" value = "mysql://userName:passWord@hostName" /> </SECTION>

50

Chapter 3. SiteManager Fundamentals

<SECTION name="db" id="secondary"> <VAR name="dbType" value = "mysql" /> <VAR name="persistent" value = "true" /> <VAR name="DSN" value = "mysql://userName:passWord@otherHost" /> </SECTION>

This would create two database connections, one identied as default and the other identied as secondary. Normally, most SiteManager objects access the database connection through their $dbH variable, which they inherit from the SM_object base class. This variable always points to the default database connection. To access a connection with a different id, use the $dbHL hash. The key to this hash is the id specied in the cong le. For example:
$SQL = "SELECT * FROM testTable"; $rh = $this->dbHL[secondary]->simpleQuery($SQL); if (DB::isError($rh)) { SM_debugLog($SQL,$this); SM_fatalErrorPage("There was a problem with the query!"); } while ($rr = $this->dbHL[secondary]->fetchRow($rh)) { $this->say($rr[firstName].<br>); } $this->dbHL[secondary]->freeResult($rh);

Error Handling and Debugging


Two global functions are provided for handling errors and issuing warnings:
SM_fatalErrorPage($msg, $obj=NULL)

This function should be used when a fatal error has occurred, and the script should not, or can not, continue. It will create an error page, displaying $msg in red text, and display the current debug log. If you specify $obj, it will prex the message with which object issued the fatal error.
SM_debugLog($msg, $obj=NULL)

This is used for non-fatal debug output. $msg is the message to log, $obj is the calling object, if any. If its specied, the objects class name will be logged (usually you should specify $this, if youre using this function from a module) Use this function, in conjunction with the JavaScript Debug Window or debugOnVar, to track down errors. Calls to SM_debugLog() will not show up in the main page view, only in the debug log. This lets you view the complete page without test debug messages all over it, but still allows you to view any type of debug message you need. You can also use standard PHP functions such as echo, var_dump, and print_r. Their output will not show up in main page, only the debug page. Use either $SM_siteManager->fatalDebugPage() or one of the debugging methods listed below to view their output.

DebugOnVar
One simple way to debug your script is to use "debugOnVar". This is a variable set in the GCS in the "debug" SECTION. When its true, SiteManager will look for a global variable called "SM_debug" to be set to 1. If it is, it will generate a page that has all the debug output at the top, then your completed page below it. This separates the debug output from the main output and still allows

51

Chapter 3. SiteManager Fundamentals

you to see all of your warning and debug message issued through SM_debugLog(). It will also display the output buffer, which you can use to view calls to PHPs var_dump() and print_r() routines. To use, make sure "debugOnVar" is set to "true" in your localCong.xsm le. Then, when viewing your script, add "SM_debug=1" to the URL, such as:
http://localhost/home/testScript.php?SM_debug=1

You should now see your page displayed with debug information attached to it.

JavaScript Debug Window


Another way to debug your modules and scripts is to use the JavaScript Debug Window, which will display a pop up box of debug information. As this uses JavaScript to output its code, it sometimes has problems displaying everything correctly. We recommend the "debugOnVar" method if you cant get the JavaScript window to function. There are three conguration directives that decide how the javascript pop up debug window will work. They will be set depending on how you wish to use the debug window. In both cases, however, you must have a <SM TYPE="javaScript"> tag in your template. There are two different ways to use the window: 1) The debug window opens and updates automatically when you reload your page To use this option, see the following conguration directives in globalConfig.xsm (or localConfig.xsm for your site) in the "debug" SECTION:
jsDebugWindow - true jsDebugLink - false jsDebugAutoFocus - false

You must also add one additional piece of code to your root template. You must tell the client to run the SM_viewDebugLog javascript function upon loading. Do this by adding the following tag to your templates <BODY> HTML tag:
ONLOAD="SM_viewDebugLog();"

For example, your template might have:


<BODY BGCOLOR="#FFFFFF" ONLOAD="SM_viewDebugLog();">

If you dont wish to have to change your template to use the debug log, use the next option below. 2) The debug window opens and updates when you click on a link thats added to the bottom of all your pages To use this option, see the following conguration directives in globalConfig.xsm (or localConfig.xsm for your site) in the "debug" SECTION:
jsDebugWindow - true jsDebugLink - true jsDebugAutoFocus - true

With these options set, all of your pages will now have a link at the bottom [view debug output]. Clicking on this link will open the JavaScript Debug Output window, showing all messages that were written with SM_debugLog().

52

Chapter 3. SiteManager Fundamentals

For example, one way to use the debugLog is to check a variable when youre not sure of its value. For example (excerpt from a module):
.... SM_debugLog("testVariable is $testVariable", $this); if ($testVariable == check) { // do something } ....

Then click on "open debug output" on the bottom of your page. It will pop open a window with your test message (or update the window if it was already open).

Helpful Debug Routines


SM_dumpVars() - global function that dumps variables in HTTP_POST_VARS and HTTP_GET_VARS $smartForm->dumpFormVars() - call this SmartForm method to dump value of all form variables $SM_module->dumpInVars() - call this SM_Module method to dump value of all declared inVars $SM_siteManager->siteConfig->dumpConfig() - dump current Global Site Configuration values $SM_siteManager->fatalDebugPage() - called in place of completeDisplay() to view all current configuration values for all templates, modules, etc.

SmartForms contains its own debug output log. If ags => sfDebug is true in Global Cong, you should be able to view the source of an page that includes a directive script to see the debug output from a form.

Miscellaneous Routines
Other supportive routines are included in the SiteManager system. Please see the following library les and the API documentation for more information:
Authentication Routines Security Routines Support Routines Data Manipulation Routines (auth.inc) (security.inc) (support.inc) (dataManip.inc)

53

Chapter 4. Designing a SiteManager Site By Example


The rst part of the manual was designed to familiarize you with the basics of SiteManager. This chapter is designed as a starting point for learning how to design a templated and modular web site with Roadsend PHP SiteManager. In this chapter, well go through the design steps necessary to create a SiteManager site, as well as plan out the design of a simple ctional website. Our ctional site is the Roadsend Car Dealership. It will require a system for keeping track of current inventory that users will be able to browse. Administrators of the site must have a way to maintain the inventory online, through administrative forms. There will also be a feedback system, allowing users to ask questions online. Well begin by breaking down the design of the site into the following steps: 1. Assess the site needs 2. Determine separation of layout from content 3. Determine method of splitting dynamic content into modules 4. Create a Site Plan: a consistent framework for the site 5. Implement site: build up Templates, CodePlates and Modules

Assess Site Needs


The rst stage involves some planning to answer a few basic questions that will help us design the rest of the site: Functionality of Site. Perhaps the most important aspect of this phase is to gure out exactly what functionality the site will have. You can start with the front page - what will show up there? What options will the user have? Will there be a news page? Does it pull from a database? Do you want an articles section or a poll? Will you need a search engine or shopping cart? Before answering the following questions, make sure you have a good idea of what functionality you will need to implement in your site. Does the site need a database? Since youre creating a dynamic, modular web site, youll probably want to use a database of some sort to keep track of information or to generate content. If so, you have several things to decide: which database system to use, a schema for storing the information, etc. This document doesnt cover these steps (there are other such resources available). It assumes youve already taken the steps necessary to setup a database system that will power your web site (or have chosen not to use one). If you need a place to start, check out MySQL (http://www.mysql.com) or PostgreSQL (http://www.postgresql.org) both freely available database servers. If you do not use a database, you might be limited in the number of features your site can use. For example, the SiteManager Sessions System works best with a database, and the Member System requires it. Also, not using a database system limits your sites scalability - although you can always setup database access for your SiteManager site at a later date. The dealership will require a database. We will need it to store our inventory, feedback information, and administrative member tables. We will use a MySQL database. How will the site interact with the user? Will your site simply display information, or will it receive input from the people using your site? If you will be receiving input from users, you will be using SmartForms to gather that input. You should decide what information you will be gathering this will help you with your database table design, as well as give you an idea of how many SmartForms you will need to create, and exactly what their functionality will be. The dealership will have two major, and one minor form. The major forms are the administrative inventory maintenance form, and the user feedback form. The minor form will be a simple form where the user may enter their zip code. The administrative form will be available only to properly authorized members (using the SiteManager member system), while the feedback form will be available to everyone (guests). The administrative form will read and write to a database table, while the feedback form will only write.

54

Chapter 4. Designing a SiteManager Site By Example

Sessions. If you will need to maintain information for clients that access your site, then you will need to use the Session system. For example, you might want to use sessions to track visitors by some global ID, or to keep track of preferences they may have set. Sessions are most useful when used with a database, as you will be able to store a wider range of information as a session variable. At this point, you need to think about what information you wish to keep persistent within your site. Decide how you will store this information (for example, do you want to keep an array of values? a simple string? perhaps a class object?). This will help you generate the list of Persistent Variables you will use. The dealership will keep one persistent variable: zip code. If the user enters their zip code into the zip code form, the value will be kept persistent for that user, and we will attempt to use a cookie so that if the user comes back to the site later, we will still know their zip code. The zip code will be used to gauge how far away the user is. Member Login System. Does your site need a member system? If you wish to have clients "log in" to your site, then the answer is yes. The member system is designed to be exible enough to allow you to store whatever information you need to about the members of your site, and allow your modules to know if the current session is a Member or Guest session. You should decide exactly what information you want to gather from each user - this will help you design your member table, and the SmartForms necessary for logging in, creating and updating a user account. The dealership will use the member system, but only for administrators. General users will not need to login to the site. Administrators who will be maintaining the inventory, however, must have a member entry and must login to use the administration forms. Client Administration System. Often when you design a site for a client, the client needs the ability to maintain their database or otherwise update the site themselves. For example, they may need a system for editing and maintaining an online catalog. If the site includes this requirement, you will need to build a Client Administration system. This usually involves extra modules with SmartForms that are designed for authorized administrators to update the sites content. You may also integrate this with the Member Login system, and some form of access control. As explained previously, this is exactly the system we will be using for the Roadsend Car Dealership. Co-brand System. Co-brands are a convenient way for one company to offer the functionality from their site to another company. This allows two companies to partner, whereby Company A has a functioning website that Company B wishes to use, but still make it look (to the user) like they are on Company Bs site. With SiteManager, this is a snap since the same modules used in Company As site can simply be placed in a template that contains the layout for Company B. Since the same code module is used in both places, when an update happens to the module (such as a bug x), it affects all co-brands automatically. The dealership wont be needing a co-brand system at this point in time. If we need it in the future, we can always add it later. Multilingual. The Internet is a global place, so SiteManager makes it easy to add multiple languages to your site. If you know you will need to support multiple languages, you can start planning IDs that will be used to access blocks of text. You will use the IDs to access the text from a particular language, instead of hard coding them into your modules. While you can always add this support later, if you plan ahead you can avoid rewriting your modules to use IDs instead of hard coded text. Since the dealership is a local company, we wont be using a multilingual system. Perhaps well add it when it becomes cost effective to ship cars throughout the country.

Determine Separation of Static Layout from Dynamic Content


Now that you know a little bit about the direction of your site, you need to gure out exactly what will be static and what will be dynamic. This will let you know what can be in a template, and what needs to be made into a module. Determine static content of site. How many root layouts are there? A root template (or layout) is typically a piece of HTML code in which all parts of page that will stay the same have been hard coded. Usually this includes, for example, a company logo at the top, a certain table layout with columns where data will show up, a footer along the bottom containing copyright information. This content will show up on every page, regardless of what dynamic content shows up inside of it.

55

Chapter 4. Designing a SiteManager Site By Example

One site might have several root templates, one for each section of their site that has different content. Perhaps one root layout has a three column table, while another has a simple one column with no footer. Within these columns we will later place dynamic pieces of code to display different pieces of information. The dealership will have one root template. We will display a logo at the top of all pages, and use the company colors for displaying text and table background colors. There will be one main column (area) where content will show up. Will templates be needed for modules to load and use? At this point you can also determine if you will be loading templates into your modules. You might do this if you want to keep layout completely external from modules, instead of hard coding your module to output a particular bit of HTML code. The dealership wont be using this feature for now. Will templates be needed for the forms on the site? Another way to separate layout from code is by templating your SmartForms. This gives you exact control over the layout of the entities in the form. If you have a form that needs to be laid out in any other fashion then the default, two column table style, you will need to use a SmartForm template. The dealership will use SmartForm templates for both the administrative form and the feedback form, since we want to have concise control over the placement of the form entities. Determine dynamic content. Now you need to determine which parts of the site are dynamic. These are the parts of the site where the output will vary based on user input, database pull, or by some other dynamic means. For example, a News section on a site would be pulled from a database. A poll would change based on user input, and previous values stored in a database. By determining which parts of the site need to be dynamic, you can begin to understand how many modules you will be creating to complete the sites functionality. On the dealership site, there will be three major pieces of dynamic content that the user will have access to. We want to have a system for displaying a block of text pulled from a database, that can be administered by employees. This will be used for displaying general company information, as well as blocks of text like Directions. We will also have a system for displaying the current inventory list, which the user will be able to browse and sort. Finally, we will have the feedback system which will allow the user to send us feedback.

Determine Method of Splitting Dynamic Content Into Modules


Determine how dynamic content will be broken up into modules. Now that you have an idea of which parts of you site will be dynamic, you need to best gure out how you can create those modules in a way that makes the code reusable. There might be several ways to split up functionality into several modules. The goal is to try and create as much reusable code as you can, so that a module created in one circumstance can be reused in another part of the site. Try to take each bit of functionality you wrote out in the last section and decide how to break it into code modules. Regarding SmartForms, you should gure one module per SmartForm as its good to have each form in its own module. The dealership will need at least three modules that will be visible by the user: a module for displaying a block of text from a database, at least one module for browsing the inventory, and a module for allowing users to send feedback. The inventory module might be broken up into several modules, depending on how much functionality is required. We might have one "meta-module" that loads different modules depending on how the user is trying to view or sort the inventory. In addition to these modules, well need modules for the administration system, guring one per SmartForm.

Determine Site Plan


Create a plan from information gathered so far. You should now have enough information to put together a plan for the site. Youve examined the needs of the site, the separation of layout from content, and method of splitting the functionality of your site into reusable modules of code. Gather this information together and create a Design Document for the site.

56

Chapter 4. Designing a SiteManager Site By Example

In addition to the specic information youve obtained about your site, there are also a few more general practices which may help in creating sites with a clean, consistent framework. Consistent Variable Names. Try to be consistent when using variables names throughout your site. Pick a naming structure and stick to it. For example, dont abbreviate "index" to "idx" in one variable, and "indx" in another. If you create several modules that make use of an email address, use "$emailAddress" in both modules, not "$email" in one and "$emailAddress" in another. Coding Practices. Choose a system of coding practices to follow. For example, indentation style and function/variable naming convention. Choose whether youre using tabs or spaces. Be consistent with functions and variable naming, for example functionName or function_name. You might want to prex "private" class variables with an underscore. The actual method you choose isnt important, as long as it makes sense to you and you stick to it. For example coding practices, see http://php.net/manual/en/pear.standards.php Directory Layout. Try to follow a consistent directory layout. SiteManager includes a pretty rigid directory structure thats meant to be consistent across sites and make it easy to nd your way to the various SiteManager resources used by the site. You may choose to follow this, or create your own - but keep it consistent across all of your SiteManager sites. As this manual isnt a introduction to programming in general, sufce to say there are many ways you can make your programming more efcient by having consistent coding standards. This will save you time and aggravation in the long run. Now that you have a complete plan for your site and standards with which to implement it, you can begin coding.

Implement Site Plan


Follow plan to create the required SiteManager resources to nish the site.. First, create a skeleton SiteManager site by copying the skeletonSite/ directory, or using the bin/siteManager script. This will give you a good starting point, since the directory structure and cong les will be setup for you. You will also have a basic template and module ready to go.

Site Conguration
First, edit the admin/common.inc le. This is rst include le loaded by all directive scripts, and is where you will specify such things as the Site ID, SiteName, and the base directory path of the site. It also includes the SiteManager library. In common.inc are also the calls to start the database and session systems. After editing admin/cong/localCong.xsm (in the next step) you may want to come back and uncomment these lines. If you need to include any other library les you may have, you can do that in common.inc. Next, edit admin/cong/localCong.xsm le. This is the main conguration le for the site. All of the values have descriptions, make sure you read through each one and set them up appropriately. Pay attention to the directory paths. If you wish to setup database access, you will need to specify database conguration values here.

Template Design
Now edit the template placed for you by the skeletonSite (admin/templates/basicTemplate.tpt). Since its strait HTML, you should be able to get the exact layout desired for your site. Add the static content, such as image links and background colors. Then, add the SM tags required by your site. You will need at least one SM AREA tag to add dynamic content.

Module Design:
Look at the sample module in admin/modules/basic.mod. This is a basic module that was added by the skeletonSite. It contains a lot of commented out code that will be useful while designing a module. It includes descriptions of how to use directives, inVars,

57

Chapter 4. Designing a SiteManager Site By Example

styles, databases, and SmartForms in code.

58

Chapter 5. Using The Test Site


The testSite/ directory contains a full SiteManager site used for testing. To use it fully, you need to setup a database connection. Use the following steps to create the test user and database. Setup MySQL (or PosgreSQL) 1. Create test database if not already there 2.
GRANT ALL PRIVILEGES ON test.* TO testUser@localhost IDENTIFIED BY testPass

3. Create the test tables using the le test.db.sql in tables/ directory in the SiteManager root directory In testSite/admin/config/localConfig.xsm, the database settings are already setup to reect this. You should also check the "dirs" SECTION of this le to verify the paths match your setup. Otherwise, if SiteManager has been setup correctly on your system, and testSite is in your web document path somewhere, you may point your browser at the main directory and try it out. The testSite is also a great place to look for examples. You should nd at least a basic example of most of the features of SiteManager.

59

Chapter 6. Extending SiteManager


There are many ways to extend SiteManager, and much needed documentation on how to do so. A couple of options include: 1. Creating Modules 2. Creating Templates 3. Creating XML SmartForm Files 4. Creating SmartForm Input Entities 5. Creating SmartForm Filters 6. Creating Libraries for use with SiteManager, such as a Member Permission System For now, you may look at the current modules, entities and lters for example code. Also library code is heavily documented. Check the SiteManager API documentation as well.

60

Chapter 7. Frequently Asked Questions


1. How did you generate the API documentation from your code comments? We used PHPDoc to generate the API documentation. It requires you to comment your code in a particular way, but its well worth it. You can nd this program at: http://phpdocu.sourceforge.net 2. Can I install SiteManager if I dont have root access? Yes, but you must have access to .htaccess (apache). You can do everything in this le you do normally through the main apache cong le, and the main php le. The .htaccess le should be located in your root web document directory. It should contain the following lines:
# dont allow access to SiteManager files <FilesMatch "\.(inc|tpt|stp|mod|xsm|cpt)$"> Order allow,deny Deny from all </FilesMatch> # include SiteManager directory php_value include_path /var/www/users/username/siteManager:/usr/local/lib/php

Alternatively, you can leave out the php_value include_path statement, and edit siteManager.inc. Edit the $SM_rootDir directory to point to the main SiteManager root directory. If you do this, you dont need to have it in the PHP path. If you do it this way, you will also have to specify the full path to siteManager.inc in your admin/common.inc le 3. Im trying to use the $SM_siteManager class, but I keep getting errors. Make sure its declared as global. Remember, PHP requires you to declare globals variables inside of functions and classes. It doesnt automatically give you access to all global variables. Since SM_siteManager is global, if youre in a function or a function within a class, you must declare it global before gaining access to it:
// declare SM_siteManager global global $SM_siteManager;

61

Chapter 8. Getting More Help


The documentation weve included so far should help you get started using and extending SiteManager.But theres also a lot thats not covered. We recommend going through the library source les to get a better understanding of the library system. All les are heavily documented, using a JavaDoc like layout. You may also use our online resources to get help. Head over to http://www.roadsend.com/siteManager and our SourceForge page at: http://sourceforge.net/projects/sitemanager Here you will nd the latest information on SiteManager, including links to Message Boards, Mailing Lists, Support Emails, and the like. When in doubt, you can also rip us off an email: siteManager@roadsend.com Thanks.

62

Appendix A. Directive Lists


The following are a list of available directives in use by the SiteManager system. You may override the default values by calling the addDirective() method on each object.

Module Directives
outputInTable (default: true) When set to true, the module will output itself in a table automatically. If you dont want your module to appear in a table (for example, its a module to be used within another module), then set this directive to false. outputInSpan (default: true) When set to true, the module output itself within a SPAN tag, with an ID attribute set to the value of the modules prex. Setting this to false will force the module NOT to output a SPAN tag. tableBorder (default: 0) When outputting module in a table, this is the BORDER size tableWidth (default: 100%) When outputting module in a table, this is the table WIDTH tableCellPadding (default: 0) When outputting module in a table, this is the table CELLPADDING tableCellSpacing (default: 0) When outputting module in a table, this is the table CELLSPACING tableBgColor (default: ) When outputting module in a table, this is the table BGCOLOR centerInTable (default: false) When outputting module in a table, this adds ALIGN=CENTER to the <TD> that the module appears in when set to true. No effect if outputInTable is false. dieOnBadInVarType (default: true) When adding an inVar through the addInVar() method, you can specify a data type you are expecting this inVar to be (for example, numeric). If SiteManager determines that the inVar was passed, but wasnt of this type, it can either issues a debug warning, or not continue loading the page. If this option is set to true, the page will not load if the data type is incorrect. This is a security measure and we recommend leaving it on.

63

Appendix A. Directive Lists

propagateInVars (default: true) This sets the default for inVar propagation for this module. When true, all added inVars will be "read-write" or propagated by default. Note, you can also turn off propagation on a per inVar basis. See the Module section for more information.

Template Directives
bodyBGCOLOR (default: ) When using the SM TYPE="HTMLBODY" tag, this denes the BGCOLOR attribute of the BODY tag. bodyLINK (default: ) When using the SM TYPE="HTMLBODY" tag, this denes the LINK attribute of the BODY tag. bodyALINK (default: ) When using the SM TYPE="HTMLBODY" tag, this denes the ALINK attribute of the BODY tag. bodyVLINK (default: ) When using the SM TYPE="HTMLBODY" tag, this denes the VLINK attribute of the BODY tag. bodyBACKGROUND (default: ) When using the SM TYPE="HTMLBODY" tag, this denes the BACKGROUND attribute of the BODY tag. bodyONLOAD (default: ) When using the SM TYPE="HTMLBODY" tag, this denes the ONLOAD attribute of the BODY tag. bodyOther (default: ) When using the SM TYPE="HTMLBODY" tag, this denes arbitrary text that should be inserted as attributes into the BODY tag. You can use this to add attributes not directly supported as a directive.

SmartForm Directives
tableBorder (default: 0) When using the default SmartForm table layout, this is the BORDER size tableWidth (default: 100%) When using the default SmartForm table layout, this is the table WIDTH tableCellPadding (default: 0) When using the default SmartForm table layout, this is the table CELLPADDING

64

Appendix A. Directive Lists

tableCellSpacing (default: 0) When using the default SmartForm table layout, this is the table CELLSPACING tableBgColor (default: ) When using the default SmartForm table layout, this is the table BGCOLOR requiredTag (default: true) When true, the default SmartForm table layout will show a message to the user indicating a symbol which means a particular eld is required. requiredStar (default: *) When not blank, this text will show up before every required eld. This may be an IMG tag. normalClassTag (default: sfNormal) The style sheet element to use for normal element titles badClassTag (default: sfBad) The style sheet element to use for element titles whos entity failed the lter check correctMessageClassTag (default: sfMessage) The style sheet element to use for displaying an error message when a eld failed a lter check requiredClassTag (default: sfNormal) The style sheet element to use for displaying the required tag message. rowColorAlt1, rowColorAlt2 (default: ) These two directives allow you to specify two colors the form should use for alternating rows. It value should be a hex color value (ie, #FFFFFF). The row color alternator will preserve groups. resetButton (default: ) If this value is non blank, a RESET button will be added whose title is the same as the value of this variable. controlsOnRight (default: false) If this value is true, the submit value will show up to the right of the form, instead of on the bottom. This is useful for forms with one element, where you want a vertically compact form. submitAlign (default: "LEFT") When not using a template for output, and resetButton is (so it wont show up), this directive species how the Submit button should be aligned at the bottom of the SmartForm. Should be either LEFT, RIGHT, or CENTER. freeFormSeperator (default: <br>) This value is used when layout is SF_LAYOUT_FREEFORM. It is the separator used between entities.

65

Appendix A. Directive Lists

defaultLayout (default: SF_LAYOUT_NORMAL) This value is the default layout of form entities. Other options are SF_LAYOUT_FLIPPED, SF_LAYOUT_SINGLE, and SF_LAYOUT_FREEFORM. useJS (default: true) When true, JavaScript code will be collected and given back to the SiteManager system for inclusion in the nal output page. Some lters or entities might not work without this. postScript (default: $PHP_SELF) Normally a SmartForm will post to itself. If you want your form to POST to another page, set this directive. Note that the lter system will not work if this is changed. submitImage (default: ) If you would like the submit button to be an image instead of a regular button, set this directive with the image youd like to use. (ie /images/button.gif) showRequiredHelp (default: true) Set this to false to turn off both the message that says "* = Required Field" and the actual * next to required elds (ie, sets requiredTag to false and requiredStar to blank) cleanHiddens (default: false) Normally all hidden variables added to a SmartForm include the module prex attached to them. This is so variables added to this form dont conict with variables added from other modules. However, sometimes youll want to access the variables from a SmartForm with their prex - set this directive to true to allow the hiddens not to include their module prex. enctype (default: ) If you need your SmartForm to have a special ENCTYPE added to the FORM tag (for example, youre using your form to post a le), you can set this directive. badFormMessage (default: ) If this variable is non-blank, it will display its contents above the form (as a header) when any of the lters in the form fail. It should contain a message such as "The form was invalid, please check your input and try again".

Input Entity Directives


coming soon

Filter Directives
coming soon

66

Appendix B. File Formats


.XSM Resource Files
All les with a .XSM extension are XML les used by SiteManager for conguration and operation of the site. They all contain the root tag <SM_XML>, and one or more of the tags listed in this section. Most of these les can be cached by SiteManager.

SMARTFORM
SMARTFORM les describe a method for dening and conguring SiteManager SmartForms.

SMLANGUAGE
SMLANGUAGE les describe a method for dening translations of blocks of text.
<SMLANGUAGE VERSION="1"> <LDEF locale="en_US"> <TEXT id="text1">This is the text</TEXT> <TEXT id="text2">Here is some more text</TEXT> </LDEF> <LDEF locale="da_DK"> <TEXT id="text1">Dette er en tekst</TEXT> </LDEF> <LDEF locale="es_ES"> <TEXT id="text1">ste es el texto</TEXT> <TEXT id="text2">Aqu est ms texto</TEXT> </LDEF> <LDEF locale="fr_FR"> <TEXT id="text1">Cest le texte</TEXT> </LDEF> <LDEF locale="de_DE"> <TEXT id="text1">Dieses ist der Text</TEXT> </LDEF> <LDEF locale="it_IT"> <TEXT id="text1">Ci il testo</TEXT> </LDEF> </SMLANGUAGE>

An LDEF should appear for each language to be dened. The locale attribute should contain the language youre dening (if anyone can nd a reference as to where the ofcial list of these locale ids are, please notify us). Each block of text to be dened should be listed in a TEXT tag. The id attribute is arbitrary, and will be used by the getText() method for retrieving this block. The same ID should be used in each translation of that text.

SMOBJECT
SMOBJECT les describe a method for conguring SiteManager objects.

67

Appendix B. File Formats

SMCONFIG
SMCONFIG les describe method for conguring SiteManager sites on a global and site-wide basis.

SMRESOURCE
SMRESOURCE les are to be for describing various SiteManager objects. These are to be used for tools that will parse these les and understand which objects are available for use. They are not used directly by the SiteManager library. Blank SMRESOURCE Object
<SMRESOURCE type="" name="" extends="" version=""> <DIRECTIVE name="" default="" desc="" type=""> <DESCRIPTION> </DESCRIPTION> </SMRESOURCE>

Sample SMRESOURCE Object


<SMRESOURCE type="SM_INPUTENTITY" name="text"> <DIRECTIVE name="size" default="20" desc="size of the input box" dataType="int"> <DIRECTIVE name="maxLength" default="20" desc="maximum number of characters that may be typed" dataType="int"> <DIRECTIVE name="passWord" default="false" desc="when true, displayed as password text" dataType="bool"> <DESCRIPTION> </DESCRIPTION> </SMRESOURCE>

Tag Descriptions
SMRESOURCE type name version extends

type of object were describing name of the object being described what version of the SMRESOURCE are we using (optional) which object this extends (optional)

Start tag for a general SiteManager Resource object DIRECTIVE name default desc data dataType bool

the name of the directive the default value for the directive (optional) the description of the directive (optional) misc data stored for this directive or dataType (see below) (optional) format of value the directive should have (optional) - true/false value

68

Appendix B. File Formats

int string color list date dir percentage

numeric, integer free form text hex color value #rrggbb comma separated list of available values, stored in data attribute date value directory (path) percentage value 0-100%

A directive tag, which will indicate that the object may be configured through its directives using the variable indicated. DESCRIPTION A text description of this object

69

Anda mungkin juga menyukai