Documentation is available at datamanager.php
- <?php
- /**
- * @package midcom.helper.datamanager
- * @author The Midgard Project, http://www.midgard-project.org
- * @version $Id: datamanager.php,v 1.23.2.4 2005/11/04 09:05:15 bergius Exp $
- * @copyright The Midgard Project, http://www.midgard-project.org
- * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
- */
- /**
- * The 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.
- *
- * <b>Layout database definition:</b>
- *
- * 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
- *
- * <pre>
- * <layout database> :== Array (
- * <layout line>
- * [ , <layout line> ... ]
- * );
- * <layout line> ::= <layout name> => <layout definition>,
- * <layout name> ::= <string>
- * <string> ::= Any PHP String
- * </pre>
- *
- * Each layout again consists of a descriptive string and the list of data
- * fields indexed by their name.
- *
- * <pre>
- * <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]*
- * </pre>
- *
- * 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.
- *
- * <pre>
- * <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> ]
- * )
- * </pre>
- *
- * 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:
- *
- * <pre>
- * "name" => <string>
- * </pre>
- *
- * 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.
- *
- * <b>Validation support:</b>
- *
- * 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:
- *
- * <pre>
- * "validation" => array (
- * '<type>' => array (
- * 'message' => 'Some message to the user' ,
- * ['format' => 'string' , ]
- * ['function' => 'functionname'
- * [ 'object' => 'classname',] ]
- * )
- * )
- * </pre>
- *
- * 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.
- *
- * <b>Localizaion support:</b>
- *
- * 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.
- *
- * <b>Automatic Cache invalidation:</b>
- *
- * 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.
- *
- * <b>Object destruction:</b>
- *
- * 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.
- *
- *
- * <b>Copyright references:</b>
- *
- * 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
- *
- * @package midcom.helper.datamanager
- */
- class midcom_helper_datamanager {
- /**
- * 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!
- *
- * @var MidgardObject
- * @access private
- */
- var $_storage;
- /**
- * This is the complete Layout database with which the system has been
- * initialized.
- *
- * @var Array
- * @access private
- */
- var $_layoutdb;
- /**
- * The layout currently in use, this is a reference into $_layoutdb.
- *
- * @var Array
- * @access private
- */
- var $_layout;
- /**
- * The index name of the layout currently in use.
- *
- * @var string
- * @access private
- */
- var $_layoutname;
- /**
- * The list of fields currently in use, this is a reference into $_layoutdb.
- *
- * @var Array
- * @access private
- */
- var $_fields;
- /**
- * The collection of datatypes corresponding to the fields out of the schema
- * file.
- *
- * @var Array
- * @access private
- */
- var $_datatypes;
- /**
- * 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.
- *
- * @var int
- * @access private
- */
- var $_processing_result;
- /**
- * Creation mode callback object reference
- *
- * @var object
- * @access private
- */
- var $_creation_code_objref;
- /**
- * Creation mode callback method name
- *
- * @var string
- * @access private
- */
- var $_creation_code_objmethod;
- /**
- * Creation mode schema name
- *
- * @var string
- * @access private
- */
- var $_creation_schema;
- /**
- * Creation mode flag
- *
- * @var bool
- * @access private
- */
- var $_creation;
- /**
- * A simple collection of field names from the required fields check. It is used
- * for switching required fields to a seperate css class.
- *
- * @var Array
- * @access private
- */
- var $_missing_required_fields;
- /**
- * The URL of the help icon. This URL is complete, no prefixes need to be added.
- *
- * @var string
- * @access private
- */
- var $_url_help_icon;
- /**
- * The URL of the lock icon. This URL is complete, no prefixes need to be added.
- *
- * @var string
- * @access private
- */
- var $_url_lock_icon;
- /**
- * 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.
- *
- * @var Array
- * @access private
- */
- var $_lock;
- /**
- * $_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.
- *
- * @var bool
- * @access private
- */
- var $_ourlock;
- /**
- * Pointer to a RuleRegistry singeltonobject.
- *
- * @var ???
- * @todo tarjei: Complete documentation
- * @access private
- */
- var $_rule_registry;
- /**
- * 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:
- *
- * - _schema contains the name of the data schema in use.
- * - _storage_type contains the name of the table in which we are stored (WARNING, this value will be deprecated
- * during the DBA updates)
- * - _storage_id and _storage_guid hold the ID and GUID respecitvly of the storage object.
- *
- * @var Array
- */
- var $data;
- /**
- * Form field name prefix
- *
- * @var string
- */
- var $form_prefix;
- /**
- * Form URL prefix
- *
- * @var string
- */
- var $url_prefix;
- /**
- * 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.
- *
- * @var string
- */
- var $errstr;
- /**
- * URL prefix to the form
- *
- * @var string
- */
- var $url_me;
- /**
- * Datamanager L10n Database
- *
- * @access private
- * @var midcom_services__i18n_l10n
- */
- var $_l10n;
- /**
- * MidCOM L10n Database
- *
- * @access private
- * @var midcom_services__i18n_l10n
- */
- var $_l10n_midcom;
- /**
- * The primary L10n DB to use for schema translation.
- *
- * @var midcom_services__i18n_l10n
- * @access private
- */
- var $_l10n_schema = null;
- /* *************************** */
- /* ** Object Initialization ** */
- /**
- * 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().
- *
- * @param mixed $layoutdb Either a string with the URL to a layoutDB or an Array containing the DB.
- * @see midcom_get_snippet_content()
- */
- function midcom_helper_datamanager ($layoutdb = null)
- {
- global $midcom;
- global $midcom_errstr;
- debug_push_class(__CLASS__, __FUNCTION__);
- if (is_null($layoutdb))
- {
- $this = false;
- $midcom_errstr = "Default Constructor not allowed";
- debug_add($midcom_errstr);
- debug_pop();
- return false;
- }
- $midgard = $midcom->get_midgard();
- $this->form_prefix = "midcom_helper_datamanager_";
- $this->url_prefix = $midcom->get_context_data(MIDCOM_CONTEXT_ANCHORPREFIX);
- $this->url_me = $midgard->uri;
- if (array_key_exists('QUERY_STRING',$_SERVER)
- && strlen(trim($_SERVER['QUERY_STRING'])) > 0 )
- {
- // We have HTTP GET parameters present, save them through the request.
- $this->url_me .= '?' . $_SERVER['QUERY_STRING'];
- }
- $this->_storage = null;
- $this->_layoutdb = null;
- $this->_layout = null;
- $this->_layoutname = "";
- $this->_fields = null;
- $this->_datatypes = null;
- $this->_processing_result = null;
- $this->_creation_code_objref = null;
- $this->_creation_code_objmethod = null;
- $this->_creation_schema = null;
- $this->_creation = false;
- $this->_missing_required_fields = Array();
- $this->errstr = "";
- $this->data = null;
- $this->_url_help_icon = MIDCOM_STATIC_URL . '/stock-icons/16x16/stock_help-agent.png';
- $this->_url_lock_icon = MIDCOM_STATIC_URL . '/stock-icons/24x24/lock.png';
- $this->_lock = null;
- $this->_ourlock = null;
- $i18n =& $GLOBALS["midcom"]->get_service("i18n");
- $this->_l10n = $i18n->get_l10n("midcom.helper.datamanager");
- $this->_l10n_midcom = $i18n->get_l10n("midcom");
- $this->_load_schema_database($layoutdb);
- debug_pop ();
- }
- /**
- * 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.
- *
- * @param string $schema The schema name which should be used for creation of the new object.
- * @param object $object The callback object containing the creation code.
- * @param string $callback The method name that should be used to create the new object.
- * @return bool Indicating success
- */
- function init_creation_mode ($schema, &$object, $callback = "_dm_create_callback") {
- $this->_creation_code_objref =& $object;
- $this->_creation_code_objmethod = $callback;
- if (array_key_exists("midcom_helper_datamanager_creation_schema", $_REQUEST))
- $this->_creation_schema = $_REQUEST["midcom_helper_datamanager_creation_schema"];
- else
- $this->_creation_schema = $schema;
- $this->_creation = true;
- $this->_storage = null;
- return $this->_true_init(null);
- }
- /**
- * 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.
- *
- * @param MidgardObject $storage The storage object to which the DM should be linked to.
- * @param string $schema Do not autodetect the schema but use the one given here.
- * This is useful if you want to edit the same object with more then one schema.
- * Can be omitted.
- * @return bool True on success, false on failure, errors go to the debug log.
- */
- function init (&$storage, $schema = null) {
- $this->_storage =& $storage;
- return $this->_true_init($schema);
- }
- /**
- * 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 <i>lower case</i> before
- * translation, as this is the usual form how strings are in the
- * l10n database. (This is for backwards compatibility mainly.)
- *
- * @param string $schema Do not autodetect the schema but use the one given here.
- * This is useful if you want to edit the same object with more then one schema.
- * @return bool Indicating success
- * @access private
- */
- function _true_init ($schema) {
- debug_push_class(__CLASS__, __FUNCTION__);
- $this->errstr = "";
- if ( ! is_object($this->_storage)
- && ! $this->_creation
- )
- {
- debug_add ("No object given!", MIDCOM_LOG_ERROR);
- debug_pop ();
- return false;
- }
- // get the layout of article, use the first defined layout if
- // none specified
- if ($this->_creation)
- {
- $this->_layoutname = $this->_creation_schema;
- }
- else if (is_null($schema))
- {
- $this->_layoutname = $this->_storage->parameter ("midcom.helper.datamanager", "layout");
- if (! $this->_layoutname)
- {
- $layouts = array_keys ($this->_layoutdb);
- $this->_layoutname = $layouts[0];
- debug_add ("Object has no schema, trying to use default: {$this->_layoutname}", MIDCOM_LOG_INFO);
- }
- }
- else
- {
- $this->_layoutname = $schema;
- }
- debug_add("Got Layout $this->_layoutname. Validating it...");
- if (array_key_exists($this->_layoutname, $this->_layoutdb))
- {
- debug_add("Layout $this->_layoutname found.");
- $this->_layout =& $this->_layoutdb[$this->_layoutname];
- $this->_fields =& $this->_layout["fields"];
- }
- else
- {
- $GLOBALS["midcom_errstr"] = "Layout does not exist!";
- debug_add ($GLOBALS["midcom_errstr"], <a href="../undocumented/_lib_constants_php.html#defineMIDCOM_LOG_ERROR">MIDCOM_LOG_ERROR</a>);
- debug_pop ();
- return false;
- }
- if (array_key_exists('l10n_db', $this->_layout))
- {
- $comp = $this->_layout['l10n_db'];
- }
- else
- {
- $comp = $GLOBALS['midcom']->get_context_data(<a href="../undocumented/_lib_constants_php.html#defineMIDCOM_CONTEXT_COMPONENT">MIDCOM_CONTEXT_COMPONENT</a>);
- }
- debug_add("We have to translate the schema using the database {$comp}.");
- $i18n =& $GLOBALS['midcom']->get_service('i18n');
- $this->_l10n_schema = $i18n->get_l10n($comp);
- $this->_translate_schema_field($this->_layout['description']);
- // Complete Field Defaults
- if (! array_key_exists("locktimeout", $this->_layout))
- {
- $this->_layout["locktimeout"] = 60;
- }
- if (! array_key_exists("lockoverride", $this->_layout))
- {
- $this->_layout["lockoverride"] = "poweruser";
- }
- if (! array_key_exists('save_text', $this->_layout))
- {
- $this->_layout['save_text'] = 'save';
- }
- if (! array_key_exists('cancel_text', $this->_layout))
- {
- $this->_layout['cancel_text'] = 'cancel';
- }
- $this->_translate_schema_field($this->_layout['save_text']);
- $this->_translate_schema_field($this->_layout['cancel_text']);
- foreach ($this->_fields as $name => $field)
- {
- $this->_fields[$name]["name"] = $name;
- if (!array_key_exists("helptext",$field))
- {
- $this->_fields[$name]["helptext"] = "";
- }
- if (!array_key_exists("hidden",$field))
- {
- $this->_fields[$name]["hidden"] = false;
- }
- if (!array_key_exists("readonly",$field))
- {
- $this->_fields[$name]["readonly"] = false;
- }
- if (!array_key_exists("required",$field))
- {
- $this->_fields[$name]["required"] = false;
- }
- if (!array_key_exists("aisonly",$field))
- {
- $this->_fields[$name]["aisonly"] = false;
- }
- // Translate the field
- $this->_translate_schema_field($this->_fields[$name]['description']);
- $this->_translate_schema_field($this->_fields[$name]['helptext']);
- if (array_key_exists('start_fieldgroup', $field))
- {
- $this->_translate_schema_field($this->_fields[$name]['start_fieldgroup']['title']);
- }
- if ( array_key_exists("location", $field)
- && $field["location"] == "config"
- && ( ! array_key_exists("config_domain", $field)
- || ! array_key_exists("config_key", $field)))
- {
- $GLOBALS["midcom_errstr"] = "Config field detected without config_domain or config_key";
- debug_add ($GLOBALS["midcom_errstr"], <a href="../undocumented/_lib_constants_php.html#defineMIDCOM_LOG_ERROR">MIDCOM_LOG_ERROR</a>);
- debug_print_r ("Field $name was defined as: ", $field);
- debug_pop();
- return false;
- }
- }
- // If we have a datatype listing, we kill them before creating the new one
- // This covers the cases where we re-init the datamanager.
- if (! is_null($this->_datatypes))
- {
- $this->_destroy_types();
- }
- // Instantinate all Datatype Concepts
- $this->_datatypes = Array();
- foreach ($this->_fields as $name => $field)
- {
- debug_print_r("Processing $name:", $field);
- $classname = "midcom_helper_datamanager_datatype_" . $field["datatype"];
- $this->_datatypes[$name] =& new $classname ($this, $this->_storage, $field);
- if (! $this->_datatypes[$name])
- {
- $GLOBALS["midcom_errstr"] = "Could not instantinate " . $name . " Datatype Class.";
- debug_add($GLOBALS["midcom_errstr"], <a href="../undocumented/_lib_constants_php.html#defineMIDCOM_LOG_ERROR">MIDCOM_LOG_ERROR</a>);
- debug_pop();
- return false;
- }
- }
- $this->_populate_data();
- debug_pop();
- return true;
- }
- /*********************************/
- /*** Form Processing Functions ***/
- /**
- * 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:
- *
- * - <b>MIDCOM_DATAMGR_FAILED:</b> Something critical occured, processing failed.
- * - <b>MIDCOM_DATAMGR_CANCELLED:</b> Editing has been cancelled by the user, you
- * should return to view-mode, no changes made. In case of a creation loop,
- * the actual record has already been created and must be deleted by the
- * callee manually.
- * - <b>MIDCOM_DATAMGR_SAVED:</b> Data has been save, you should return to
- * view-mode.
- * - <b>MIDCOM_DATAMGR_EDITING:</b> We are still editing the data, keep calling the
- * form-mode. If we are in creation mode, this means that object creation
- * happened, but there was some validation error or the such, consult the
- * datamanager's error messages for further details; an object has been
- * created.
- * - <b>MIDCOM_DATAMGR_CREATEFAILED:</b> The creation callback could not create an
- * empty record for use with the datamanager. This is serious. No new
- * record has been created yet.
- * - <b>MIDCOM_DATAMGR_CREATING:</b> This is a variant of EDITING, the callee should show
- * the edit form now. It is the first time, the edit interface is shown, no
- * data has been stored yet.
- * - <b>MIDCOM_DATAMGR_CANCELLED_NONECREATED:</b> The user aborted the creation of an new
- * object before any new object could have been created. The application
- * should revert to some welcome screen, nothing has to be deleted.
- *
- * This method does its work only once. Consecutive calls will only yield the
- * same result as the first call to avoid trouble with multiple updated runs
- * in the datatypes.
- *
- * It will also call the _update_nemein_rcs helper to utilize its RCS mechanism
- * if available on any successful storage to