Previous | Next | |
UnitTests | RSDTable |
The basic idea of the RSDEngine is to sepeate things that change from things that do not. What does change in every application is the data that is managed with it - the database design. But what does not change, is the way this data is created, updated, selected or deleted. Everything or let's say the most of the things that 'stay the same' can be therefore generated. The rest is analysis and cannot be performed by a computer but by an analyst - a database designer! The RSDEngine needs the result of the analysis - the database design - and a few other configuration options as input and outputs an implementation of this analysis based on a very modular and flexible design.
The RSDEngine is not an all-purpose code generator. It only generates code for a specific type of application - database backended applications. It will not implement complex business logic for you. What it does, is to implement a powerful interface to your relational data. Note: it is possible to generate projects that are not database backended. This can be very useful as well but keep in mind that the power of the RSDEngine lies in generating code for accessing a database!
The RSDEngine needs an associative array of configuration options as input. This associative array must be passed to the method RSDEngine::generate. The RSDEngine understands the following configuration options:
Whether to create a project with versioning support. In fact this option is just stored in the config file - the RSDEngine has nothing else to with it. This configuration option is used by EVS. If $config['versioning'] is true the project will be created with versioning support.
The name of your project. This option is obligatory!
A short description of your project containing no newline characters. This field is optional.
A list of authors in the following format:
Multile authors are separated by newline characters ('\n').Firstname Lastname <name@host.tld>
A string containing copyright information. Must not contain newline characters.
The path to the skel (skeleton directory). Set this option to an empty string if you do not want a skel to be used. This would be the case if you are regenerating a project. Please see Basic Directory Structure
Whether to update all @version tags in all files found in the version directory when making a new release. In fact this option is just stored in the config file - the RSDEngine has nothing else to with it. This configuration option is used by EVS. EVSVersion actually performs the update after making a new release.
The path to the directory where PHPDocumentor is installed. In fact this option is just stored in the config file - the RSDEngine has nothing else to with it. This configuration option is used by EVS. Example: /usr/share/php/phpDocumentor/. Use forward slashes and place one at the end of the path! You do not even have to specify an absolute path - just make sure a require_once statement as the following will not fail:
1 require_once("${phpDocumentorDir}phpdoc.php");
The contents of the obligatory INSTALL file.
The contents of the obligatory README file.
If the supplied value evaluates to the boolean value true support for a database backend will be implemented. Creating code for accassing a database is probably the most powerful feature of the RSDEngine. See Database Backend: $config['sql'].
The name of the host on which the database runs on - ignored if Database Backend: $config['databaseBackend'] is set to false.
The name of the database - ignored if Database Backend: $config['databaseBackend'] is set to false.
The username to use to connect to the database - ignored if Database Backend: $config['databaseBackend'] is set to false.
The password to use to connect to the database - ignored if Database Backend: $config['databaseBackend'] is set to false.
The type of the database. Only databases supported by PEAR::DB are valid - ignored if Database Backend: $config['databaseBackend'] is set to false.
Whether to ensure referential integrity. This has the advantage that errors will be catchted earlyer and it will be possible to tell which column violated which constraint. The disadvantage is the reduced speed. Note that this option cannot ensured referential integrity in you database. If you really need referential integrity use a relational database (which MySQL prior to 4.0 definitely is not). It only configures the isValid-Methods and the method checkUniqueConstraints. Ignored if Database Backend: $config['databaseBackend'] is set to false.
The prefix used for all tables in Database Backend: $config['sql'] - ignored if Database Backend: $config['databaseBackend'] is set to false.
The prefix used for all columns in Database Backend: $config['sql'] - ignored if Database Backend: $config['databaseBackend'] is set to false.
The name of the static class that provides the validation methods that can be used in the /**isValid:...**/ statements in in $config['sql']. Please see Column Modifier /**isValid:TYPE:ARG1:ARG2:ARG3...**/. The default is 'RSValidation' (RSValidation). This configuration option will be ignored if Database Backend: $config['databaseBackend'] is set to false.
The name of the file in which the validation class is definded. Please see Database Backend: $config['validationClassName']. The default is 'RSValidation/RSValidation.php' (RSValidation). This configuration option will be ignored if Database Backend: $config['databaseBackend'] is set to false.
The default storage directory for uploaded files. Please see Column Modifier /**isValid:TYPE:ARG1:ARG2:ARG3...**/. This configuration option will be ignored if Database Backend: $config['databaseBackend'] is set to false.
This can be a multiline string containing constant definitions (valid PHP code). For example:
This configuration option will be ignored if Database Backend: $config['databaseBackend'] is set to false.
1 /**This right is required to create new records in the table prj_document.
2 */
3 define('PRJ_LIVEUSER_RIGHT_DOCUMENT_CREATE', 1);
4
5 /**This right is required to select records from the table prj_document.
6 */
7 define('PRJ_LIVEUSER_RIGHT_DOCUMENT_SELECT', 2);
The SQL DDL of this project - ignored if Database Backend: $config['databaseBackend'] is set to false.
The CREATE TABLE statements must be formatted as follows:
Note that is is allowed (and somethimes even recommended) to put each configuration option on a separated line (as for f_activated). If Table Modifiers - General are used the formatting differs a bit:CREATE TABLE t_user( f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL /**isValid:isInt**/ /**sequence:t_user_userid**/ , f_group_id NUMBER /**isValid:isInt**/, f_firstname VARCHAR(100) /**isValid:isString:2:30**/, f_lastname VARCHAR(200) /**isValid:isString:2:30**/, f_activated CHAR(1) /**isValid:in:'0':'1'**/ /**defaultInsert:'1'**/ , UNIQUE(f_firstname,f_lastname), FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid) );
The specification of a table type is valid as well:CREATE TABLE t_user /**option1**/ /**option2**/ ( f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL /**isValid:isInt**/ /**sequence:t_user_userid**/, f_group_id NUMBER /**isValid:isInt**/, f_firstname VARCHAR(100) /**isValid:isString:2:30**/, f_lastname VARCHAR(200) /**isValid:isString:2:30**/, UNIQUE(f_firstname,f_lastname), FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid) );
Note:CREATE TABLE t_user /**option1**/ /**option2**/ ( f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL /**isValid:isInt**/ /**sequence:t_user_userid**/, f_group_id NUMBER /**isValid:isInt**/, f_firstname VARCHAR(100) /**isValid:isString:2:30**/, f_lastname VARCHAR(200) /**isValid:isString:2:30**/, UNIQUE(f_firstname,f_lastname), FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid) ) TYPE=MyISAM;
Table modifiers can be set beween the table name and the opening brace. The following format is strongly recommended.
It is recommended to wirte a table option on a single line if possible! It is possible though to write it over multiple lines. But realize that an opening brace on the end of a line is considered as the end of the table modifier section! Please follow the following coding conventions:
1 CREATE TABLE t_user
2 /**modifier1**/
2
3 /**modifier2**/
3
4 (
5 f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL,
6 f_group_id NUMBER,
7 f_firstname VARCHAR(100),
8 f_lastname VARCHAR(200),
9 UNIQUE(f_firstname,f_lastname),
10 FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid)
11 );
If a table is defined with this table modifier it is completly ignored.
1 CREATE TABLE t_user
2 /**ignore**/
2
3 (
4 f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL,
5 f_group_id NUMBER,
6 f_firstname VARCHAR(100),
7 f_lastname VARCHAR(200),
8 UNIQUE(f_firstname,f_lastname),
9 FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid)
10 );
This option defines which SQL expression will be used to define the lable of a record of the defined column. The label is used in all popup menues to represent a record. The default is to use the first column defined as VARCHAR.
1 CREATE TABLE t_user
2 /**label:CONCAT(CONCAT(f_lastname, ", "), f_firstname)**/
2
3 (
4 f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL,
5 f_group_id NUMBER,
6 f_firstname VARCHAR(100),
7 f_lastname VARCHAR(200),
8 UNIQUE(f_firstname,f_lastname),
9 FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid)
10 );
With this option you can define PHP code to get executed right before the insert operation.
1 CREATE TABLE t_user
2 /**beforeInsert:$registrationhistory =& $this->app->getTable('t_registrationhistory');
3 $error = $registrationhistory->insert(
4 array(
5 'f_user_id' > $inserts['f_userid']
6 );
7 );
8 if (PEAR::isError($error)) {
9 return $error;
10 }
11 **/
11
12 (
13 f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL,
14 f_group_id NUMBER,
15 f_firstname VARCHAR(100),
16 f_lastname VARCHAR(200),
17 UNIQUE(f_firstname,f_lastname),
18 FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid)
19 );
20
21 CREATE TABLE t_registrationhistory (
22 f_user_id NUMBER,
23 f_registrationdate DATETIME NOT NULL
24 /**defaultInsert:new RSDColumnValue('NOW()', '!')**/
24
25 /**doNotUpdate**/
25
26 );
Context: The code specified will be run before an insert operation. You will mostly use the variable $inserts which is an associative array containing column name and column value pairs (to be inserted). Not that a column value can be specifed as a string or as an instance of RSDColumnValue. Please see {@see RSDColumnValue}.
With this option you can define PHP code to get executed right after the insert operation.
1 CREATE TABLE t_user
2 /**afterInsert:$registrationhistory =& $this->app->getTable('t_registrationhistory');
3 $error = $registrationhistory->insert(
4 array(
5 'f_user_id' > $inserts['f_userid']
6 );
7 );
8 **/
8
9 (
10 f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL,
11 f_group_id NUMBER,
12 f_firstname VARCHAR(100),
13 f_lastname VARCHAR(200),
14 UNIQUE(f_firstname,f_lastname),
15 FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid)
16 );
17
18 CREATE TABLE t_registrationhistory (
19 f_user_id NUMBER,
20 f_registrationdate DATETIME NOT NULL
21 /**defaultInsert:new RSDColumnValue('NOW()', '!')**/
21
22 /**doNotUpdate**/
22
23 );
Context: The code specified will be run after a successful insert operation. If the insert failed for some reasons an instance of PEAR_Error will be returned before the spcecified code could be run. You will mostly use the variable $inserts which is an associative array containing column name and column value pairs. Not that a column value can be specifed as a string or as an instance of RSDColumnValue. Please see {@see RSDColumnValue}.
With this option you can define PHP code to get executed right before the update operation.
1 CREATE TABLE t_user
2 /**beforeUpdate:$changehistory =& $this->app->getTable('t_changehistory');
3 $error = $registrationhistory->insert(
4 array(
5 'f_user_id' > $record['f_userid']
6 );
7 );
8 if (PEAR::isError($error)) {
9 return $error;
10 }
11 **/
11
12 (
13 f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL,
14 f_group_id NUMBER,
15 f_firstname VARCHAR(100),
16 f_lastname VARCHAR(200),
17 UNIQUE(f_firstname,f_lastname),
18 FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid)
19 );
20
21 CREATE TABLE t_changehistory (
22 f_user_id NUMBER,
23 f_changedate DATETIME NOT NULL
24 /**defaultInsert:new RSDColumnValue('NOW()', '!')**/
24
25 /**doNotUpdate**/
25
26 );
Context: The code specified will be run before an update operation. The code is placed inside a while loop that loops over all records that will be affected by the update operation. You will mostly use the variable $record which represents (obviously) a record that will be updated. $record will always be an associative array with the column names as keys.
With this option you can define PHP code to get executed right after the update operation.
1 CREATE TABLE t_user
2 /**afterUpdate:$changehistory =& $this->app->getTable('t_changehistory');
3 $error = $registrationhistory->insert(
4 array(
5 'f_user_id' > $record['f_userid']
6 );
7 );
8 if (PEAR::isError($error)) {
9 return $error;
10 }
11 **/
11
12 (
13 f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL,
14 f_group_id NUMBER,
15 f_firstname VARCHAR(100),
16 f_lastname VARCHAR(200),
17 UNIQUE(f_firstname,f_lastname),
18 FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid)
19 );
20
21 CREATE TABLE t_changehistory (
22 f_user_id NUMBER,
23 f_changedate DATETIME NOT NULL
24 /**defaultInsert:new RSDColumnValue('NOW()', '!')**/
24
25 /**doNotUpdate**/
25
26 );
Context: The code specified will be run after a successful update operation. If the update failed for some reasons an instance of PEAR_Error will be returned before the spcecified code could be run. The code is placed inside a while loop that loops over all records that where affected by the update operation. You will mostly use the variable $record which represents (obviously) a record that was updated. $record will always be an associative array with the column names as keys. NOTE: The records that you reference via $record are already updated!
With this option you can define PHP code to get executed right before the delete operation.
1 CREATE TABLE t_user
2 /**beforeDelete:$deletehistory =& $this->app->getTable('t_deletehistory');
3 $error = $registrationhistory->insert(
4 array(
5 'f_user_id' > $record['f_userid']
6 );
7 );
8 if (PEAR::isError($error)) {
9 return $error;
10 }
11 **/
11
12 (
13 f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL,
14 f_group_id NUMBER,
15 f_firstname VARCHAR(100),
16 f_lastname VARCHAR(200),
17 UNIQUE(f_firstname,f_lastname),
18 FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid)
19 );
20
21 CREATE TABLE t_deletehistory (
22 f_user_id NUMBER,
23 f_deletedate DATETIME NOT NULL
24 /**defaultInsert:new RSDColumnValue('NOW()', '!')**/
24
25 /**doNotUpdate**/
25
26 );
Context: The code specified will be run before a delete operation. The code is placed inside a while loop that loops over all records that will be affected by the delete operation. You will mostly use the variable $record which represents (obviously) a record that will be deleted. $record will always be an associative array with the column names as keys.
With this option you can define PHP code to get executed right after the delete operation.
1 CREATE TABLE t_user
2 /**afterDelete:$deletehistory =& $this->app->getTable('t_deletehistory');
3 $error = $registrationhistory->insert(
4 array(
5 'f_user_id' > $record['f_userid']
6 );
7 );
8 if (PEAR::isError($error)) {
9 return $error;
10 }
11 **/
11
12 (
13 f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL,
14 f_group_id NUMBER,
15 f_firstname VARCHAR(100),
16 f_lastname VARCHAR(200),
17 UNIQUE(f_firstname,f_lastname),
18 FOREIGN KEY (f_group_id) REFERENCES(t_group.f_groupid)
19 );
20
21 CREATE TABLE t_deletehistory (
22 f_user_id NUMBER,
23 f_deletedate DATETIME NOT NULL
24 /**defaultInsert:new RSDColumnValue('NOW()', '!')**/
24
25 /**doNotUpdate**/
25
26 );
Context: The code specified will be run after a successful delete operation. If the delete failed for some reasons an instance of PEAR_Error will be returned before the spcecified code could be run. The code is placed inside a while loop that loops over all records that where affected by the delete operation. You will mostly use the variable $record which represents (obviously) a record that was updated. $record will always be an associative array with the column names as keys. NOTE: Do not forget that the records you access via $record actually do not exist any more (they have already been deleted).
This option must be in the following format:
/**LiveUserRight[:$OPERATION]:rightId=$RIGHT_ID|condition=PHP_CODE|recordCondition=PHP_CODE**/Or a little more specific:
/**LiveUserRight[:select|insert|update|delete|all][:rightId=column|table.column|SQL_QUERY|PHP_CODE]|[condition=PHP_CODE|recordCondition=PHP_CODE]**/$OPERATION can therefore be one of:
This allows a select operation for everybody and forbids everything else. It is equivalent to the following:
1 CREATE TABLE t_document
2 /**LiveUserRight:all:condition=false**/
2
3 /**LiveUserRight:select:condition=true**/
3
4 (
5 f_documentid INTEGER NOT NULL PRIMARY KEY
6 /**isValid:isInt**/
6
7 /**sequence:prj_document_documentid**/
7 ,
8 f_folder_id INTEGER /**isValid:isInt**/
8 ,
9 f_selectdocumentright /**isValid:isInt**/
9 ,
10 f_lastmodified DATE
11 /**isValid:isDate**/
11
12 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
12
13 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
13 ,
14 f_title VARCHAR(100) /**isValid:isString:2:100**/
14
15 );
1 CREATE TABLE t_document
2 /**LiveUserRight:insert:condition=false**/
2
3 /**LiveUserRight:update:condition=false**/
3
4 /**LiveUserRight:delete:condition=false**/
4
5 /**LiveUserRight:select:condition=true**/
5
6 (
7 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
7 /**sequence:prj_document_documentid**/
7 ,
8 f_folder_id INTEGER /**isValid:isInt**/
8 ,
9 f_selectdocumentright /**isValid:isInt**/
9 ,
10 f_lastmodified DATE /**isValid:isDate**/
10 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
10 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
10 ,
11 f_title VARCHAR(100) /**isValid:isString:2:100**/
11
12 );
1 CREATE TABLE t_document
2 /**LiveUserRight:condition=true**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_selectdocumentright /**isValid:isInt**/
6 ,
7 f_lastmodified DATE /**isValid:isDate**/
7 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
7 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
7 ,
8 f_title VARCHAR(100) /**isValid:isString:2:100**/
8
9 );
In the above example the generated select method will return only those records to which the user has access (has the right saved in f_selectdocumentright by id). If the the user has access to no records an empty array containing no records will be returned. Here is an other example with update:
1 CREATE TABLE t_document
2 /**LiveUserRight:select:rightId=f_selectdocumentright**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_selectdocumentright /**isValid:isInt**/
6 ,
7 f_lastmodified DATE /**isValid:isDate**/
7 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
7 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
7 ,
8 f_title VARCHAR(100) /**isValid:isString:2:100**/
8
9 );
The generated method 'update' will raise an error if the user does not have the rights saved in f_updatedocumentright for all columns she is about to update. So there is no 'partial' update - the requested update operation is performed or not. The same is true for delete:
1 CREATE TABLE t_document
2 /**LiveUserRight:select:rightId=f_selectdocumentright**/
2
3 /**LiveUserRight:update:rightId=f_updatedocumentright**/
3
4 (
5 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
5 /**sequence:prj_document_documentid**/
5 ,
6 f_folder_id INTEGER /**isValid:isInt**/
6 ,
7 f_selectdocumentright /**isValid:isInt**/
7 ,
8 f_updatedocumentright /**isValid:isInt**/
8 ,
9 f_lastmodified DATE /**isValid:isDate**/
9 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
9 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
9 ,
10 f_title VARCHAR(100) /**isValid:isString:2:100**/
10
11 );
1 CREATE TABLE t_document
2 /**LiveUserRight:select:rightId=f_selectdocumentright**/
2
3 /**LiveUserRight:update:rightId=f_updatedocumentright**/
3
4 /**LiveUserRight:delete:rightId=f_deletedocumentright**/
4
5 (
6 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
6 /**sequence:prj_document_documentid**/
6 ,
7 f_folder_id INTEGER /**isValid:isInt**/
7 ,
8 f_selectdocumentright /**isValid:isInt**/
8 ,
9 f_updatedocumentright /**isValid:isInt**/
9 ,
10 f_deletedocumentright /**isValid:isInt**/
10 ,
11 f_lastmodified DATE /**isValid:isDate**/
11 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
11 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
11 ,
12 f_title VARCHAR(100) /**isValid:isString:2:100**/
12
13 );
This works because the method RSDEngineDBTable::_getSelectIncludingMethodName finds the selectIncluding* method that performs a join over both tables based on the foreign key t_document.f_folder_id referencing the primary key t_folder.f_folderid. The generated method select will only return those records the user has access to. Again the methods 'delete' and 'update' raise a permission denied error if the permission for a single records is missing. Since RSDEngine v0.1.10 the type 'table.column' can be used for the operation 'insert' as well. In this case the RSDEngine tries to find a table that is directly related to the current table and is as well related to the 'target' table specified by 'table.column'.
1 CREATE TABLE t_document
2 /**LiveUserRight:select:rightId=t_folder.f_selectfolderright**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:seq_prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_lastmodified DATE /**isValid:isDate**/
6 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
6 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
6 ,
7 f_documentname VARCHAR(100) /**isValid:isString:2:100**/
7 ,
8 FOREIGN KEY (f_folder_id) REFERENCES t_folder (f_folderid)
9 );
10
11 CREATE TABLE t_folder
12 /**LiveUserRight:select:rightId=f_selectfolderright**/
12
13 (
14 f_folderid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
14 /**sequence:seq_prj_folder_folderid**/
14 ,
15 f_foldername VARCHAR(100) /**isValid:isString:2:100**/
15 ,
16 f_selectfolderright /**isValid:isInt**/
16
17 );
The most important difference to 'column' and 'table.column' is that the right is checked only once - not for every record! Let's go back to the privous example of documents and folders. If we only want to allow a user to create documents in folders she has (read-) access to we would do it like this:
1 $rightId = $db->getOne("WHATEVER_YOU_TYPED");
Note that we need to close the string with a double quote (") and open it afterwards again if we want to interrupt the SQL query. Be aware that $inserts['f_folder_id'] is not quoted by that time. To prevent a SQL injection we need to call $this->db->quote.
1 CREATE TABLE t_document
2 /**LiveUserRight:select:rightId=t_folder.f_selectfolderright**/
2
3 /**LiveUserRight:insert:rightId=SELECT f_selectfolderright FROM efx_folder WHERE f_folderid=" . $this->db->quote($inserts['f_folder_id']) . "**/
3
4 (
5 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
5 /**sequence:seq_prj_document_documentid**/
5 ,
6 f_folder_id INTEGER /**isValid:isInt**/
6 ,
7 f_lastmodified DATE /**isValid:isDate**/
7 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
7 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
7 ,
8 f_documentname VARCHAR(100) /**isValid:isString:2:100**/
8 ,
9 FOREIGN KEY (f_folder_id) REFERENCES t_folder (f_folderid)
10 );
11
12 CREATE TABLE t_folder
13 /**LiveUserRight:select:rightId=f_selectfolderright**/
13
14 (
15 f_folderid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
15 /**sequence:seq_prj_folder_folderid**/
15 ,
16 f_foldername VARCHAR(100) /**isValid:isString:2:100**/
16 ,
17 f_selectfolderright /**isValid:isInt**/
17
18 );
The most important difference to 'column' and 'table.column' is that the right is checked only once - not for every record! The most common usage will be the use of constants that are used to save certain right-IDs. Use Database Backend: $config['additionalConfig'] to define these constants. In the following example the user must have the right with the ID saved in PRJ_LIVEUSER_RIGHT_DOCUMENT_SELECT in order to select records from this table.
1 $rightId = WHATEVER_YOU_TYPED;
Now a little more complex example. It solves the same problem as the example of 'SQL_QUERY'.
1 CREATE TABLE t_document
2 /**LiveUserRight:select:PRJ_LIVEUSER_RIGHT_DOCUMENT_SELECT**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_selectdocumentright /**isValid:isInt**/
6 ,
7 f_lastmodified DATE /**isValid:isDate**/
7 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
7 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
7 ,
8 f_title VARCHAR(100) /**isValid:isString:2:100**/
8
9 );
The object that represents the table t_document and contains the method 'insert' has a property named 'db' that holds a handle to an instance of PEAR::DB. This is why we need to call $this->db->getOne. Be aware that $inserts['f_folder_id'] is not quoted by that time. To prevent a SQL injection we need to call $this->db->quote.
1 CREATE TABLE t_document
2 /**LiveUserRight:select:rightId=t_folder.f_selectfolderright**/
2
3 /**LiveUserRight:insert:rightId=$this->db->getOne("SELECT f_istemplatefolder FROM efx_folder WHERE f_folderid=" . $this->db->quote($inserts['f_folder_id']))**/
3
4 (
5 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
5 /**sequence:seq_prj_document_documentid**/
5 ,
6 f_folder_id INTEGER /**isValid:isInt**/
6 ,
7 f_lastmodified DATE /**isValid:isDate**/
7 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
7 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
7 ,
8 f_documentname VARCHAR(100) /**isValid:isString:2:100**/
8 ,
9 FOREIGN KEY (f_folder_id) REFERENCES t_folder (f_folderid)
10 );
11
12 CREATE TABLE t_folder
13 /**LiveUserRight:select:rightId=f_selectfolderright**/
13
14 (
15 f_folderid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
15 /**sequence:seq_prj_folder_folderid**/
15 ,
16 f_foldername VARCHAR(100) /**isValid:isString:2:100**/
16 ,
17 f_selectfolderright /**isValid:isInt**/
17
18 );
But be aware that this condition will be used as well in the generated method canDelete. As this method is not always called with an argument the following would cause NOTICES:
1 CREATE TABLE t_document
2 /**LiveUserRight:delete:condition=$this->app->isAdmin()**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_selectdocumentright /**isValid:isInt**/
6 ,
7 f_lastmodified DATE /**isValid:isDate**/
7 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
7 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
7 ,
8 f_title VARCHAR(100) /**isValid:isString:2:100**/
8
9 );
You should make sure the variables you use are initialised:
1 CREATE TABLE t_document
2 /**LiveUserRight:delete:condition=$this->app->isAdmin() && $record['f_folder_id'] != '666'**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_selectdocumentright /**isValid:isInt**/
6 ,
7 f_lastmodified DATE /**isValid:isDate**/
7 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
7 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
7 ,
8 f_title VARCHAR(100) /**isValid:isString:2:100**/
8
9 );
This would keep the notices away but our canDelete method would allways return false if called with no arguements. To fix this you could write:
1 CREATE TABLE t_document
2 /**LiveUserRight:delete:condition=$this->app->isAdmin() && isset($record['f_folder_id']) && $record['f_folder_id'] != '666'**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_selectdocumentright /**isValid:isInt**/
6 ,
7 f_lastmodified DATE /**isValid:isDate**/
7 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
7 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
7 ,
8 f_title VARCHAR(100) /**isValid:isString:2:100**/
8
9 );
This is only advisable if the isValid options for f_folder_id would prevent the insertion of a record with f_folder_id not set. One more thing: if you want to reference a column value in an insert operation you have to use $inserts (not $record!):
1 CREATE TABLE t_document
2 /**LiveUserRight:delete:condition=(!isset($record['f_folder_id']) && $this->app->isAdmin()) || ($this->app->isAdmin() && isset($record['f_folder_id']) && $record['f_folder_id'] != '666')**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_selectdocumentright /**isValid:isInt**/
6 ,
7 f_lastmodified DATE /**isValid:isDate**/
7 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
7 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
7 ,
8 f_title VARCHAR(100) /**isValid:isString:2:100**/
8
9 );
This is probably a bit confusing but results from the fact that we simply do not deal with a record!
1 CREATE TABLE t_document
2 /**LiveUserRight:insert:condition=(!isset($inserts['f_folder_id']) && $this->app->isAdmin()) || ($this->app->isAdmin() && isset($inserts['f_folder_id']) && $inserts['f_folder_id'] != '666')**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_selectdocumentright /**isValid:isInt**/
6 ,
7 f_lastmodified DATE /**isValid:isDate**/
7 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
7 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
7 ,
8 f_title VARCHAR(100) /**isValid:isString:2:100**/
8
9 );
1 CREATE TABLE t_document
2 /**LiveUserRight:delete:recordCondition=$record['f_folder_id'] != 666**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_selectdocumentright /**isValid:isInt**/
6 ,
7 f_lastmodified DATE /**isValid:isDate**/
7 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
7 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
7 ,
8 f_title VARCHAR(100) /**isValid:isString:2:100**/
8
9 );
The following definition of file modifier is more specific (spread over multiple lines to increase readability):
The file modifier knows the folling options:
1 /**file
2 [:type=controllers|templates|classes|get|getOne|search|delete|update|create|getController|getOneController|searchController|deleteController|updateController|createController|getTemplate|getOneTemplate|searchTemplate|deleteTemplate|updateTemplate|createTemplate|childClass|baseClass|all]
3 [:write=true|false|overwrite]
4 [:public=true|false]
5 [:header=true|false]
6 [:footer=true|false]
7 [:showKeyColumns=true|false]
8 [:orderBy=SQL_EXPRESSION]
9 [:allowUserOrderBy=true|false]
10 [:paging=true|false]
11 [:recordsPerPage=X
12 [:selectMethodName=methodName]
13 [:separateRecordTemplate=true|false]
14 **/
To prevent the delete-controller from getting written to disk and to make the get-controller public you would define:
To prevent as well the delete-template from getting written you could write:CREATE TABLE prj_user /**file:type=deleteController:write=false**/ /**file:type=getController:public=true**/ ( f_userid INT, f_firstname VARCHAR(100), f_lastname VARCHAR(100) );
This works becuase delete is a "container". It is equivalent to writingCREATE TABLE prj_user /**file:type=delete:write=false**/ /**file:type=getController:public=true**/ ( f_userid INT, f_firstname VARCHAR(100), f_lastname VARCHAR(100) );
If you want the get and the getOne controller to use the selectIncluding-method selectIncludingAll and the search controller to use selectIncludingDirectlyRelated you could writeCREATE TABLE prj_user /**file:type=deleteController:write=false**/ /**file:type=deleteTemplate:write=false**/ /**file:type=getController:public=true**/ ( f_userid INT, f_firstname VARCHAR(100), f_lastname VARCHAR(100) );
You could as well writeCREATE TABLE prj_user /**file:type=get:selectMethodName=selectIncludingAll**/ /**file:type=getOne:selectMethodName=selectIncludingAll**/ /**file:type=search:selectMethodName=selectIncludingDirectlyRelated**/ ( f_userid INT, f_firstname VARCHAR(100), f_lastname VARCHAR(100) );
The first /**file**/ modifier is owerwritten by the second one for the type and options specified. This means that in the following example orderBy will be `f_firstname DESC' for all controllers:CREATE TABLE prj_user /**file:type=all:selectMethodName=selectIncludingAll**/ /**file:type=search:selectMethodName=selectIncludingDirectlyRelated**/ ( f_userid INT, f_firstname VARCHAR(100), f_lastname VARCHAR(100) );
Note: the second /**file**/ modifier only overwrites selectMethodName for the file type 'search' - nothing else.CREATE TABLE prj_user /**file:type=all:selectMethodName=selectIncludingAll:orderBy=f_firstname DESC**/ /**file:type=search:selectMethodName=selectIncludingDirectlyRelated**/ ( f_userid INT, f_firstname VARCHAR(100), f_lastname VARCHAR(100) );
With this table modifier you can reduce the number of generated selectIncluding-methods. This is useful because the RSDEngine creates a selectIncluding-method for every possible combination of tables that are related to the current table. But you cannot exclude selectIncluding-methods that are required to produce ready-to-run code. This means that you cannot exclude selectIncludingAll, selectIncludingDirectlyRelated and all methods required to retrieve a LiveUser right or were explicitly specified with the selectMethodName option of the table modifier /**file**/.
Technically spoken selectIncludingAll, selectIncludingDirectlyRelated and all methods returned by {@see RSDEngineDBTable::_getSelectIncludingMethodName} or passed to {@see RSDEngineDBTable::getSelectMethodColumns} cannot be excluded.
The regular expressions you specify are used in the following way:
This allows you to specify a comma separated list of method names you want to be excluded - without thinking about perl regular expressions:
1 preg_match("/^$REG_EXPR\$/", $methodName)
To exclude all methods that perform a join over pcs_message, pcs_discussion and 3rd table you would write:CREATE TABLE pcs_message /**excludeSelectMethod:selectIncludingDiscussion,selectIncludingDiscussionAndProject**/ ( f_messageid BIGINT UNSIGNED NOT NULL, f_messagetype_id BIGINT UNSIGNED NOT NULL, f_user_id BIGINT UNSIGNED NOT NULL /**defaultInsert:$this->app->getUserId()**/ /**doNotUpdate**/, f_discussion_id BIGINT UNSIGNED NOT NULL, f_messagecreationdate DATETIME NULL /**defaultInsert:new RSDColumnValue('NOW()', '!')**/, f_messagesubject VARCHAR(255) NOT NULL, f_content TEXT NOT NULL, PRIMARY KEY(f_messageid), INDEX idx_pcs_message_messagetype_id(f_messagetype_id), INDEX idx_pcs_message_user_id(f_user_id), INDEX idx_pcs_message_discussion_id(f_discussion_id), FOREIGN KEY(f_discussion_id) REFERENCES pcs_discussion(f_discussionid) ON DELETE NO ACTION ON UPDATE NO ACTION, FOREIGN KEY(f_user_id) REFERENCES pcs_user(f_userid) ON DELETE NO ACTION ON UPDATE NO ACTION, FOREIGN KEY(f_messagetype_id) REFERENCES pcs_messagetype(f_messagetypeid) ON DELETE NO ACTION ON UPDATE NO ACTION );
But the most common use of this table modifier will be to exclude all methods that are not somehow required. A synonym for `.*' is `all' or `ALL':CREATE TABLE pcs_message /**excludeSelectMethod:selectIncludingDiscussionAnd[A-Z][a-z]***/ ( f_messageid BIGINT UNSIGNED NOT NULL, f_messagetype_id BIGINT UNSIGNED NOT NULL, f_user_id BIGINT UNSIGNED NOT NULL /**defaultInsert:$this->app->getUserId()**/ /**doNotUpdate**/, f_discussion_id BIGINT UNSIGNED NOT NULL, f_messagecreationdate DATETIME NULL /**defaultInsert:new RSDColumnValue('NOW()', '!')**/, f_messagesubject VARCHAR(255) NOT NULL, f_content TEXT NOT NULL, PRIMARY KEY(f_messageid), INDEX idx_pcs_message_messagetype_id(f_messagetype_id), INDEX idx_pcs_message_user_id(f_user_id), INDEX idx_pcs_message_discussion_id(f_discussion_id), FOREIGN KEY(f_discussion_id) REFERENCES pcs_discussion(f_discussionid) ON DELETE NO ACTION ON UPDATE NO ACTION, FOREIGN KEY(f_user_id) REFERENCES pcs_user(f_userid) ON DELETE NO ACTION ON UPDATE NO ACTION, FOREIGN KEY(f_messagetype_id) REFERENCES pcs_messagetype(f_messagetypeid) ON DELETE NO ACTION ON UPDATE NO ACTION );
CREATE TABLE pcs_message /**excludeSelectMethod:ALL**/ ( f_messageid BIGINT UNSIGNED NOT NULL, f_messagetype_id BIGINT UNSIGNED NOT NULL, f_user_id BIGINT UNSIGNED NOT NULL /**defaultInsert:$this->app->getUserId()**/ /**doNotUpdate**/, f_discussion_id BIGINT UNSIGNED NOT NULL, f_messagecreationdate DATETIME NULL /**defaultInsert:new RSDColumnValue('NOW()', '!')**/, f_messagesubject VARCHAR(255) NOT NULL, f_content TEXT NOT NULL, PRIMARY KEY(f_messageid), INDEX idx_pcs_message_messagetype_id(f_messagetype_id), INDEX idx_pcs_message_user_id(f_user_id), INDEX idx_pcs_message_discussion_id(f_discussion_id), FOREIGN KEY(f_discussion_id) REFERENCES pcs_discussion(f_discussionid) ON DELETE NO ACTION ON UPDATE NO ACTION, FOREIGN KEY(f_user_id) REFERENCES pcs_user(f_userid) ON DELETE NO ACTION ON UPDATE NO ACTION, FOREIGN KEY(f_messagetype_id) REFERENCES pcs_messagetype(f_messagetypeid) ON DELETE NO ACTION ON UPDATE NO ACTION );
With this table modifyer you can include methods excluded with Table Modifier /**excludeSelectMethod:REG_EXPR[,REG_EXPR][,REG_EXPR][...]**/. This can save you some typing:
CREATE TABLE pcs_message /**excludeSelectMethod:ALL**/ /**includeSelectMethod:selectIncludingDiscussion**/ ( f_messageid BIGINT UNSIGNED NOT NULL, f_messagetype_id BIGINT UNSIGNED NOT NULL, f_user_id BIGINT UNSIGNED NOT NULL /**defaultInsert:$this->app->getUserId()**/ /**doNotUpdate**/, f_discussion_id BIGINT UNSIGNED NOT NULL, f_messagecreationdate DATETIME NULL /**defaultInsert:new RSDColumnValue('NOW()', '!')**/, f_messagesubject VARCHAR(255) NOT NULL, f_content TEXT NOT NULL, PRIMARY KEY(f_messageid), INDEX idx_pcs_message_messagetype_id(f_messagetype_id), INDEX idx_pcs_message_user_id(f_user_id), INDEX idx_pcs_message_discussion_id(f_discussion_id), FOREIGN KEY(f_discussion_id) REFERENCES pcs_discussion(f_discussionid) ON DELETE NO ACTION ON UPDATE NO ACTION, FOREIGN KEY(f_user_id) REFERENCES pcs_user(f_userid) ON DELETE NO ACTION ON UPDATE NO ACTION, FOREIGN KEY(f_messagetype_id) REFERENCES pcs_messagetype(f_messagetypeid) ON DELETE NO ACTION ON UPDATE NO ACTION );
All modifiers but 'PRIMARY KEY' and 'UNIQUE' are surrunded by /** and **/ to distinguish them from normal comments starting with /* and ending with */ which are ignored. It is allowed to place each column modifier on a separate line but be aware that it is strongly recommended no to break up one column modifier over multiple lines. (This is because the columns are sepereated by performing a split(',\n') operation.) The following column modifiers are supported:
The column will not be parsed and completely ignored by the RSDEngine. Example:
Actually /**ignore**/ can also be used for table constraints (UNIQUE, FOREIGN KEY (..) REFERENCES (...)). In the following example the table constraint UNIQUE and the FOREIGN KEY definition would be complitly ignored by the RSDEngine:CREATE TABLE t_test( f_test VARCHAR(200), f_creationdate DATE /**ignore**/ );
CREATE TABLE prj_user( f_userid INTEGER PRIMARY KEY NOT NULL /**sequence:seq_prj_user_userid**/, f_group_id INTEGER, f_firstname VARCHAR(200), f_lastname VARCHAR(200), UNIQUE(f_firstname, f_lastname) /**ignore**/, FOREIGN KEY (f_group_id) REFERENCES(prj_group.f_groupid) /**ignore**/ );
As explained in Column Modifier /**isValid:TYPE:ARG1:ARG2:ARG3...**/ only values with a prepare string of `?' are validated. Thus NULL values are in fact always valid. What this column modifier really does is to leave the choice whether to insert/update a NULL value to the template designer. If the template designer defines that a select option with the value "userSubmittedNULL", NULL will be inserted/updated. This allows the controllers not to deal with this issue. Wheather the string "userSubmittedNULL" should be replace by a real NULL value (specified as as an instance of RSDColumnValue [new RSDColumnValue('NULL', '!')] is defined in the application logic through /**canBeNull**/. The result will be that the use will not be forced to select an option in a select menue. In the following example the user would not be forced to specify a group for the user to create/update.
CREATE TABLE prj_user( f_userid INTEGER PRIMARY KEY NOT NULL /**sequence:seq_prj_user_userid**/, f_group_id INTEGER /**canBeNull**/, f_firstname VARCHAR(200), f_lastname VARCHAR(200), UNIQUE(f_firstname, f_lastname), FOREIGN KEY (f_group_id) REFERENCES(prj_group.f_groupid) );
Values for this column must pass the specified validation. Note: Only values with a prepare string of `?' are validated! This is because these values are usually those that come from outside the Model (from outside the application logic; i.e. from the user himself). Besides that you whould have to validate SQL expressions like `NOW()' which is not very practicable. Please see {@see RSDTable::insert} and {@see RSDTable::update}. TYPE can be one of the follwoing:
NOTE: the following normally doesn't make a lot of sense because the values submitted by a user via an HTML-form are always interpreted as strings.CREATE TABLE t_test( f_test VARCHAR(200) /**isValid:in:'0':'1'**/ );
The following would only allow values for f_test that evaluate to 'y' or 'n'.CREATE TABLE t_test( f_test VARCHAR(200) /**isValid:in:0:1**/ );
Note that any php expression can be used:CREATE TABLE t_test( f_test VARCHAR(200) /**isValid:in:'y':'n'**/ );
would result inCREATE TABLE t_test( f_test VARCHAR(200) /**isValid:in:$GLOBALS['object']->getId():CONSTANT_ID**/ );
1 if (!($test === $GLOBALS['object']->getId() || $test === CONSTANT_ID))
Or a little more complex:CREATE TABLE t_test( f_test VARCHAR(200) /**isValid:code:$GLOBALS['someObject']->validate(%s)**/ );
which is by the way equivalent toCREATE TABLE t_test( f_test VARCHAR(200) /**isValid:code:%s === '0' || %s === '1' || %s === 'y' || %s === 'n'**/ );
would result inCREATE TABLE t_test( f_test VARCHAR(200) /**isValid:in:'0':'1':'y':'n'**/ );
1 if (!($test === '0' || $test === '1' || $test === 'y' || $test === 'n'))
It is recommended to use RSValidate for validation. For a list of the methods provided by RSValidation and thier useage please see the {@see RSValidation} and RSValidation. PEAR::Validate would do the job as well but the methods of RSValidation have a more intuitive order of arguments. Note: RSValidate extends PEAR::Validate! Usage example:
1 boolean RSValidation::isString($str, $minLength = null, $maxLength = null)
2 boolean RSValidation::isAlpha($str)
3 boolean RSValidation::isNumeric($str)
4 boolean RSValidation::isDate($str)
5 boolean RSValidation::isTime($str)
6 boolean RSValidation::isDateTime($str)
7 boolean RSValidation::isAlphanumeric($str)
8 boolean RSValidation::isEmail($str)
would result in the following code (if RSValidation was chosen for validation):CREATE TABLE t_test( f_test VARCHAR(200) /**isValid:isString:2:4**/ );
Note that any php expression can be used as argument:
1 if(!RSValidation::isString(2, 4))
would result inCREATE TABLE t_test( f_test VARCHAR(200) /**isValid:isString:2 + $GLOBALS['someObject']->getId():4**/ );
1 if(!RSValidation::isString(2 + $GLOBALS['someObject']->getId(), 4))
Note that every column defined with /**isValid:file...**/ needs to be defined with a sequence! This sequence will be used to generate the filenames. This allows all files to be stored in the same storage directory [recommened]. Note that you would not have to use the same sequence for all columns because the files are stored with a table and a column prefix. The following usage is recommended because it gives you the most security: /**isValid:file:size[KB|MB]:CONTENT_TYPE:DEFAULT_FILE**/.CREATE TABLE t_test( f_file1 VARCHAR(200) /**isValid:file**/ /**sequence:seq_test_files**/, f_file2 VARCHAR(200) /**isValid:file:1024**/ /**sequence:seq_test_files**/, f_file3 VARCHAR(200) /**isValid:file:10KB**/ /**sequence:seq_test_files**/, f_file4 VARCHAR(200) /**isValid:file:5MB**/ /**sequence:seq_test_files**/, f_file5 VARCHAR(200) /**isValid:file:5MB:image/**/ /**sequence:seq_test_files**/, f_file6 VARCHAR(200) /**isValid:file:5MB:image/jpg**/ /**sequence:seq_test_files**/, f_file7 VARCHAR(200) /**isValid:file:5MB:image/jpg:./images/file7Default.jpg**/ /**sequence:seq_test_files**/, f_file8 VARCHAR(200) /**isValid:file:5MB:image/jpg:./images/file8Default.jpg;./file8Storage**/ /**sequence:seq_test_files**/, f_file9 VARCHAR(200) /**isValid:file:::./images/file8Default.jpg**/ /**sequence:seq_test_files**/ );
Specifies the HTML input type to use in the template. TYPE can be one of the follwoing:
CREATE TABLE t_test( f_test VARCHAR(200) /**inputType:text**/ );
CREATE TABLE t_test( f_password VARCHAR(200) /**inputType:password**/ );
Note that this is the default behaviour for all foreign key columns. In the following example we specify TYPE_DATA:CREATE TABLE t_test( f_test VARCHAR(200) /**inputType:select**/, FOREIGN KEY(f_test) REFERENCES t_test2(f_test2) );
And now a little different (the status is saved by name not by ID):CREATE TABLE t_test( f_status CHAR(1) /**isValid:in:'0':'1':'2'**/ /**inputType:select:array('0' => 'unknown', '1' => 'in work', '2' => 'done')**/ );
Please note that using TYPE_DATA should be used with care! If the possible values are likely to chage, consider creating a new table for all possible values and link that with a foreign key. This increases maintainability.CREATE TABLE t_test( f_status VARCHAR(7) /**isValid:in:'unknown':'in work':'done'**/ /**inputType:select:array('unknown' => 'unknown', 'in work' => 'in work', 'done' => 'done')**/ );
CREATE TABLE t_test( f_activated VARCHAR(200) /**isValid:in:'Y':'N'**/ /**inputType:checkbox:array('checked' => 'Y', 'unchecked' => 'N')**/ );
The generated method 'insert' will use PHP_EXPRESSION as default value for this column. This is useful if you want to insert the current date and time by default (for, let's say a f_creationdate column). Please read RSDTable::insert first. The array, that is passed to insert as argument, holds the inserts as key value pairs. The key is the column name while the value can be a string or again an array. Again, read RSDTable::insert if you do not understand this! The array element for this column will be constructed like this:
So if you want the integer 0 to be the default value you would write
1 'f_columnname' => PHP_EXPRESSION
Note that you have to be careful if you additionaly defined this column as /**isValid:in:'0':'1'**/ as described in Column Modifier /**isValid:TYPE:ARG1:ARG2:ARG3...**/. Because /**isValid:in:'0':'1'**/ would result in the isValid condition %s === '0' || %s === '1' which would not be true for our default value. So if you defined your column as /**isValid:in:'0':'1'**/ use /**defaultInsert:'0'**/. For inserting the current date and time (in MySQL) you would write
1 /**defaultInsert:0**/
If you want to save the creation date of a record you would additionally define the column with Column Modifier /**doNotUpdate**/:
1 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
Please note that all columns defined with /**defaultInsert...**/ are treated as if defined as well with Column Modifier /**doNotInsert**/.CREATE TABLE prj_test( f_testid INTEGER INTEGER PRIMARY KEY NOT NULL /**sequence:seq_prj_test_testid**/, f_test VARCHAR(200) /**isValid:isString:2:200**/, f_creationdate DATE /**defaultInsert:new RSDColumnValue('NOW()','!')**/ /**doNotUpdate**/ );
The generated method 'update' will use PHP_EXPRESSION as default value for this column. This is useful if you want to update a f_lastmodified column with the current date and time by default. Please read RSDTable::update first. The array, that is passed to update as argument, holds the updates as key value pairs. The key is the column name while the value can be a string or again an array. Again, read RSDTable::update if you do not understand this! The array element for this column will be constructed like this:
So if you want the integer 0 to be the default value you would write
1 'f_columnname' => PHP_EXPRESSION
Note that you have to be careful if you additionaly defined this column as /**isValid:in:'0':'1'**/ as described in Column Modifier /**isValid:TYPE:ARG1:ARG2:ARG3...**/. Because /**isValid:in:'0':'1'**/ would result in the isValid condition %s === '0' || %s === '1' which would not be true for our default value. So if you defined your column as /**isValid:in:'0':'1'**/ use /**defaultUpdate:'0'**/. For updating a column by default with the current date and time (in MySQL) you would write
1 /**defaultUpdate:0**/
If you want to save the date of the last modification of the record in a column named f_lastmodified you would use both /**defaultInsert...**/ and /**defaultUpdate...**/:
1 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
Please note that all columns defined with /**defaultUpdate...**/ are treated as if defined as well with Column Modifier /**doNotUpdate**/.CREATE TABLE prj_test( f_testid INTEGER PRIMARY KEY NOT NULL /**sequence:seq_prj_test_testid**/, f_test VARCHAR(200) /**isValid:isString:2:200**/, f_lastmodified DATE /**defaultInsert:new RSDColumnValue('NOW()','!')**/ /**defaultUpdate:new RSDColumnValue('NOW()','!')**/ );
If provided a method named getNextCOLUMNNAME will be created that returns the next id from the sequence specified. Note that sequences are emulated by PEAR::DB if not supported by the RDBMS. Please follow the naming conventions of RSD for naming sequences. Example:
Note that if you define a primary key column with a sequence, the return value of the generated getNext-Method will be used as default value for this column in the method insert. Please see Column Modifier /**defaultInsert:PHP_EXPRESSION**/ for details on default values.CREATE TABLE prj_test( f_test VARCHAR(200), f_testid NUMBER /**sequence:seq_prj_test_testid**/ );
The generated controllers and templates that handle the creation of a new record will not deal with this column. Example:
This comes in handy when you have columns that a user should not edit directly (or not at all). Please note that all columns defined with Column Modifier /**defaultInsert:PHP_EXPRESSION**/ are treated as if defined with /**doNotInsert**/.CREATE TABLE prj_test( f_test VARCHAR(200), f_creationdate DATE /**doNotInsert**/ f_test2 VARCHAR(200) DEFAULT 'undefined' /**doNotInsert**/ );
The generated teplates will not display this column. Example:
As in the example above it my be appropriate not to display certain columns.CREATE TABLE prj_user( f_userid INTEGER PRIMARY KEY NOT NULL /**sequence:seq_prj_user_userid** f_username VARCHAR(200), f_password VARCHAR(200) /**doNotSelect**/ );
The generated controllers and templates that handle an update operation of a record will not deal with this column. Example:
This comes in handy when you have columns that a user should not edit directly (or not at all). Please note that all columns defined with Column Modifier /**defaultUpdate:PHP_EXPRESSION**/ are treated as if defined with /**doNotUpdate**/.CREATE TABLE prj_test( f_test VARCHAR(200), f_creationdate DATE /**doNotUpdate**/ f_test2 VARCHAR(200) DEFAULT 'undefined' /**doNotUpdate**/ );
If this column modifier is used the LiveUser right stored in this column by ID is deleted when the containing record is deleted. In the following example a new LiveUser right will be created for each record - and deleted again when the record is deleted:
In fact this is just a synonym for the table modifier Table Modifier /**afterUpdate:PHP_CODE**/ used in the following way:
1 CREATE TABLE t_document
2 /**LiveUserRight:select:rightId=f_selectdocumentright**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_selectdocumentright
7 /**isValid:isInt**/
7
8 /**deleteLiveUserRightOnDelete**/
8
9 /**doNotUpdate**/
9
10 /**defaultInsert:$this->app->addLiveUserRight(1, 'EFX_LIVEUSER_RIGHT_DOCUMENT_SELECT', 'EFX_LIVEUSER_RIGHT_DOCUMENT_SELECT', array($this->app->liveUser->getProperty('permUserId')))**/
10
11 ,
12 f_lastmodified DATE /**isValid:isDate**/
12 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
12 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
12 ,
13 f_title VARCHAR(100) /**isValid:isString:2:100**/
13
14 );
1 /**afterDelete:$this->app->callLiveUserPermAdminMethod('removeRight', array($record['f_selectdocumentright']));**/
If this column modifier is used the LiveUser group stored in this column by ID is deleted when the containing record is deleted. In the following example a new LiveUser group will be created for each record - and delete again when the record is deleted.
1 CREATE TABLE t_document
2 /**LiveUserRight:select:rightId=f_selectdocumentright**/
2
3 (
4 f_documentid INTEGER NOT NULL PRIMARY KEY /**isValid:isInt**/
4 /**sequence:prj_document_documentid**/
4 ,
5 f_folder_id INTEGER /**isValid:isInt**/
5 ,
6 f_selectdocumentright
7 /**isValid:isInt**/
7
8 /**deleteLiveUserRightOnDelete**/
8
9 /**doNotUpdate**/
9
10 /**defaultInsert:$this->app->addLiveUserRight(1, 'EFX_LIVEUSER_RIGHT_DOCUMENT_SELECT', 'EFX_LIVEUSER_RIGHT_DOCUMENT_SELECT', array($this->app->liveUser->getProperty('permUserId')))**/
10
11 ,
12 f_lastmodified DATE /**isValid:isDate**/
12 /**defaultInsert:new RSDColumnValue('NOW()','!')**/
12 /**defaultUpdate:new RSDColumnValue('NOW()','!')**/
12 ,
13 f_title VARCHAR(100) /**isValid:isString:2:100**/
13
14 );
1 /**afterDelete:$this->app->callLiveUserPermAdminMethod('removeGroup', array($record['f_selectdocumentright']));**/
If this column modifier is used the LiveUser area stored in this column by ID is deleted when the containing record is deleted. In fact this is just a synonym for the table modifier Table Modifier /**afterUpdate:PHP_CODE**/ used in the following way:
1 /**afterDelete:$this->app->callLiveUserPermAdminMethod('removeArea', array($record['f_columnname']));**/
If this column modifier is used the LiveUser right stored in this column by ID is made editable. A more specific definition of this option is
/**editLiveUserRight[:userRight|groupRight|grantRight|revokeRight|grantUserRight|revokeUserRight|grantGroupRight|revokeGroupRight|all][[:rightId=column|table.column|SQL_QUERY|PHP_CODE]|condition=PHP_CODE**/Therefore $OPERATION can be one of the following:
For more details on how to use the different $RIGHT_ID types or condition=PHP_CODE please see Table Modifier /**LiveUserRight[:$OPERATION]:rightId=$RIGHT_ID|condition=PHP_CODE|recordCondition=PHP_CODE**/.
1 CREATE TABLE ehr_workgroup
2 /**LiveUserRight:update:rightId=f_workgroupupdate**/
2
3 (
4 f_workgroupid INT UNSIGNED NOT NULL,
5 f_workgroupname VARCHAR(100) NULL,
6 f_workgroupupdate INT UNSIGNED NOT NULL
7 /**isValid:isInt**/
7
8 /**deleteLiveUserRightOnDelete**/
8
9 /**defaultInsert:$this->app->addLiveUserRight(1, 'EHR_WORKGROUP_UPDATE', 'EHR_WORKGROUP_UPDATE')**/
9
10 /**doNotUpdate**/
10
11 /**editLiveUserRight:grantRight**/
11
12 /**editLiveUserRight:revokeUserRight:condition=$this->app->isAdmin()**/
12
13 /**editLiveUserRight:revokeGroupRight:condition=false**/
13
14 );
If this column modifier is used the LiveUser area stored in this column by ID is made editable. A more specific definition of this option is
/**editLiveUserArea[:addAdmin|removeAdmin|updateNameAndComment|all][:[rightId=column|table.column|SQL_QUERY|PHP_CODE]|[condition=PHP_CODE]]**/Therefore $OPERATION can be one of the following:
Note that the second editLiveUserArea option overwrites the first one for the operation updateNameAndComment. For more details on how to use the different $RIGHT_ID types or condition=PHP_CODE please see Table Modifier /**LiveUserRight[:$OPERATION]:rightId=$RIGHT_ID|condition=PHP_CODE|recordCondition=PHP_CODE**/.
1 CREATE TABLE ehr_workgroup
2 /**LiveUserRight:update:rightId=f_workgroupupdate**/
2
3 (
4 f_workgroupid INT UNSIGNED NOT NULL,
5 f_workgroupname VARCHAR(100) NULL,
6 f_workgroupupdate INT UNSIGNED NOT NULL
7 /**isValid:isInt**/
7
8 /**deleteLiveUserRightOnDelete**/
8
9 /**defaultInsert:$this->app->addLiveUserRight(1, 'EHR_WORKGROUP_UPDATE', 'EHR_WORKGROUP_UPDATE')**/
9
10 /**doNotUpdate**/
10
11 /**editLiveUserRight:grantRight**/
11
12 /**editLiveUserRight:revokeUserRight:condition=$this->app->isAdmin()**/
12
13 /**editLiveUserRight:revokeGroupRight:condition=false**/
13
14 ,
15 f_workgrouparea INT UNSIGNED NOT NULL
16 /**isValid:isInt**/
16
17 /**deleteLiveUserAreaOnDelete**/
17
18 /**defaultInsert:$this->app->addLiveUserArea(EHR_LIVEUSER_APPLICATION_ID, 'EHR_WORKGROUP_AREA', 'EHR_WORKGROUP_AREA', array($this->app->getUserId()))**/
18
19 /**doNotUpdate**/
19
20 /**editLiveUserArea:all:rightId=f_workgroupupdate**/
20
21 /**editLiveUserArea:updateNameAndComment:condition=false**/
21
22 );
If this column modifier is used the LiveUser group stored in this column by ID is made editable. A more specific definition of this option is
/**editLiveUserGroup[:addUser|removeUser|activate|deactivate|updateNameAndComment|all][:[rightId=column|table.column|SQL|PHP]|[condition=PHP_CODE]]**/Therefore $OPERATION can be one of the following:
Only administrators are allowed to create a new workgroup. When a new workgroup is created, a new group with the creator as the only member is created as well and its ID is assigned to the column f_workgroupgroup. It is only possible to add and to remove users from the group, not to change the name or comment. In order to do this the right stored in the column f_workgroupupdate is required. The ID of a newly created area with the creator as area admin is assigned to the column f_workgrouparea. The column f_workgroupupdate saves the right that is required to add or remove a user from the group saved in f_workgroupgroup or to perform a general update operation for this table. The right itself cannot be granted to any user or group. In the column f_workgroupmembership, the ID of another newly created right is stored. This right is granted to the group stored in f_workgroupgroup. It cannot be directly granted to any users or groups. Only administrators can delete workgroups. When a workgroup is deleted, the corresponding area, group and rights are deleted as well. A user must have the right stored in f_workgroupmembership in order to select a certain record from this table. This right can only be granted via adding the user to the group stored in f_workgroupgroup because the right cannot be directly granted (as already mentioned). The creator has the right stored in f_workgroupupdate because she is the admin of the area stored in f_workgrouparea and is member of the group stored in f_workgroupgroup. For more details on how to use the different $RIGHT_ID types or condition=PHP_CODE please see Table Modifier /**LiveUserRight[:$OPERATION]:rightId=$RIGHT_ID|condition=PHP_CODE|recordCondition=PHP_CODE**/.
1 CREATE TABLE prj_workgroup
2 /**LiveUserRight:insert:condition=$this->app->isAdmin()**/
2
3 /**LiveUserRight:update:rightId=f_workgroupupdate**/
3
4 /**LiveUserRight:delete:condition=$this->app->isAdmin()**/
4
5 /**LiveUserRight:select:rightId=f_workgroupmembership**/
5
6 (
7 f_workgroupid INT UNSIGNED NOT NULL,
8 f_workgroupname VARCHAR(100) NULL,
9 f_workgroupdescription TEXT NULL,
10 f_workgroupcreationdate DATE NULL /**defaultInsert:new RSDColumnValue('NOW()','!')**/
10 /**doNotUpdate**/
10 ,
11 f_workgroupdeactivated CHAR(1) NULL DEFAULT '0' /**isValid:in:'0':'1'**/
11 ,
12 f_workgroupgroup INT UNSIGNED NOT NULL
13 /**isValid:isInt**/
13
14 /**deleteLiveUserGroupOnDelete**/
14
15 /**defaultInsert:$this->app->addLiveUserGroup('PRJ_WORKGROUP_GROUP', array($this->app->getUserId()), 'This is a workgroup.')**/
15
16 /**doNotUpdate**/
16
17 /**editLiveUserGroup:addUser:rightId=f_workgroupupdate**/
17
18 /**editLiveUserGroup:removeUser:rightId=f_workgroupupdate**/
18
19 ,
20 f_workgrouparea INT UNSIGNED NOT NULL
21 /**isValid:isInt**/
21
22 /**deleteLiveUserAreaOnDelete**/
22
23 /**defaultInsert:$this->app->addLiveUserArea(PRJ_LIVEUSER_APPLICATION_ID, 'PRJ_WORKGROUP_AREA', 'PRJ_WORKGROUP_AREA', array($this->app->getUserId()))**/
23
24 /**doNotUpdate**/
24
25 /**editLiveUserArea:condition=false**/
25
26 ,
27 f_workgroupupdate INT UNSIGNED NOT NULL
28 /**isValid:isInt**/
28
29 /**deleteLiveUserRightOnDelete**/
29
30 /**defaultInsert:$this->app->addLiveUserRight($inserts['f_workgrouparea'], 'PRJ_WORKGROUP_UPDATE', 'PRJ_WORKGROUP_UPDATE')**/
30
31 /**doNotUpdate**/
31
32 /**editLiveUserRight:condition=false**/
32
33 ,
34 f_workgroupmembership INT UNSIGNED NOT NULL
35 /**isValid:isInt**/
35
36 /**deleteLiveUserRightOnDelete**/
36
37 /**defaultInsert:$this->app->addLiveUserRight($inserts['f_workgrouparea'], 'PRJ_WORKGROUP_MEMBERSHIP', 'PRJ_WORKGROUP_MEMBERSHIP', array(), array($inserts['f_workgroupgroup']))**/
37
38 /**doNotUpdate**/
38
39 /**editLiveUserRight:condition=false**/
39
40 ,
41 PRIMARY KEY(f_workgroupid),
42 UNIQUE INDEX idx_prj_workgroup_workgroupid(f_workgroupid)
43 );
If provided the methods getByCOLUMNNAME, updateByCOLUMNNAME and deleteByCOLUMNNAME will be generated for this column. Example:
This will not only generate the methods getByTestid, updateByTestid and deleteByTestid (f_testid was defined as a primary key) but as well getByName, updateByName and deleteByName.CREATE TABLE prj_test( f_testid NUMBER PRIMARY KEY NOT NULL /**sequence:seq_prj_test_testid**/, f_name VARCHAR(200) /**key**/ );
If provided this column will be treated as a primary key. This means:
CREATE TABLE prj_test( f_testid NUMBER PRIMARY KEY, f_name VARCHAR(200) );
If provided, it is verified before updating or inserting a record that the value for this column is unique. Example:
CREATE TABLE prj_test( f_username VARCHAR(200) UNIQUE, f_password VARCHAR(200) );
Defines column as a foreign key. Example:
defines f_group_id as foreign key referencing prj_group.f_groupid. The foreign key definition does not have to fit on one line and 'ON DELETE' and 'ON UPDATE' sections area legal as well (but will get ignored):CREATE TABLE prj_user( f_group_id NUMBER, f_username VARCHAR(200), f_password VARCHAR(200), FOREIGN KEY (f_group_id) REFERENCING(prj_group.f_groupid) );
CREATE TABLE prj_user( f_group_id NUMBER, f_username VARCHAR(200), f_password VARCHAR(200), FOREIGN KEY(f_group_id) REFERENCING(prj_group.f_groupid) ON DELETE NO ACTION ON UPDATE NO ACTION );
If used along with a FOREIGN KEY definition the referenced record will be deleted as well when a record of this table is deleted:
CREATE TABLE prj_test( f_test VARCHAR(20), f_test2_id INTEGER, FOREIGN KEY (f_test2_id) REFERENCING(prj_test2.f_test2id) /**deleteReferencedRecordOnDelete**/ );
Defines the combination of one ore columns as unique. Not that specifying only one column does work as well but is NOT recommended. Define the UNIQUE constraint as a column constraint if only one column is invloved! Example:
Defines the combination of f_user_id and f_group_id as unique. In this case it is a N:N relationship between users and groups. Using unique in this way prevents one user becoming a member in the same group twice. An unique contraint can as well be defined as an UNIQUE INDEX:CREATE TABLE prj_user_group( f_user_id NUMBER, f_group_id NUMBER, UNIQUE(f_user_id,f_group_id) );
CREATE TABLE prj_user_group( f_user_id NUMBER, f_group_id NUMBER, UNIQUE INDEX idx_prj_user_group_user_id_group_id (f_user_id,f_group_id) );
Defines one column as a primary key. Specifying more than one column would be valid SQL DDL but the RSDEngine is not able to handle it. Example:
This defines f_countryid as the primary key.CREATE TABLE prj_country( f_countryid NUMBER, f_countryname VARCHAR(50), PRIMARY KEY(f_countryid) );
An index definition like the following will be ignored:
CREATE TABLE prj_country( f_countryid NUMBER, f_countryname VARCHAR(50), INDEX idx_prj_country_countryid(f_countryid) );
If Database Backend: $config['makeIsValidAssumption'] is set an isValid option is guessed from the column type for all columns that are not defined with an isValid option. The following mapping was implemented:
CHAR VARYING(x), BINARY(x), VARBINARY(x), VARCHAR(x) and VARCHAR(x) --> isString:1:x CHAR(x) --> isString:x:x TINYBLOB, TINYTEXT --> isString:0:pow(2,8)-1 BLOB, TEXT --> isString:0:pow(2,16)-1 MEDIUMBLOB, MEDIUMTEXT --> isString:0:pow(2,24)-1 LONGBLOB, LONGTEXT --> isString:0:pow(2,32)-1 TINYINT --> isInt:-128:127 SMALLINT --> isInt:-32768:32767 MEDIUMINT --> isInt:-8388608:8388607 BIGINT --> isInt:-9223372036854775808:9223372036854775807 INT --> isInt:-2147483648:2147483647
If Database Backend: $config['makeSequenceAssumption'] is set a Column Modifier /**sequence:sequence_name**/ is internally added for all primary key columns that were not difine with one.
You can as well write a CREATE TABLE statement as follows (note dollar signs!):
This makes it possible to specify the names of the tables and columns at run time! This is done by passing an associative array as constructor argument. Example:CREATE TABLE $t_user( $f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL, $f_group_id NUMBER, $f_firstname VARCHAR(100), $f_lastname VARCHAR(200), UNIQUE($f_firstname,$f_lastname), FOREIGN KEY ($f_group_id) REFERENCES($t_group.$f_groupid) );
This would make PRJUser using the table prj_user (instead of t_user), the column f_first (instead of f_firstname) and f_last (instead of f_lastname). Note that we did not specify a value for $f_group_id. Therefore the column will be named as in the SQL DDL (with the leading dollar sign removed). This means that you can specify the dynimically named columns and tables - but you do not have to! It is as well possible to define only specific columns and tables with dynamic naming:
1 $options['t_user'] = 'prj_user';
2 $options['f_firstname'] = 'f_first';
3 $options['f_lastname'] = 'f_last';
4 $prjUser = new PRJUser(&$rsdApp, &$rsdApp->db, &$options);
This makes it only possible to name $f_group_id, and its foreign key target dynamically.CREATE TABLE t_user( f_userid NUMBER PRIMARY KEY UNIQUE NOT NULL, $f_group_id NUMBER, f_firstname VARCHAR(100), f_lastname VARCHAR(200), UNIQUE($f_firstname,$f_lastname), FOREIGN KEY ($f_group_id) REFERENCES($t_group.$f_groupid) );
Dynamic Naming is most useful if you want to write an application like an authentication system (please don't; use PEAR::Auth!) and want the user of your class (the programmer) to be able to specify what tables and columns to use without hacking around in your code.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. The method to call to get the records for the getOne controller. Methods that are always valid are: select, selectIncludingAll (performs a join over all tables related to this table) and selectIncludingDirectlyRelated (performs a join over the tables directly refrenced by a foreign key defined in this table). This option will be ignored if Database Backend: $config['databaseBackend'] or Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. The method to call to get the records for the search controller. Methods that are always valid are: select, selectIncludingAll (performs a join over all tables related to this table) and selectIncludingDirectlyRelated (performs a join over the tables directly refrenced by a foreign key defined in this table). This option will be ignored if Database Backend: $config['databaseBackend'] or Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. The method to call to get the records for the 'get' controller. Methods that are always valid are: select, selectIncludingAll (performs a join over all tables related to this table) and selectIncludingDirectlyRelated (performs a join over the tables directly refrenced by a foreign key defined in this table). This option will be ignored if Database Backend: $config['databaseBackend'] or Web Application: $config['webApplication'] is set to false.
Whether to implement a paging feature in the get controllers and templates. paging means that not all records are diplayed at once but that you can browse them per page. This option will be ignored if Database Backend: $config['databaseBackend'] or Web Application: $config['webApplication'] is set to false.
Whether to implement a paging feature in the search controllers and templates. paging means that not all records are diplayed at once but that you can browse them per page. This option will be ignored if Database Backend: $config['databaseBackend'] or Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. How many records to display per page. This option will be ignored if Database Backend: $config['databaseBackend'] or Web Application: $config['webApplication'] is set to false.
If the supplied value evaluates to the boolean value true an authentication system based on PEAR::Auth will be implemented. NOTE: $config['auth'] and all other authentication options will be ignored if Database Backend: $config['databaseBackend'] is set to false.
The name of the table that stores the login information - ignored if Authentication: $config['auth'] is set to false. This information is used to create a new instance of PEAR::Auth. Please see the documentation of PEAR::Auth for details.
The name of the column that stores the usernames - ignored if Authentication: $config['auth'] is set to false. This information is used to create a new instance of PEAR::Auth. Please see the documentation of PEAR::Auth for details.
The name of the column that stores the passwords - ignored if Authentication: $config['auth'] is set to false. This information is used to create a new instance of PEAR::Auth. Please see the documentation of PEAR::Auth for details.
The name of the column that stores the information if a user is activated (can log in). Pass an empty string if you do not need this feature. Ignored if Authentication: $config['auth'] is set to false. This information is used to create a new instance of PEAR::Auth. Please see the documentation of PEAR::Auth for details.
The name of the cryptographic algorithm to use for storing passwords. Use 'md5', 'crypt' or 'none'. If you might need the feature of sending a user his password use 'none' - ignored if Authentication: $config['auth'] is set to false. This information is used to create a new instance of PEAR::Auth. Please see the documentation of PEAR::Auth for details.
The name of the session cookie to set. IMPORTANT: If two applications on your system use the same cookie name a user who has once logged in at one of the applications can also use the other applications without logging in again! - ignored if Authentication: $config['auth'] is set to false. This information is used to create a new instance of PEAR::Auth. Please see the documentation of PEAR::Auth for details.
The maximum time a session can be idle (in seconds). From a security and performance standpoint of view it is highly recommended to set it to something smaller than 1800 (half an hour) - ignored if Authentication: $config['auth'] is set to false. This information is used to create a new instance of PEAR::Auth. Please see the documentation of PEAR::Auth for details.
The URL the user should be redirected to after logout. If your application resides in http://domain.com/app/ and you set $logoutURL to an empty string the user will be redirected to http://domain.com/app/ - ignored if Authentication: $config['auth'] is set to false. AUTH::setLogoutCallback is called to register a callback function that does the redirect.
Whether to implement the authentication and permission management system LiveUser. Please see http://pear.php.net/package-info.php?package=LiveUser and http://projects.21st-hq.de/liveuser for details. LiveUser is not stable yet but under very active development!
The session name (cookie name) LiveUser uses for all sessions. IMPORTANT: If two applications on your system use the same cookie name a user who has once logged in at one of the applications can also use the other applications without logging in again! This option is ignored if LiveUser: $config['liveUser'] is set to false.
The submit method used by the login form. Valid values are 'GET' and 'POST'. This option is ignored if LiveUser: $config['liveUser'] is set to false.
Whether to allow the use of the remember-me feature. The name of the "remember me" checkbox on the HTML login form must be 'rememberMe'. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The name for the cookie to store auth information in (used for the "remember me" feature) This option is ignored if LiveUser: $config['liveUserRememberMe'] is set to false.
The lifetime of the "remember me" cookie in days. Note that the cookie lifetime will be refreshed every time the user logs in. This option is ignored if LiveUser: $config['liveUserRememberMe'] is set to false.
The domain for the "remember me" cookie. To make the cookie available on all subdomains of example.com then you'd set it to '.example.com'. The . is not required but makes it compatible with more browsers. Setting it to www.example.com will make the cookie only available in the www subdomain. This option is ignored if LiveUser: $config['liveUserRememberMe'] is set to false.
The path for the "remember me" cookie. If set to '/', the cookie will be available within the entire domain. If set to '/foo/', the cookie will only be available within the /foo/ directory and all sub-directories such as /foo/bar/ of domain. The default value is the current directory that the cookie is being set in. This option is ignored if LiveUser: $config['liveUserRememberMe'] is set to false.
This is the secret key used for remember-me cookie value encryption. This option is ignored if LiveUser: $config['liveUserRememberMe'] is set to false.
The URL to redirect to when the user logs out. This option is ignored if LiveUser: $config['liveUser'] is set to false.
Whether or not to destroy the entire session on logout. This option is ignored if LiveUser: $config['liveUser'] is set to false.
Maximum time of idleness in seconds. Idletime gets refreshed each time, LiveUser::init() is called. If this options is set to 0, idle time is never checked. This option is ignored if LiveUser: $config['liveUser'] is set to false.
Number of hours that must pass between two logins to be counted as a new login. If you want the auth container to count each login as new login, you've to set it to 0. It is recommended to set this option to 0. This option is ignored if LiveUser: $config['liveUser'] is set to false.
Auth lifetime or maximum login time in seconds. If you want the user to be automaticly logged out after one hour, you've to set it to 3600. Attention: If you want to use expire, you should set LiveUser: $config['liveUserAuthLoginTimeout'] to 0 ! It is recommended to set this option to 0. This option is ignored if LiveUser: $config['liveUser'] is set to false.
Whether to allow multiple users in the database to have the same login handle. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The encryption mode the password is stored in the container. Possible values are 'plain' and 'md5'. You shouldn't use 'plain' for security reasons. This option is ignored if LiveUser: $config['liveUser'] is set to false.
Whether to refresh a user's rights on every request or not. This is neccessary if you deal with dynamic right creation but slows down everything a bit. If set to true $liveUser->_perm->readRights() is called on every request. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The name of the database table to be used by the authentication container. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The name of the user-ID column in LiveUser: $config['liveUserAuthTable']. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The name of the handle (username) column in LiveUser: $config['liveUserAuthTable']. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The name of the password column in LiveUser: $config['liveUserAuthTable']. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The name of the last-login column in LiveUser: $config['liveUserAuthTable']. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The name of the is-active column in LiveUser: $config['liveUserAuthTable']. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The "name" of the container. LiveUser includes the container found in /LiveUser/Perm/Container/"type".php and creates a new object $_perm. For now available are 'DB_Simple', 'DB_Medium' and 'DB_Complex'. This option is ignored if LiveUser: $config['liveUser'] is set to false.
Prefix for all database tables used by the permission container. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The class name of the auth admin class. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The path to the file that contains LiveUser: $config['liveUserAuthAdminClass']. This is usually something like: 'LiveUser/Admin/Auth/Container/DB.php'. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The class name of the perm admin class. This option is ignored if LiveUser: $config['liveUser'] is set to false.
The path to the file that contains LiveUser: $config['liveUserAuthAdminClass']. This is usually something like: 'LiveUser/Admin/Perm/Container/DB_Complex.php'. This option is ignored if LiveUser: $config['liveUser'] is set to false.
Whether to make an assumption about the /**sequence**/ setting if a primary key was not defined with one. Please see Sequence Guessing for details. This option is ignored if Database Backend: $config['databaseBackend'] is set to false.
Whether to make an assumption about /**isValid**/ setting if a column was not define with one. Please see IsValid Guessing for details. This option is ignored if Database Backend: $config['databaseBackend'] is set to false.
Whether to display the columns defined as primary or foreing key in the templates. With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This option is ignored if Web Application: $config['webApplication'] is set to false.
If the supplied value evaluates to the boolean value true the design model MVC will be implemented. This is done by seperating the Model, the View and the Controller and storing its files in different directories. The template engine SMARTY is used to separate Controller and View. If this option is set to a value that evaluates to true and Web Application: $config['webApplicationSkel'] is set the Web Application Directory Structure is used.
The left delemiter for Smarty-tags generated in the template files. Can be any string. Note that '{{' is recommended.
The right delemiter for Smarty-tags generated in the template files. Can be any string. Note that '}}' is recommended.
The path to the directory where you installed Smarty. Example: /usr/share/php/smarty/ or C:/php/inc/smarty/. Note that this directory must not be in the webroot! Use forward slashes and place one at the end of the path! You do not even have to specify an absolute path - just make sure an require_once statement as the following will not fail:
1 require_once("${SMARTY_DIR}Smarty.class.php");
The path to the skel (skeleton directory) for web applications. Set this option to an empty string if you do not want a web application skel to be used. This would be the case if you are regenerating a project. Note: this option is ignored if Web Application: $config['webApplication'] is set to false. Please see Web Application Directory Structure
If this configuration option is set to true, RSD will try to guess the HTML input type of all columns. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. If this configuration option is set to true, the search and get-controllers will not directly implement the way a record is displayed but will include an other file for this purpose. The included file will be be generated as well if this option is set to true. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
>With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. If this configuration option is set to true, the search and get-controllers will allow the user to sort the listed records by the column she chooses. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. If this configuration option is set to true, the generated templates will include a file called header.tpl and the the controllers will include header.php. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. If this configuration option is set to true, the generated templates will include a file called footer.tpl and the the controllers will include footer.php. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. If this configuration option is set to true, the generated get-controllers will be public (require no authentication). This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. If this configuration option is set to true, the generated getOne-controllers will be public (require no authentication). This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. If this configuration option is set to true, the generated search-controllers will be public (require no authentication). This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. If this configuration option is set to true, the generated delete-controllers will be public (require no authentication). This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. If this configuration option is set to true, the generated update-controllers will be public (require no authentication). This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. If this configuration option is set to true, the generated create-controllers will be public (require no authentication). This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
All configuration options starting with `write' know three possible values:
1 `true' ...create the file in question only if it does not already exist
2 `false' ...do not write the file
3 `overwrite' ...write the file and overwrite an existing file if necessary
This configuration option defines if the paging template file (paging.tpl) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the header files (header.php, header.tpl) should be written. So this option affects a template AND a controller! Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the footer files (footer.php, footer.tpl) should be written. So this option affects a template AND a controller! Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the get-template (get${TABLE_NAME}.tpl) files should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the getOne-template files (getOne${TABLE_NAME}.tpl) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the getRecord-template files should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false. Wheather the generated get-template should try to include a separate file for displaying a record can be defined with Web Application: $config['separateRecordTemplate'] (Default).
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the update-template files (update${TABLE_NAME}.tpl) should be written. This option as well as the per-table setting will affect as well the updateArea, updateGroup and updateRight templates (see {@see RSDEngineDBTemplateFileUpdateGroup}, {@see RSDEngineDBTemplateFileUpdateArea}, {@see RSDEngineDBTemplateFileUpdateRight}). Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the delete-template files (delete${TABLE_NAME}.tpl) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the search-template files (search${TABLE_NAME}.tpl) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the searchRecord-template files should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false. Wheather the generated search-template should try to include a separate file for displaying a record can be defined with Web Application: $config['separateRecordTemplate'] (Default).
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the create-template files (create${TABLE_NAME}.tpl) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the fatal error template (fatalError.tpl) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the permission denied template (permissionDenied.tpl) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the get-controller (get${TABLE_NAME}.tpl) files should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the getOne-controller files (getOne${TABLE_NAME}.tpl) should be written. This option as well as the per-table setting will affect as well the getOneStored-controller (see {@see RSDEngineDBControllerFileGetStored}). Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the update-controller files (update${TABLE_NAME}.tpl) should be written. This option as well as the per-table setting will affect as well the updateArea, updateGroup and updateRight controllers (see {@see RSDEngineDBControllerFileUpdateGroup}, {@see RSDEngineDBControllerFileUpdateArea}, {@see RSDEngineDBControllerFileUpdateRight}). Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the delete-controller files (delete${TABLE_NAME}.tpl) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the search-controller files (search${TABLE_NAME}.tpl) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. This configuration option defines if the create-controller files (create${TABLE_NAME}.tpl) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the smarty base class file should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the smarty child class file should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the application config file should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the application init file should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the public application file should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the private application file should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the index file (index.php) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the logout file (logout.php) should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the application base class file should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
´This configuration option defines if the application child class file should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the table base class files should be written. With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the table child class files should be written. With this option you can define the default. A per-table setting is possible using Table Modifier /**file:OPTIONS**/. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
This configuration option defines if the error manager class class file should be written. Please see General: write options. This configuration option will be ignored if Web Application: $config['webApplication'] is set to false.
Whether to implement a mail sending system. PEAR::Mail is used for this purpose. Please see its documentation for details.
The default sender address to use. This option is ignored if Mail: $config['mail'] is set to false.
The mail sending mechanism to use. Valid values are 'mail', 'sendmail' and 'smtp'. Please see the documentation of PEAR::Mail for details.
If $config['mailType'] is set to 'sendmail' you have to specify the options Mail: $config['mailSendmailPath'] and Mail: $config['mailSendmailArgs'] as well.
If $config['mailType'] is set to 'smtp' you have to specify the options Mail: $config['mailSMTPHost'], Mail: $config['mailSMTPPort'], Mail: $config['mailSMTPAuth'] and evantually Mail: $config['mailSMTPUsername'] and Mail: $config['mailSMTPPassword'] This option is ignored if Mail: $config['mail'] is set to false.
If $config['mailType'] is set to 'mail' the builtin function mail is used and no more options are needed.
The location of the sendmail program on the filesystem. This option is ignored if Mail: $config['mailType'] is not set to 'sendmail'.
Additional parameters to pass to the sendmail program. This option is ignored if Mail: $config['mailType'] is not set to 'sendmail'.
The SMTP server to connect to. This option is ignored if Mail: $config['mailType'] is not set to 'smtp'.
The port to connect to. This option is ignored if Mail: $config['mailType'] is not set to 'smtp'.
Whether or not to use SMTP authentication. This option is ignored if Mail: $config['mailType'] is not set to 'smtp'.
The username to use for SMTP authentication. This option is ignored if Mail: $config['mailSMTPAuth'] is set to false.
The password to use for SMTP authentication. This option is ignored if Mail: $config['mailSMTPAuth'] is set to false.
The RSDEngine follows the coding standards of RSD - Rapid and Secure Development: RSD Coding Conventions. Please see it's documentation for details.
A project will be created using a specific directory structure. Which one depends on the configuration options set. But all directory structures extend the Basic Directory Structure. Note that all occurences of PROJECT_NAME preceeded and followed by %% and PROJECT_DESCRIPTION preceeded and followed by %% in file or directory names will be replaced with General: $config['projectName'] and General: $config['projectDescription']. In all files all occurences of the string PROJECT_NAME preceeded by %% and followed by %% will be replaced with General: $config['projectName'], all occurences of PROJECT_DESCRIPTION preceeded and followed by %% will be replaced with General: $config['projectDescription'] and all occurences of DOCBOOOK_AUTHORS preceeded and followed by %% will be replaced with DocBook XML tags for the authors in General: $config['authors'].
The basic directory structure will be used if you set the configuration option Web Application: $config['webApplication'] to a value that evaluates to false. Where the basic directory structore resides must be specified by General: $config['skel']. The distributed skel looks like this:
ROOT - The project ROOT. Is renamed to ¦ $config['projectName']. +---code - The code of the application. +---design - Application design information.
This directory structure extends the Basic Directory Structure. The project will be created using the web application directory structure if you set Web Application: $config['webApplication'] to a value that evaluates to true. Where the web application directory structore resides must be specified by Web Application: $config['webApplicationSkel']. The distributed web application directory structure looks like this:
ROOT +---code +---model - Application/business logic ¦ should be implemented here. +---view - The presentation logic resides here. +---cache - Used by SMARTY to do some caching. +---configs - SMARTY configuration files ¦ can be stored here. +---templates - Put your SMARTY templates ¦ here. +---templates_c - This is where SMARTY stores the compiled templates.
These files are only generated if Database Backend: $config['databaseBackend'] is set to true.
For each table defined in Database Backend: $config['sql'] a base class is generated. Do not change the base class because these changes will get lost when regenerating your project! Each class is stored in a separate file named like the class itself (with .php appended). All Table Base Classes extend the class RSDTable. Please see its documentation for details. The Table Base Classes are generated by the classes RSDEngineDB and RSDEngineDBTable.
The name of a Table Base Class is generated like this:
If Web Application: $config['webApplication'] is set to true it is stored in ROOT/code/model. If it's not, it is stored directly in the ROOT/code.
1 ucfirst($projectName) . ucfirst($tableNameWithoutPrefix) . 'Base'
The following methods are created for all columns:
The following methods are created for all columns defined as a PRIMARY KEY, FOREIGN KEY or "undefined" key using /**key**/:
The following methos are created for all columns defined with /**sequence:sequence_name**/:
The following methos are created for all columns defined with /**isValid:file**/:
The following methods are as well generated:
The class has the following public properties:
For more information just create a documentation of your project and have a look at your Table Base Classes.
For each table a Table Child Class is generated. This file is only generated if it does not already exit - so this is where you can do your implementation. Do not change the base class because these changes will get lost when regenerating your project! Each class is stored in a separate file named like the class itself (with .php appended). A Table Child Class extends the The Table Base Classes. A Table Child Class is generated by the classes RSDEngineDB and RSDEngineDBTable.
Its name is generated like this:
If Web Application: $config['webApplication'] is set to true it is stored in ROOT/code/model. If it's not, it is stored directly in the ROOT/code.
1 ucfirst($projectName) . ucfirst($tableNameWithoutPrefix)
This is where you can implement additional logic for this table. The file that contains this class is NOT overwritten when regenerating your porject. The child classes as they are generated do nothing but to inherit from the corresponding The Table Base Classes and to call the parent constructor inside its own constructor.
If LiveUser: $config['liveUser'] is set to false it extends the class RSDApplication. If LiveUser: $config['liveUser'] is set to true it extends RSDLiveUserApplication which extends RSDApplication. So you will be always - directly or not - inheriting from RSDApplication. This class is generated by the class RSDEngineDBApplicationBaseClass. Do not change the base class because these changes will get lost when regenerating your project!
The name of the class (and the file, just with '.php' appended) is generated like this:
If Web Application: $config['webApplication'] is set to true it is stored in ROOT/code/model. If it's not, it is stored directly in the ROOT/code.
1 ucfirst($config['projectName']) . 'Base'
The Application Class holds handles to all objects created:
For more information just create a documentation of your project and have a look at your Application Base Class.
It extends the class The Application Base Class. This class is generated by the class RSDEngineDBApplicationClass. This file is only generated if it does not already exit - so this is where you can do your implementation. Do not change the base class because these changes will get lost when regenerating your project!
The name of the class (and the file, just with '.php' appended) is generated like this:
If Web Application: $config['webApplication'] is set to true it is stored in ROOT/code/model. If it's not, it is stored directly in the ROOT/code.
1 ucfirst($config['projectName'])
For more information just create a documentation of your project and have a look at your Application Child Class.
It contains declarations of constants for your application. This file is generated by the class RSDEngineDBApplicationConfigFile. Do not change this file because these changes will get lost when regenerating your project! The Application Config File contains only constants configurable through the web interface of RSD. If you need additional constants use Database Backend: $config['additionalConfig']! If this is for whatever reason not possible create a new file and include it in the The Application Init File.
The name of the Application Config File is generated like this:
If Web Application: $config['webApplication'] is set to true it is stored in ROOT/code/model. If it's not, it is stored directly in the ROOT/code.
1 strtolower($this->config['projectName']) . "Config.php"
For more information just create a documentation of your project and have a look at your Application Config File.
This file is primary for demonstration purpose. This file is generated by the class RSDEngineDBApplicationIndexFile. It will only be generated if it does not already exist.
The name of the file is index.php. It is stored in ROOT/code
For more information just create a documentation of your project and have a look at your index.php.
Requesting logout.php with a browser logs you out (and depending on the configuration destroys your session). This file is generated by the class RSDEngineDBApplicationLogoutFile. It will only be generated if it does not already exist.
The name of this file is logout.php. It is stored in ROOT/code
For more information just create a documentation of your project and have a look at your logout.php.
This file creates instances of the The Application Child Class and initializes it. This file is generated by the class RSDEngineDBApplicationInitFile. It will only be generated if it does not already exist.
The name of the init file is generated like this:
If Web Application: $config['webApplication'] is set to true it is stored in ROOT/code/model. If it's not, it is stored directly in the ROOT/code.
1 strtolower($this->config['projectName']). "Init.php"
For more information just create a documentation of your project and have a look at your Application Init File.
The generated file includes The Application Init File. It does not force authentication. Therefore including this file in a controller makes the controller 'public' - no authentication is needed to access it. This file is generated by the class RSDEngineDBApplicationPublicInitFile. It will only be generated if it does not already exist.
The name of the Public Application Init File is generated like this:
If Web Application: $config['webApplication'] is set to true it is stored in ROOT/code/model. If it's not, it is stored directly in the ROOT/code.
1 strtolower($this->config['projectName']) . "Init_public.php"
For more information just create a documentation of your project and have a look at your Public Application Init File.
The generated file includes The Application Init File. It does force authentication. Therefore including this file in a controller makes the controller 'private' - authentication is required to access it. This file is generated by the class RSDEngineDBApplicationPrivateInitFile. It will only be generated if it does not already exist.
The name of the Private Application Init File is generated like this:
If Web Application: $config['webApplication'] is set to true it is stored in ROOT/code/model. If it's not, it is stored directly in the ROOT/code.
1 strtolower($this->config['projectName']) . "Init_private.php"
For more information just create a documentation of your project and have a look at your Private Application Init File.
The generated class extends RSErrorManager. Most important it overwrites the methods 'onFatalError' and 'onPermissionDenied'. If Web Application: $config['webApplication'] is set to true these methods use the templates fatalError.tpl and permissionDenied.tpl to display the error information. This file is generated by the class RSDEngineErrorManagerClass. It will only be generated if it does not already exist.
The name of the Error Manager Class (and the name of the file, just with '.php' appended) is generated like this:
If Web Application: $config['webApplication'] is set to true it is stored in ROOT/code/model. If it's not, it is stored directly in the ROOT/code.
1 ucfirst($this->config['projectName']) . 'ErrorManager'
These files are only generated if Web Application: $config['webApplication'] is set to true.
This class extends Smarty.
The name of the Smarty Class (and the name of the file, just with '.php' appended) is generated like this:
It is stored in ROOT/code/model.
1 ucfirst($this->config['projectName']) . 'Smarty'
For more information just create a documentation of your project and have a look at your Smarty Class file.
For all tables the following controller files are created:
1 "create" . ucfirst($this->config['table']->getTableNameWithoutPrefix()) . ".php"
1 "delete" . ucfirst($this->config['table']->getTableNameWithoutPrefix()) . ".php"
1 "update" . ucfirst($this->config['table']->getTableNameWithoutPrefix()) . ".php"
1 "get" . ucfirst($this->config['table']->getTableNameWithoutPrefix()) . ".php"
1 "getOne" . ucfirst($this->config['table']->getTableNameWithoutPrefix()) . ".php"
1 "getStored" . ucfirst($this->config['table']->getTableNameWithoutPrefix()) . ucfirst($this->config['column']->getColumnNameForVariableName()) . ".php"
The controllers are stored in ROOT/code.
For more information just have a look at your generated controllers.
For all tables the following template files are created:
1 "create" . ucfirst($this->config['table']->getTableNameWithoutPrefix()) . ".tpl"
1 "delete" . ucfirst($this->config['table']->getTableNameWithoutPrefix()) . ".tpl"
1 "update" . ucfirst($this->config['table']->getTableNameWithoutPrefix()) . ".tpl"
1 "get" . ucfirst($this->config['table']->getTableNameWithoutPrefix()) . ".tpl"
1 "getOne" . ucfirst($this->config['table']->getTableNameWithoutPrefix()) . ".tpl"
The templates are stored in ROOT/code/view/templates.
For more information just have a look at the your generated templates.
The RSDEngine does a lot of work for you - but not all of it. This section tries to help the programmer with his task.
Just modify one of the The Table Child Classes. Overwrite existing methods or add new ones - as you wish. The Table Child Class files are only generated if they do not already exit - so this is where you can do your implementation.
New Template: create a new file with the extention .tpl and save it in ROOT/code/view/templates/. For how to work with Smarty please see http://smarty.php.net. You best start by coping parts of an other template.
New Controller: create a new PHP file in ROOT/code. You best start by coping parts of an other controller.
This should actually be done by the HTML-guy. Once the basic presentation logic is generated, building HTML around it is pretty easy. If you need to change the presentation logic, it would be very efficient if the HTML-guy learns how to use the SMARTY tags. Again, please see http://smarty.php.net.
Previous | Next | |
UnitTests | RSDTable |
Documentation generated on Mon, 8 Dec 2003 13:10:23 +0100 by phpDocumentor 1.2.3