midcom_helper_datamanagerThe main purpose of the Datamanager is to store arbitary data in an arbitary Midgard object.
The process of data storage and retrieval is completely automated and controlled by the layout definition used for the object in question.
It also provides a full form builder infrastructure which completely automates both form handling and data output generation.
Layout database definition:
The following schema description uses a more-or-less BNF compatible syntax to describe the structure of the layout schema Array.
A layout database is a collection of layout definitions. The first layout will be used as a default if the object in question has no layout specified. This is the data structure that gets loaded by the Data Manager upon object creation. The key for this array is used for indexing
<layout database> :== Array (
<layout line>
[ , <layout line> ... ]
);
<layout line> ::= <layout name> => <layout definition>,
<layout name> ::= <string>
<string> ::= Any PHP StringEach layout again consists of a descriptive string and the list of data fields indexed by their name.
<layout defintion> ::= Array (
"description" => <string>
[, "locktimeout" => <integer> ]
[, "lockoverride" => "all" | "poweruser" | "admin" ]
[, "l10n_db" => <string> ]
[, "save_text" => <string> ]
[, "cancel_text" => <string> ]
, "fields" => <field list>
)
<field list> ::= Array ( <field name> => <field definition>
[ , <field name> => <field definition> ... ] )
<field name> ::= [a-zA-Z0-9]*The locktimeout directive will override the global article lock timeout of 60 minutes and sets it to the specified amount in minutes. The lockoverride in turn will specify who will be able to override an existing lock; all means all users, powerusers includes only powerusers and admins, while admin will restrict it to sg admins only. If you set the lock timeout to 0, you will disable the locking system.
The field definition is the core of the magic. Here you define the behaviour of each field you want to store. "name" is used as an array index for the data retrieval array, "description" is used in the generator logic as field name. The datatype specifies the name of the object that manages the data. Optional fields include the name of the widget used in the data/form generation logic. The optional field "location" specifies an explicit requirement where to save the field. The data manager is currently unable to verify this so make sure that the destination you specify here can take the data of the datatype you want to store. See the docs of the individual datatypes for further reference.
The object names given for datatype will be prefixed with "midcom_helper_ datamanager_datatype_", while the widget object names use "midcom_helper_ datamanager_widget_" as prefix. If you want custom datatypes or widgets not given by Midcom, prefix them with "custom_", i.e. "midcom_helper_datamanager_ datatype_custom_mydatatype".
If the value l10n_db is set, it overrides the default l10n database, possible values are all valid component names, as the default component l10n DB is always used (see below for details). Due to the current schema specification, it is neccessary to specify this on a per-schema level. Per-schema-db configuration is not supported at this time.
The save_text and cancel_text values will be used as labels for the save and cancel buttons in the datamanger. They are translated using the rules outlined above.
<field definition> :== Array (
"description" => <string>,
"datatype" => <object identifier>
[ , "widget" => <object identifier> ]
[ , "location" => <storage name> ]
[ , "hidden" => <boolean> ]
[ , "aisonly" => <boolean> ]
[ , "readonly" => <boolean> ]
[ , "default" => <field value> ]
[ , "required" => <boolean> ]
[ , "start_fieldgroup" => <fieldgroup definition> ]
[ , "end_fieldgroup" => "" ]
[ , "config_domain" => <string> ]
[ , "config_key" => <string> ]
[ , "helptext" => <string> ]
[ , <option name> => <option value> ... ]
[ , "validation" => <fieldgroup definition> ]
)
<object identifier> ::= Any valid PHP class name in the namespace of the
Datamanger. (See above-)
<storage name> ::= 'parameter' | 'config' | 'attachment'
| <storage object member name>
<storage object field name> ::= Any valid member of the storage object.
<option name> ::= <string>
<option value> ::= Any valid PHP Datatype
<field value> ::= A value compatible to the datatype's value type
<boolean> ::= true|false
<fieldgroup definition> ::= Array (
"title" => <string>
[ , "css_group" => <string> ]
[ , "css_title" => <string> ]
)Note, that widget and location all have their defaults corresponding to the datatype you use. Also note, that some datatypes (for example the blob datatypes) do not allow you a choice of where to store your data.
Note also, that the Datamanger adds another entry into this array internally:
"name" => <string>
This is essentially the name of the field, which would not be available if you only have the field definition available, as for example the Datatypes or Widgets do.
The special fields hidden and readonly affect the bevahoir of the form and view generators. Hidden fields are ignored completly, nothing will be displayed either in view- or in form-mode. Readonly fields are displayed in both views, but instead of drawing the widget in form-mode, the datamanger draws the regular view there. Both fields default to FALSE.
The field aisonly is a special version of hidden, hiding the respective field only in display_(view|form) calls outside of the AIS content admin. This too defaults to FALSE.
The default field is an indication what value should be used, if the field in question is empty. It will automatically be automatically inserted by all datatypes supporting default values upon extracting the fields from the database.
Setting the required flag on a field enforces an is_empty check before allowing the user to save the object in question. The is_empty method is implemented on a per-datatype basis, so you might want to check the specific datatypes in what extent and with what meaning this operation is supported there.
If the start_fieldgroup array is definied, it will start a new optical field group before the currently defined field. The grouping is done through <div> tags. The Title is printed, again enclosed by a <div> at the top of the group. The optional css tags will be assigned to the opening div tags if present. Each opened field group has to be closed using an end_fieldgroup tag which will close the corresponding div tag. Note, that the schema writer has to ensure that the fieldgroups are correctly paired, there is no checking algorithm whatsoever which ensures the validity of the HTML to-be-generated. It is possible, to have both a start and an end fieldgroup tag within the same field, which will yield a group enclosing a single field. Note, that the hidden tag has precedence over the grouping algorithm. A field which is invisible will not start or end a field group.
The two options "config_domain" and "config_key" are both required for the config storage method, which is in essence a way of setting any arbitary parameter, where config_domain is the parameter domain in question, and config_key the parameter name. Apart from the extended configuration scheme, this mode is otherwise identical to the storage method "parameter".
The helptext parameter is there to allow for custom notes to the field. Currently, the content of this field will be added as a tooltip to the field in question. No HTML code is allowed in there yet.
Validation support:
The PEAR package HTML_Quickform must be installed to support validation.
Validation is a new feature in MidCom 1.4.0. The implementation is based on the Pear package HTML_Quickform so this must be installed for the validationcode to work. If HTML_Quickform is not installed the field will just not be validated - MidCom will just save it.
A larger manual on HTML_Quickform is found here: http://pear.php.net/manual/en/package.html.html-quickform.intro-validation.php
To add validation to a field, you add a validation keyword to the schema like this:
"validation" => array (
'<type>' => array (
'message' => 'Some message to the user' ,
['format' => 'string' , ]
['function' => 'functionname'
[ 'object' => 'classname',] ]
)
)As you see, the variables follow HTML_Quickform quite closely.
You may also write your own validationfunctions by setting the function parameter. If you function is part of a class you also have to set the class-parameter.
Localizaion support:
The description and helptext of each field and all fieldgroup titles are automatically localized using the l10db of either the current component or the component referenced by the l10n_db schema configuration key.
If the string in question does not exist in either the current or the default language, it will fall back to the midcom core l10n db searching there.
For backwards compatibility with the existing l10n databases and schemas, all name strings are converted to lower-case before being looked-up in the l10n databases.
Automatic Cache invalidation:
The Datamanager will automatically invalidate the cache during editing of an existing object. When in creation mode, it will invalidate the currently active node as well (for the current context of course). Of course, if you don't use the creation mode, you have to invalidate the right topic yourself.
Object destruction:
Due to the complex nature of the Datamanger's object hierarchy, PHP cannot reliably garbage collect Datamanager instances (it fails to resolve the cyclic references between the datamanager class, its datatypes and the widgets). Therefore you have to call the destroy method every time you do no longer need a datamanger instance. Only then you can safely let a datamanager reference out of scope. It will destroy all datatypes and widgets and clears all internal references.
This is especially important in long running requests like reindexing or bulk uploads.
Copyright references:
HTMLAREA, copyright (c) 2002-2004, interactivetools.com, inc. HTMLAREA is available under a BSD-derived license. More information at http://www.interactivetools.com/products/htmlarea/license.html
The DHTML Calendar, version 0.9.6 "Keep cool but don't freeze" Copyright Mihai Bazon, 2002, 2003 | http://dynarch.com/mishoo/
Details and latest version at: http://dynarch.com/mishoo/calendar.epl
This script is distributed under the GNU Lesser General Public License. Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
Located in /midcom/helper/datamanager/datamanager.php (line 271)
| Class | Description |
|---|---|
midcom_helper_datamanager_getvar
|
The main purpose of the Datamanager is to store arbitary data in an arbitary Midgard object. |
bool
init_creation_mode
(string $schema, object &$object, [string $callback = "_dm_create_callback"])
Array
$data
(line 434)
This array always holds a current snapshot of the data. Changes to this array are not propagated into the object.
Besides the values of all fields, the following keys are added to the array as well:
string
$errstr
(line 459)
The error string of the last call executed by the datamanager. The content of this string is automatically appended to the content manager's processing message and therefore needs only to be printed while in a non-AIS environment.
Note, that this string is HTML-capable, it should be enclosed in a <div> or <p> upon printing, as those tags are not allowed in here.
string
$form_prefix
(line 441)
Form field name prefix
string
$url_me
(line 466)
URL prefix to the form
string
$url_prefix
(line 448)
Form URL prefix
bool
$_creation
(line 365)
Creation mode flag
string
$_creation_code_objmethod
(line 349)
Creation mode callback method name
object
$_creation_code_objref
(line 341)
Creation mode callback object reference
string
$_creation_schema
(line 357)
Creation mode schema name
Array
$_datatypes
(line 323)
The collection of datatypes corresponding to the fields out of the schema file.
Array
$_fields
(line 314)
The list of fields currently in use, this is a reference into $_layoutdb.
midcom_services__i18n_l10n
$_l10n
(line 474)
Datamanager L10n Database
midcom_services__i18n_l10n
$_l10n_midcom
(line 482)
MidCOM L10n Database
midcom_services__i18n_l10n
$_l10n_schema
= null (line 490)
The primary L10n DB to use for schema translation.
Array
$_layout
(line 298)
The layout currently in use, this is a reference into $_layoutdb.
Array
$_layoutdb
(line 290)
This is the complete Layout database with which the system has been initialized.
string
$_layoutname
(line 306)
The index name of the layout currently in use.
Array
$_lock
(line 401)
This one will contain the lock data if the current storage object is locked.
It is set either by a previous call of check_log or by set_log. It is null if it is undefined, false if there is no lock or an array containing the lock of another user otherwise.
Array
$_missing_required_fields
(line 374)
A simple collection of field names from the required fields check. It is used for switching required fields to a seperate css class.
bool
$_ourlock
(line 410)
$_ourlock will be true if and only if we are the owner of the current lock; this variable is only valid if $_lock is an array.
int
$_processing_result
(line 333)
This one holds the status of the process_form run. It is neccessary to avoid multiple invocations of this method, like it is sometimes done by not ideally designed components. It is null if process_form wasn't called yet.
???
$_rule_registry
(line 419)
Pointer to a RuleRegistry singeltonobject.
MidgardObject
$_storage
(line 281)
This MidgardObject is used for storing and retrieving the data. Any object that is derived from them can also be used. Note that this member is populated with a reference!
string
$_url_help_icon
(line 382)
The URL of the help icon. This URL is complete, no prefixes need to be added.
string
$_url_lock_icon
(line 390)
The URL of the lock icon. This URL is complete, no prefixes need to be added.
The constructor loads the layout database, verifies its structure and initializes the complete class for usage. No object gets loaded at this point.
The path to the schema database can be anything accepted by midcom_get_snippet_content().
This member will append the given string both to the internal error string and, if available, to the current content manager's processing message string.
Note, that this function is public, but should only be called by widgets and datatypes.
Call this function if you no longer need the DM instance. It will drop all instantinated classes and resolve the cyclic references which prevent a DM instance to be garbage collected by PHP.
Here is the root of the all-mighty form generator. Calling this function will
result in a complete editing form to be put out to the client. Remebmer to call the process_form function before any of this form operations, even upon displaying the form the first time. This view can be customized by CSS commands.
The form's action will point to the same URL as the current page, including all HTTP GET parameters
This function will display the current data of the object in an non-editable way. It will not display edit/delete Links for the object. This view can be customized by CSS commands, see below.
This command will not work in creation mode.
This is a small version of the display_view method above for use outside of
the datamanager. It calls the draw_view method of the corresponding widget which essentially renders the data in the datamangers default view representation. It does not display an headings or the like, so it can be easily used to created custom database applications without having to reimplement the view logic for each datatype again and again.
get_csv_header_line will yield a line containing all the field descriptions to be used as column headers.
get_csv_line function will transform the data array into a CSV compatible form.
The actual CSV representation of the data is determined by the individual datatypes. Data will be separated by the given separator and ends with the given newline characters. The internal helper _csv_encode is used to encode the actual data from the components.
Return the name of the currently active schema.
This method is responsible for the initialization of the datamanager to a given object.
The datamanager loads the object and initializes all local fields accordingly. All datatypes get instantinated and the data array gets populated. If the object has no schema accociated with it, it defaults to the first layout in the database.
Initializes the datamanager for object creation.
In the creation mode, special rules apply. First, there must be a callback from the application itself, that is executed when the dm need to create the true storage object (after the user first clicks save, that is). The function must return an array: The parameter "strorage" is mandatory and holds a reference(!) to the storage object to be used. Note, that this object is passed by reference to the complete datamanager system, so that all changes propagate accordingly. The parameter "success" is optional, setting it to false tells the datamanager to stay in the edit loop rather then complete it. Note, that this function must create an empty object without any references to schema names and so on.
The callback function receives only one parameter, which is a reference (!!) to the datamanager object itself.
Note, that the callback should absolutly try to create an empty record somehow, telling success=false on all minor errors along with an appropriate error message through the append_error method of the datamanager. If no storage object can be created, NULL should be returned instead with an appropriate error message through append_error. Know, that it is not possible, to retain the user's input in the form in that case!
The datamanager internally keeps track of the schema to be used for the new record. The parameter $schema therefor is only relevant on the first call of the function. Its value is tracked through a hidden variable within the input form to save the application from keeping track of this variable over the requests.
This method does all processing related to datamanager-generated forms. You must call this method during your handle phase and act according to the constant returned:
It will also call the _update_nemein_rcs helper to utilize its RCS mechanism if available on any successful storage to the storage object.
Reindexes all blobs (or subtypes thereof) set to autoindex mode.
The calls are relayed to the blob method autoreindex.
Schema translation helper, usable by components from the outside.
The l10n db from the schema is used first, the MidCOM core l10n db second. If the string is not found in both databases, the string is returned unchanged.
Note, that the string is translated to lower case before translation, as this is the usual form how strings are in the l10n database. (This is for backwards compatibility mainly.)
This function will check if the current object does have a still valid lock which prevents us from editing. It returns true, if the storage object is locked for us, false otherwise.
This will clear any existing lock on the storage object. Note, that it will check the permissions of the user and the lock. Returns true if the lock was successfully cleared.
Encodes the given string into CSV according to these rules: Any appearance of the separator or one of the two newline characters \n and \r will trigger quoting. In quoting mode, the entire string will be enclosed in double-quotes.
Any occurence of a double quote in the original string wille be transformed into two double quotes. Any leading or trailing whitespace around the data will be eliminated.
This funtion extracts the Layout Database from the snippet referenced by
$path. The snippet must only contain the layout definitions without the surrounding array definition, this corresponds to this part of the schema definition:
[ , ... ]
This helper function will load the schema database identified by $source, which can either be a path to a snippet/file or an already loaded database array.
This method populates the Array $data with the current field information.
This tries to set a lock at the current storage object. If it returns false, this failed due to an existing lock.
This helper translates a field of the schema. Strings are translated in-place.
This is the common initialization work shared between the existing-object and the new-object ("creation mode") init procedure.
It will translate all descriptions and helptexts automatically.
Note, that the string is translated to lower case before translation, as this is the usual form how strings are in the l10n database. (This is for backwards compatibility mainly.)
Calls midcom_update_nemein_rcs to update the Nemein RCS store if configured.
Documentation generated on Mon, 21 Nov 2005 18:13:48 +0100 by phpDocumentor 1.3.0RC3