Ejemplo n.º 1
0
 protected static function storeModuleMagicData($shortname, $old_vers, $new_vers, $mod_configurator, $imported)
 {
     $mod_storage = $mod_configurator->getStorage();
     if (!$mod_storage instanceof I2CE_MagicDataNode) {
         I2CE::raiseError("Expecting magic data");
         return false;
     }
     //processconfig data
     $storage = I2CE::getConfig();
     $merges = $mod_configurator->getMerges();
     foreach ($merges as $path => $merge) {
         if ($storage->is_scalar($path)) {
             I2CE::raiseError("Trying to merge arrays into {$path} where target is scalar valued. Skipping");
             continue;
         }
         if ($mod_storage->is_scalar($path)) {
             I2CE::raiseError("Trying to merge arrays into {$path} where source is scalar valued. Skipping");
             continue;
         }
         $old_arr = $storage->getAsArray($path);
         $new_arr = $mod_storage->getAsArray($path);
         $mod_storage->__unset($path);
         if (!is_array($old_arr)) {
             //in case the target did not exist
             $old_arr = array();
         }
         if (!is_array($new_arr)) {
             //in case no values were set for the source
             $new_arr = array();
         }
         switch ($merge) {
             case 'uniquemerge':
                 $new_arr = I2CE_Util::array_unique(array_merge($old_arr, $new_arr));
                 break;
             case 'merge':
                 $new_arr = array_merge($old_arr, $new_arr);
                 break;
             case 'mergerecursive':
                 I2CE_Util::merge_recursive($old_arr, $new_arr);
                 $new_arr = $old_arr;
                 break;
         }
         $storage->__unset($path);
         $storage->{$path} = $new_arr;
     }
     //we took care of all array merges.  anything that is left is an overwrite.
     foreach ($mod_storage as $k => $v) {
         if ($k == 'config') {
             //don't update config info that might be here. It's handled below.
             continue;
         }
         if (is_scalar($v) && $mod_storage->is_translatable($k) && !$storage->is_parent($k)) {
             $storage->setTranslatable($k);
             $translations = $mod_storage->traverse($k, true, false)->getTranslations();
             foreach ($translations as $locale => $trans) {
                 if (strlen($trans) == 0) {
                     continue;
                 }
                 $storage->setTranslation($locale, $trans, $k);
             }
         } else {
             $storage->{$k}->setValue($v, null, false);
         }
         if ($storage->{$k} instanceof I2CE_MagicDataNode) {
             //free up some memory.
             $storage->{$k}->unpopulate(true);
         }
     }
     $storage->config->status->config_processed->{$shortname} = $new_vers;
     //set the config data as processed
     if (isset($storage->config->status->initialized->{$shortname})) {
         $storage->config->status->initialized->{$shortname} = 1;
         //set the config data as processed
     }
     foreach ($imported as $locale => &$data) {
         unset($data['old_vers']);
     }
     $storage->config->status->localized->{$shortname} = $imported;
     return true;
 }
 protected function loadMDTemplate($doc, $transform = false, $erase = false)
 {
     //doc is either a file name or a DOMDocument
     if ($transform) {
         //transform
         if (is_string($doc)) {
             $file = $doc;
             $doc = new DOMDocument();
             if (!($contents = file_get_contents($file))) {
                 $this->userMessage("Could not load source file");
                 return false;
             }
             if (!$doc->loadXML($contents)) {
                 $this->userMessage("Could not load file source contents");
                 return false;
             }
         }
         if (!$doc instanceof DOMDocument) {
             $this->userMessage("Could not load xml into document");
             return false;
         }
         $proc = new XSLTProcessor();
         $xslt_doc = new DOMDocument();
         if (!$xslt_doc->loadXML($transform)) {
             $this->userMessage("Could not load transform: " . $_FILES['xsl']['name']);
             return false;
         }
         if (!$proc->importStylesheet($xslt_doc)) {
             $this->userMessage("Could not import style sheet");
             return false;
         }
         $trans_doc = new DOMDocument('1.0', 'UTF-8');
         $trans_doc->appendChild($trans_doc->importNode($doc->documentElement, true));
         if (($trans_out = $proc->transformToXML($trans_doc)) === false) {
             $this->userMessage("Could not transform accoring to xsl");
             return false;
         }
     } else {
         $trans_doc = $doc;
     }
     if ($trans_doc instanceof DOMDocument) {
         $temp_file = tempnam(sys_get_temp_dir(), 'MDN_UPLOAD');
         if (!file_put_contents($temp_file, $trans_out)) {
             $this->userMessage("Could not save transformed files");
             return false;
         }
     } else {
         $temp_file = $trans_doc;
     }
     $template = new I2CE_MagicDataTemplate();
     $template->setVerboseErrors(true);
     if (!$template->loadRootFile($temp_file)) {
         I2CE::raiseError("Unable to load transformed file as Magic Data");
         $this->userMessage("Unable to load transformed file as Magic Data");
         return false;
     }
     if (!$template->validate()) {
         I2CE::raiseError("Unable to validate transformed file as Magic Data");
         $this->userMessage("Unable to validate transformed file as Magic Data");
         return false;
     }
     $store = new I2CE_MagicDataStorageMem();
     $mem_config = I2CE_MagicData::instance("mdn_load");
     $mem_config->addStorage($store);
     $nodeList = $template->query("/configurationGroup");
     if (!$nodeList instanceof DOMNodeList || $nodeList->length == 0) {
         $nodeList = $template->query("/I2CEConfiguration/configurationGroup");
         //perhaps we really need to do something more if this is a module
     }
     foreach ($nodeList as $configNode) {
         $locale = false;
         $status = $template->getDefaultStatus();
         if ($configNode->hasAttribute('locale')) {
             $locale = $configNode->getAttribute('locale');
         }
         $vers = '0';
         if ($template->setConfigValues($configNode, $mem_config, $status, $vers) === false) {
             I2CE::raiseError("Could not load configuration values");
             $this->userMessage("Could not load configuration values");
             return false;
         }
     }
     //I2CE::raiseError(print_r($mem_config->getAsArray(),true));
     if ($erase) {
         $this->config->eraseChildren();
     }
     $merges = $template->getMerges();
     foreach ($merges as $path => $merge) {
         if ($this->config->is_scalar($path)) {
             I2CE::raiseError("Trying to merge arrays into {$path} where target is scalar valued. Skipping");
             continue;
         }
         if ($mem_config->is_scalar($path)) {
             I2CE::raiseError("Trying to merge arrays into {$path} where source is scalar valued. Skipping");
             continue;
         }
         $old_arr = $this->config->getAsArray($path);
         $new_arr = $mem_config->getAsArray($path);
         $mem_config->__unset($path);
         if (!is_array($old_arr)) {
             //in case the target did not exist
             $old_arr = array();
         }
         if (!is_array($new_arr)) {
             //in case no values were set for the source
             $new_arr = array();
         }
         switch ($merge) {
             case 'uniquemerge':
                 $new_arr = I2CE_Util::array_unique(array_merge($old_arr, $new_arr));
                 break;
             case 'merge':
                 $new_arr = array_merge($old_arr, $new_arr);
                 break;
             case 'mergerecursive':
                 I2CE_Util::merge_recursive($old_arr, $new_arr);
                 $new_arr = $old_arr;
                 break;
         }
         $this->config->__unset($path);
         $this->config->{$path} = $new_arr;
     }
     //we took care of all array merges.  anything that is left is an overwrite.
     foreach ($mem_config as $k => $v) {
         if (is_scalar($v) && $mem_config->is_translatable($k) && !$this->config->is_parent($k)) {
             $this->config->setTranslatable($k);
             $translations = $mem_config->traverse($k, true, false)->getTranslations();
             foreach ($translations as $locale => $trans) {
                 if (strlen($trans) == 0) {
                     continue;
                 }
                 $this->config->setTranslation($locale, $trans, $k);
             }
         } else {
             $this->config->{$k}->setValue($v, null, false);
         }
         if ($this->config->{$k} instanceof I2CE_MagicDataNode) {
             //free up some memory.
             $this->config->{$k}->unpopulate(true);
         }
     }
     return true;
 }
 /**
  * Process values for a config node
  * @param DOMNode $configNode
  * @param I2CE_MagicDataNode $data     
  * @param array $status.  If null, it defaults to the array set by getDefaultStatus().  The current status (of parent node) 
  * @param string $version .  Defaults to '0' .  The version of the currently loaded data in $storage responsible for this XML
  * @param array of string $paths -- the current path into the $storage that we are using.  Defaults to the empty array().
  * @returns boolean. true on sucess
  */
 public function processValues($configNode, $storage, $status = null, $vers, $paths)
 {
     if (!$configNode instanceof DOMNode) {
         $this->raiseError("Did not receive configuration node");
         return false;
     }
     //deal with any erase Information
     if (!$this->updatePaths($configNode, $paths)) {
         return false;
     }
     $this->processErasers($configNode, $paths);
     if ($status === null) {
         $status = $this->getDefaultStatus();
     }
     if ($configNode->hasAttribute('path')) {
         //check to see if there is an explicit path set
         $path = $configNode->getAttribute('path');
         $hasPath = true;
     } else {
         $path = $configNode->getAttribute('name');
         $hasPath = false;
     }
     if (strlen($path) === 0) {
         $this->raiseError("configuration has empty path at " . $storage->getPath());
         return false;
     }
     if ($configNode->hasAttribute('type')) {
         $valueType = strtolower(trim($configNode->getAttribute("type")));
     } else {
         $valueType = 'string';
     }
     if ($valueType == 'delimited') {
         // Delimited types really only make sense as many values
         $valueValues = 'many';
     } elseif ($configNode->hasAttribute('values')) {
         $valueValues = strtolower(trim($configNode->getAttribute("values")));
     } else {
         $valueValues = 'single';
     }
     $uniquemerge = null;
     if (array_key_exists('uniquemerge', $status)) {
         $uniquemerge = $status['uniquemerge'];
         unset($status['uniquemerge']);
     }
     $valStatus = $this->processStatus($configNode, $status, $vers);
     if (array_key_exists('uniquemerge', $valStatus)) {
         //the uniquemerge status has been set on explicitly this node.
         //do nothing
     } else {
         //the unique merge status has not been set on this node.
         //if this node is a values='many' values='string' make it a default merge
         if ($valueValues == 'many' && $valueType == 'string') {
             $valStatus['uniquemerge'] = true;
         } else {
             if ($uniquemerge !== null) {
                 $valStatus['uniquemerge'] = $uniquemerge;
             }
         }
     }
     if (!$valStatus['overwrite']) {
         return true;
     }
     $valueList = $this->query("./value", $configNode);
     if ($valueList->length == 0) {
         if ($valStatus['required'] === true) {
             $this->raiseError("Required value is not set at " . $this->getConfigPath($configNode));
             return false;
         } else {
             //not required so let's return
             return true;
         }
     }
     $processor = 'processValues_' . $valueType . '_' . $valueValues;
     $vals = null;
     $encoding = null;
     if ($valueValues == 'single') {
         if ($valueList->item(0) instanceof DOMElement) {
             //item 0 should exist by the check/return above
             $vals = $this->{$processor}(trim($valueList->item(0)->textContent), $valStatus);
         }
     } else {
         $vals = array();
         for ($k = 0; $k < $valueList->length; $k++) {
             if ($valueList->item($k) instanceof DOMElement) {
                 $vals[$k] = trim($valueList->item($k)->textContent);
             }
         }
         $vals = $this->{$processor}($vals, $valStatus);
         if (!is_array($vals)) {
             $this->raiseError("Expected array to be returned from {$processor}() while evaluating " . $this->getConfigPath($configNode));
             return false;
         }
     }
     if ($valStatus['required'] === true && ($valueValues == 'single' && $vals === null || $valueValues == 'many' && count($vals) == 0)) {
         $this->raiseError("Required value is not set at  " . $this->getConfigPath($configNode) . ' in the module ' . $this->query("/I2CEConfiguration")->item(0)->getAttribute('name'));
         return false;
     }
     $validator = 'validateValues_' . $valueType . '_' . $valueValues;
     if ($this->_hasMethod($validator)) {
         $validate = $this->{$validator}($vals, $valStatus);
         if ($validate !== null) {
             $this->raiseError("Invalid data at " . $this->getConfigPath($configNode) . " + " . $validate);
             return false;
         }
     }
     $locale = null;
     if (array_key_exists('locale', $valStatus) && $valStatus['locale']) {
         //this node is translatable.
         $locale = $valStatus['locale'];
     }
     if ($valStatus['uniquemerge'] && $valueValues == 'many') {
         if ($storage->is_scalar($path)) {
             $this->raiseError("Trying to set non-scalar value at scalar valued (uniquemerge):\n" . $storage->getPath() . '/' . $path);
             return false;
         }
         $valStorage = $this->traversePaths($storage, $paths);
         if (!$valStorage instanceof I2CE_MagicDataNode) {
             return false;
         }
         $old_vals = $valStorage->getAsArray(null, $locale);
         $valStorage->eraseChildren($locale);
         $vals = I2CE_Util::array_unique(array_merge($old_vals, $vals));
     } else {
         if ($valStatus['mergerecursive'] && $valueValues == 'many') {
             if ($storage->is_scalar($path)) {
                 $this->raiseError("Trying to set non-scalar value at scalar valued (mergerecursive):\n" . $storage->getPath() . '/' . $path);
                 return false;
             }
             $valStorage = $this->traversePaths($storage, $paths);
             if (!$valStorage instanceof I2CE_MagicDataNode) {
                 return false;
             }
             $old_vals = $valStorage->getAsArray(null, $locale);
             $valStorage->eraseChildren($locale);
             I2CE_Util::merge_recursive($old_vals, $vals);
             $vals = $old_vals;
         } else {
             if ($valStatus['merge'] && $valueValues == 'many') {
                 if ($storage->is_scalar($path)) {
                     $this->raiseError("Trying to set non-scalar value at scalar valued (merge):\n" . $storage->getPath() . '/' . $path);
                     return false;
                 }
                 $valStorage = $this->traversePaths($storage, $paths);
                 if (!$valStorage instanceof I2CE_MagicDataNode) {
                     return false;
                 }
                 $old_vals = $valStorage->getAsArray(null, $locale);
                 $valStorage->eraseChildren($locale);
                 $vals = array_merge($old_vals, $vals);
             } else {
                 if (is_array($vals) && $storage->is_scalar($path)) {
                     $this->raiseError("Trying to set non-scalar value at scalar valued:\n" . $storage->getPath() . '/' . $path);
                     return false;
                 }
                 $valStorage = $this->traversePaths($storage, $paths);
                 if (!$valStorage instanceof I2CE_MagicDataNode) {
                     return false;
                 }
             }
         }
     }
     $merges = array('merge', 'mergerecursive', 'uniquemerge');
     foreach ($merges as $merge) {
         if (!array_key_exists($merge, $valStatus) || !$valStatus[$merge]) {
             continue;
         }
         $this->merges[$valStorage->getPath(false)] = $merge;
     }
     //only one merge status can be set, notice above that unqiuemerge takes presedence over mergerecursive which takes presidents over mergere
     $valStorage->setValue($vals, $locale, false);
     if (array_key_exists('binary', $valStatus)) {
         $this->setAttributeOnChildren('binary', $valStatus['binary'], $valStorage, $vals);
     }
     if (array_key_exists('encoding', $valStatus)) {
         $this->setAttributeOnChildren('encoding', $valStatus['encoding'], $valStorage, $vals);
     }
     return true;
 }