**/ class twIf_Widget_Object extends twIf_Object_Access { const CREATE_CAPTION = 'Create'; const EDIT_CAPTION = 'Save'; const MODE_CREATE = 'new'; const MODE_EDIT = ''; // {{{ haveData /** * Check if there was data for save/create-option supplied * * @param mixed $Handle * * @access public * @return bool **/ public static function haveData ($Handle) { if (is_object ($Handle)) { $Class = strtolower (get_class ($Handle)); $ID = $Handle->getID (); } else { $Class = strtolower ($Handle); $ID = 'new'; } if (!isset ($_POST ['obj_type']) || (md5 ($Class) != $_POST ['obj_type'])) return false; if (!isset ($_POST ['obj_id']) || (md5 ($ID) != $_POST ['obj_id'])) return false; return true; } // }}} // {{{ createObject /** * Create a new Object via a newObject-generated form * * @param string $Class Name of class to create * @param array $Fields (optional) Field-Definition * @param array $Params (optional) Which fileds pipe to constructor * @param bool $Exception (optional) Throw an exception when there are fields missing (default) * * @access public * @return object */ public function createObject ($Class, $Fields = array (), $Params = array (), $Strict = true, $Exception = true) { // Check if there was data supplied if (!self::haveData ($Class)) return null; // Check required variables $Missing = array (); foreach ($Fields as $Name=>$Field) { if (!is_array ($FieldData = self::parseFieldDef ($Name, $Field, $Class, 0))) { trigger_error (twIf_i18n::getText ('Could not parse definition for %s', $Name)); return false; } $Fields [$Name]['__pData'] = $FieldData; if (!isset ($Field ['Required']) || ($Field ['Required'] != true)) continue; if (!is_object ($Control = parent::getControl ($FieldData)) || !$Control->hasPostValue (false)) $Missing [] = array ($Name, 1, null); } if (count ($Missing) > 0) { if ($Exception) throw new twIf_Validator_Error ('Missing fields', $Missing, $Class); return false; } // Generate parameters for constructor $Flags = array (); foreach ($Params as $FieldName) if (is_object ($FieldName)) $Flags [] = $FieldName; elseif (!isset ($Fields [$FieldName])) $Flags [] = ($Strict ? '' : $FieldName); else { $Flags [] = self::getPostValue ($Fields [$FieldName]['__pData'], true); unset ($Fields [$FieldName]); } // Try to create a new instance if (!is_object ($Instance = call_user_func_array (array ($Class, 'newInstance'), $Flags))) { trigger_error (twIf_i18n::getText ('Could not create class %s', $Class)); return false; } $oObjID = $_POST ['obj_id']; $oObjType = $_POST ['obj_type']; $_POST ['obj_id'] = md5 ($Instance->getID ()); $_POST ['obj_type'] = md5 (strtolower (get_class ($Instance))); // Update callbacks on fields foreach ($Fields as $Name=>$Data) if (isset ($Data ['__pData']) && is_array ($Data ['__pData']['Write']) && ($Data ['__pData']['Write'][0] == $Class)) $Fields [$Name]['__pData']['Write'][0] = $Instance; // Treat new object as an old one :) if (($rc = self::saveObject ($Instance, $Fields)) !== false) return $Instance; trigger_error (twIf_i18n::getText ('Could not update class %s', $Class)); $Instance->remove (); $_POST ['obj_id'] = $oObjID; $_POST ['obj_type'] = $oObjType; return $rc; } // }}} // {{{ saveObject /** * Modify an existing object in database * * @param object $Object Object to modify * @param array $Fields (optional) Field-Definition * * @access public * @return bool */ public function saveObject ($Object, $Fields = array ()) { // We need an object, be sure that we have one if (!is_object ($Object)) { trigger_error (twIf_i18n::getText ('Could not save a non-object')); return false; } // Determine which class to edit $Class = get_class ($Object); if (!self::haveData ($Object)) return false; $Changed = false; foreach ($Fields as $Key=>$Field) { // Try to parse field-data if (is_array ($Field ['__pData'])) $FieldData = $Field ['__pData']; elseif (!is_array ($FieldData = self::parseFieldDef ($Key, $Field, $Object))) continue; // Get content of the field $Value = self::getPostValue ($FieldData); if ($Value === null) continue; if (!($rc = self::setFieldValue ($Object, $FieldData, $Value))) trigger_error (twIf_i18n::getText ('setFieldValue() failed')); $Changed = $Changed || ($rc && (is_array ($FieldData ['Write']) || $Object->checkUpdate ())); } // Check if there were some modifycations on the object # This fails if the object gets commited by an API-Call # $Changed = $Changed && $Object->checkUpdate (); // Commit to database if anything was changed if ($Changed) return $Object->commit (); // Return unchanged-status return null; } // }}} // {{{ newObject /** * Print Formular to create a new object * * @param string $Class Name of class to create * @param array $Fields (optional) Field-Definition * @param string $myURL (optional) Where to post data to * @param object $Exception (optional) * @param string $Caption (optional) Caption for submit-button * * @access public * @return string */ public function newObject ($Class, $Fields = array (), $myURL = null, $Exception = null, $Caption = self::CREATE_CAPTION) { return self::editObject ($Class, $Fields, $myURL, $Exception, $Caption, true); } // }}} // {{{ editObject /** * Print Formular to modify an existing object * * @param object $Object Object to modify * @param array $Fields (optional) Field-Definition * @param string $myURL (optional) Where to post data to * @param object $Exception (optional) * @param string $Caption (optional) Caption for submit-button * @param bool $AllowCreate (optional) Allow Class-Names instead of an object * * @access public * @return string */ public static function editObject ($Object, $Fields = array (), $myURL = null, $Exception = null, $Caption = self::EDIT_CAPTION, $AllowCreate = false) { // Validate input if (!is_object ($Object) && !$AllowCreate) return; if (!is_object ($Object) && !class_exists ($Object)) { trigger_error (twIf_i18n::getText ('Class %s does not exist', $Object), E_USER_WARNING); return; } // Determine which class to use if (is_object ($Object)) $Class = strtolower (get_class ($Object)); else $Class = strtolower ($Object); // Initialize $AutoSubmit = (count ($Fields) < 2); $forceSubmitBreak = false; $FieldDefs = array (); $ObjID = md5 (is_object ($Object) ? $Object->getID () : 'new'); $ClsID = md5 ($Class); $Descriptions = array (); $errorFields = array (); $buf = ''; $setFocus = ''; $hasExtended = false; $isExtended = (isset ($_REQUEST [$ClsID . '_ex']) && ($_REQUEST [$ClsID . '_ex'] == 1) ? true : false); // Detect Columns $Columns = array (); foreach ($Fields as $Name=>$Setting) { if (!isset ($Setting ['Column'])) $Setting ['Column'] = 1; if ($Setting ['Extended'] === true) { $hasExtended = true; if (!$isExtended) continue; } elseif (($Setting ['Extended'] === null) && $isExtended) continue; if (!isset ($Columns [$Setting ['Column']])) $Columns [$Setting ['Column']] = array (); $Columns [$Setting ['Column']][$Name] =& $Fields [$Name]; } # ksort ($Columns); // Detect which groups to use $ColumnGroups = array (); $maxGroups = 1; foreach ($Columns as $Col=>$Items) { $ColumnGroups [$Col] = array ('__undef__' => array ()); foreach ($Items as $Name=>$Settings) { if (isset ($Settings ['Group'])) $Gr = $Settings ['Group']; else $Gr = '__undef__'; if (!isset ($ColumnGroups [$Col][$Gr])) $ColumnGroups [$Col][$Gr] = array ('Name' => $Gr, 'Items' => array ()); $ColumnGroups [$Col][$Gr]['Items'][$Name] =& $Items [$Name]; } $maxGroups = max ($maxGroups, count ($ColumnGroups [$Col])); } // Generate output $buf .= '
\n"; // Check if any of the fields was marked as required foreach ($Fields as $Field) if ($Field ['Required']) { $buf .= '* ' . twIf_i18n::getText ('Required') . "
\n"; break; } if (count ($Descriptions) > 0) { $buf .= '' . ($i++) . ' ' . nl2br (twIf_i18n::getText ($Descr)) . '
'; $buf .= "