**/ class twIf_Generic_Convert extends twIf_Generic_Basic { /* Override defaults of our parent class */ const CAPTION = 'Import/Export'; const SUBMIT_CAPTION = 'Import/Export'; const MSG_SUCCESS = 'Import/Export completed successfully'; const MSG_FAILED = 'Import/Export failed'; const MSG_EMPTY = 'No data for Import/Export found'; const INTRODUCTION = ''; const ALLOW_FEEDBACK = true; const GENERATE_SUMMARY = true; const CACHE_ITEMS = true; /* Which convert-backend to use */ const CONVERT_CLASS = ''; const CONVERT_REQUEST_CLASS = 'twIf_Generic_Convert_Request'; /* Our convert-modes */ const MODE_IMPORT = 0; const MODE_EXPORT = 1; const CONVERT_MODE = twIf_Generic_Convert::MODE_EXPORT; /* Handle of the current request */ private $Request = null; /* Result from Import */ private $Result = null; private $Items = null; private $deferredItems = null; // {{{ getConvertClass /** * Retrive Classname for Convert-Backend * * @access protected * @return string **/ protected function getConvertClass () { return parent::findConstant ('CONVERT_CLASS', false); } // }}} // {{{ getConvertRequestClass /** * Retrive the name of the class to use as convert-request * * @access protected * @return string **/ protected function getConvertRequestClass () { return parent::findConstant ('CONVERT_REQUEST_CLASS', self::CONVERT_REQUEST_CLASS); } // }}} // {{{ getConvertMode /** * Retrive our convert-direction * * @access protected * @return enum **/ protected function getConvertMode () { return parent::findConstant ('CONVERT_MODE', self::MODE_EXPORT); } // }}} // {{{ getConvertFields /** * Retrive field-definition for convert-module * * @access protected * @return array **/ protected function getConvertFields () { return array (); } // }}} // {{{ giveFeedback /** * Determine wheter the editor-widget should output a feedback or not * * @access protected * @return bool **/ protected function giveFeedback () { return self::findConstant ('ALLOW_FEEDBACK', true); } // }}} // {{{ getMessageConvertSuccess /** * Which message to output when an import/export * * @access protected * @return string **/ protected function getMessageConvertSuccess () { return self::findConstant ('MSG_SUCCESS', self::MSG_SUCCESS); } // }}} // {{{ getMessageConvertFailed /** * Which message to output whenver convert failed * * @access protected * @return string **/ protected function getMessageConvertFailed () { return self::findConstant ('MSG_FAILURE', self::MSG_FAILED); } // }}} // {{{ getMessageNoChanges /** * Which message to output whenever no changes where made * * @access protected * @return string **/ protected function getMessageConvertEmpty () { return self::findConstant ('MSG_EMPTY', self::MSG_EMPTY); } // }}} // {{{ getSubmitCaption /** * Retrive the caption of our submit-button * * @access protected * @return string **/ protected function getSubmitCaption () { if ($this->getCovertMode == self::MODE_EXPORT) $Default = 'Export'; else $Default = 'Import'; return self::findConstant ('SUBMIT_CAPTION', $Default); } // }}} // {{{ getConvertRequest /** * Retrive handle of the current request * * @access public * @return object **/ public function getConvertRequest () { return $this->Request; } // }}} // {{{ setConvertRequest /** * Store our current request * * @param object $Handle * * @access protected * @return void **/ protected function setConvertRequest ($Request) { if (!is_object ($this->Request)) $this->Request = $Request; } // }}} // {{{ getFields /** * Retrive the fields for the request-generator * * @access protected * @return array **/ protected function getFields () { // TODO: Which fields are required for export-mode? if ($this->getConvertMode () == self::MODE_EXPORT) return array (); return array ( 'ImportData' => array ( 'Type' => twIf_Widget_Control::TYPE_UPLOAD, 'Caption' => 'Data for Import', 'Read' => 'getImportData()', 'Write' => 'setImportData()', ), ); } // }}} // {{{ prepare /** * Prepare this interface for output * * @access public * @return bool **/ public function prepare () { if (isset ($_REQUEST ['twIfConvertProceed']) && is_array ($Req = $this->retriveValue ('Request', false))) { $Class = $this->getConvertRequestClass (); $Request = new $Class; foreach ($Req as $Name=>$Value) if (ord ($Name [0]) != 0) $Request->update ($Name, $Value, false); if (($rc = $this->prepareRequest ($Request)) !== null) return $rc; } elseif (isset ($_REQUEST ['twIfConvertCancel'])) $this->removeStoredValues (); return parent::prepare (); } // }}} // {{{ getDefinition /** * Generate Page-Definition * * @access public * @return array **/ public function getDefinition () { // Load definition from our parent $Base = parent::getDefinition (); // Validate the request-class $Class = $this->getConvertRequestClass (); if (($Class != self::CONVERT_REQUEST_CLASS) && !is_subclass_of ($Class, self::CONVERT_REQUEST_CLASS)) $Base [] = array ( 'Type' => 'Feedback', 'Success' => false, 'Message' => twIf_i18n::getText ('The Request-Class %s has to extend %s', $Class, self::CONVERT_REQUEST_CLASS), ); // Append the summary elseif ($this->onSummary ()) { $Base [] = $Proceed = array ( 'Type' => 'Chooser', 'Items' => array ( $this->getSubmitCaption () => $this->insertURLParameter ('twIfConvertProceed', 1), 'Cancel' => $this->insertURLParameter ('twIfConvertCancel', 1), ), ); $Base [] = array ( 'Type' => 'Listing', 'Paging' => false, 'Counter' => null, 'Source' => array ($this, 'listStoredItems'), 'Fields' => array ($this, 'getConvertFields'), 'Options' => array (), 'Highlight' => array (), 'SortParams' => array ('Enabled' => false), 'Group' => null, 'EnableToggle' => false, 'ShowHeader' => true, 'EnableSelect' => false, 'Select' => null, ); $Base [] = $Proceed; // Append the request-generator } else { $Base [] = array ( 'Type' => 'Editor', 'Mode' => twIf_Widget_Object::MODE_CREATE, 'Constructor' => array (), 'Source' => $Class, 'Fields' => array ($this, 'getFields'), 'onSuccess' => array ($this, 'prepareRequest'), 'Feedback' => $this->giveFeedback (), 'msgSaved' => $this->getMessageConvertSuccess (), 'msgSaveFailed' => $this->getMessageConvertFailed (), 'msgNoChanges' => $this->getMessageConvertEmpty (), 'msgSubmit' => $this->getSubmitCaption (), ); if (is_array ($this->deferredItems) && (count ($this->deferredItems) > 0)) { $Base [] = array ('Type' => 'Caption', 'Text' => 'The following records were not imported or caused errors'); $Base [] = array ( 'Type' => 'Listing', 'Paging' => false, 'Counter' => null, 'Source' => array ($this, 'listDeferredItems'), 'Fields' => array ($this, 'getDeferredFields'), 'Options' => array (), 'Highlight' => array (), 'EnableToggle' => false, 'ShowHeader' => true, 'EnableSelect' => false, ); } } return $Base; } // }}} protected function listDeferredItems () { return $this->deferredItems; } protected function getDeferredFields () { if (!is_array ($this->deferredItems) || (count ($this->deferredItems) < 1)) return false; foreach ($this->deferredItems as $I) { $Fields = array (); foreach ($I as $K=>$V) $Fields [$K] = array ( 'Caption' => $K, 'Read' => $K, ); return $Fields; } } // {{{ listItems /** * Retrive Item-Listing for export-mode * * @access protected * @return array **/ protected function listItems () { return $this->listStoredItems (); } // }}} // {{{ listStoredItems /** * Generate an item cache and list items from there * * @access protected * @return array **/ protected function listStoredItems () { // Check if there are cached items if (self::findConstant ('CACHE_ITEMS', true) && is_array ($this->Items)) return $this->Items; // Check if there are cached values or try to cache them $cacheIDs = false; if (($sP = $this->retriveValue ('sortParams', false)) === false) { if (!is_array ($sP = $this->getSortParams ()) || (count ($sP) != 2)) $sP = array (null, null); $this->storeValue ('sortParams', $sP, true, false); } if (($Class = $this->retriveValue ('Class', false)) === false) { // Check if the used class exists if (!class_exists ($Class = $this->getClass ())) { trigger_error (twIf_i18n::getText ('Class %s does not exist', $Class)); return ($this->Items = array ()); } // Check if it features the listItems-function if (!is_callable (array ($Class, 'listItems'))) { trigger_error (twIf_i18n::getText ('Class %s does not have listItems-interface', $Class)); return ($this->Items = array ()); } $this->storeValue ('Class', $Class, true, false); } if (($lP = $this->retriveValue ('listParams', false)) === false) { if (!is_array ($lP = $this->getListParams ()) && !is_object ($lP)) $lP = null; $this->storeValue ('listParams', $lP, true, false); $cacheIDs = true; } if (is_array ($IDs = $this->retriveValue ('IDs', false))) { $cacheIDs = false; if (is_object ($lP)) $lP->addField (constant ($Class . '::PRIMARY'), $IDs); elseif (is_array ($lP)) $lP [constant ($Class . '::PRIMARY')] = $IDs; else $lP = array ( constant ($Class . '::PRIMARY') => $IDs, ); } if (!is_array ($Request = $this->retriveValue ('Request', false))) $this->storeValue ('Request', (array)$this->getConvertRequest (), true, false); // List the items $this->Items = call_user_func (array ($Class, 'listItems'), null, $lP, null, null, $sP [0], $sP [1]); if ($cacheIDs) { $IDs = array (); foreach ($this->Items as $Item) $IDs [] = $Item->getID (); $this->storeValue ('IDs', $IDs, true, false); } return $this->Items; } // }}} // {{{ getListParams /** * Get Parameters for listItems * * @access protected * @return array */ protected function getListParams () { return null; } // }}} // {{{ getSortParams /** * Retrive parameters for sorting * * @access protected * @return array */ protected function getSortParams () { return array ( self::findConstant ('SORT_FIELD', null), self::findConstant ('SORT_ORDER', null), ); } // }}} // {{{ getCreateParams /** * Define parameters to forward to constructor of our class (on import) * * @access protected * @return array **/ protected function getCreateParams () { return array (); } // }}} // {{{ getImportParams /** * Retrive special parameters for the import()-Function on convert-class * * @access protected * @return array **/ protected function getImportParams () { // Example: // For CSV-Import with coma-seperated data // return array (','); return array (); } // }}} // {{{ getExportParams /** * Retrive additional parameters for export-module * * @access protected * @return array **/ protected function getExportParams () { return array (); } // }}} // {{{ getImportObjects /** * Retrive all objects that where imported * * @access protected * @return array **/ protected function getImportObjects () { return $this->Result; } // }}} // {{{ getSummary /** * Check wheter to do a summary before import/export * * @access protected * @return bool **/ protected function getSummary () { return self::findConstant ('GENERATE_SUMMARY', false); } // }}} // {{{ onSummary /** * Check if we are on summary page right now * * @access public * @return bool **/ public function onSummary () { return ( $this->getSummary () && ($this->getConvertMode () == self::MODE_EXPORT) && (is_object ($this->getConvertRequest ()) || is_array ($this->retriveValue ('Request', false))) && !isset ($_REQUEST ['twIfConvertProceed']) ); } // }}} // {{{ prepareRequest /** * Prepare to handle the request * * @param object $Request * * @access protected * @return bool **/ protected final function prepareRequest ($Request) { // Store the request internally $this->setConvertRequest ($Request); // Validate our convert-class if (!class_exists ($Class = $this->getConvertClass ())) { trigger_error (twIf_i18n::getText ('Class %s does not exist', $Class)); return false; } // Don't do anything if we are on summary-page if ($this->onSummary ()) return true; // Forward request to handler return $this->handleRequest ($Request); } // }}} // {{[ handleRequest /** * Handle an incoming convert-request * * @param object $Request * * @access protected * @return bool **/ protected function handleRequest ($Request) { // Retrive our convert-class $Class = $this->getConvertClass (); // Go into export-mode if wanted if ($this->getConvertMode () == self::MODE_EXPORT) { // Construct parameters for export $Params = array ( $this->listStoredItems (), $this->getConvertFields (), ); // Append custom parameters if (is_array ($sParams = $this->getExportParams ())) foreach ($sParams as $Param) $Params [] = $Param; // Retrive the Export-Data $this->Result = call_user_func_array (array ($Class, 'export'), $Params); // Remove the stored values $this->removeStoredValues (); // Push to the user return $this->sendFile ($this->Result, constant ($Class . '::MIME_TYPE'), 'export.' . constant ($Class . '::SUFFIX')); } // Construct parameters for import $Params = array ( $Request->getImportData (), $this->getClass (), $this->getConvertFields (), $this->getCreateParams (), ); // Check if there is a valid field-definition if (!is_array ($Params [2])) { trigger_error (twIf_i18n::getText ('Failed to generate Interface')); return false; } // Append custom parameters if (is_array ($sParams = $this->getImportParams ())) foreach ($sParams as $Param) $Params [] = $Param; // Try to import $this->Result = @call_user_func_array (array ($Class, 'import'), $Params); $this->deferredItems = call_user_func (array ($Class, 'getDeferredImports')); return true; } // }}} // {{{ removeStoredValues /** * Remove our stored values from session * * @access private * @return void **/ private function removeStoredValues () { $this->unsetValue ('sortParams'); $this->unsetValue ('listParams'); $this->unsetValue ('Class'); $this->unsetValue ('IDs'); $this->unsetValue ('Request'); } // }}} } ?>