public static function dumpCacheFileLocation($prefix, $file_name) { if (!function_exists('apc_fetch')) { return false; } $locales = I2CE_Locales::getPreferredLocales(); foreach ($locales as $locale) { $file_loc = apc_fetch("I2CE_Dumper_{$prefix}_Location:{$locale}:{$file_name}"); if ($file_loc) { break; } } if (!$file_loc) { return false; } $headers = apc_fetch("I2CE_Dumper_{$prefix}_Headers:{$file_name}"); if (!$headers) { return false; } $cacheTime = apc_fetch("I2CE_Dumper_{$prefix}_CacheTime"); return self::dumpContents($file_loc, $headers, $cacheTime); }
/** * Find a file (or directory) of a certain category * @param string $category the category of the file * @param string $file_name the file name of the file we wish to find * @param boolean $find_all Defatults to false * @returns mixed. Returns either a string which is the path and file name of the file * we found, or null if we did not find the file. */ public function search($category, $file_name, $find_all = false) { if (!array_key_exists($category, $this->ordered_paths)) { $factory = I2CE_ModuleFactory::instance(); $factory->loadPaths(null, $category, false, $this); } if ($find_all || $this->stale_time < 0) { return parent::search($category, $file_name, $find_all); } if (array_key_exists($category, $this->preferred_locales) && is_array($this->preferred_locales[$category])) { $locales = $this->preferred_locales[$category]; } else { $locales = I2CE_Locales::getPreferredLocales(); } if (array_key_exists('I2CE_FileSearch_Caching', $_SESSION) && is_array($_SESSION['I2CE_FileSearch_Caching']) && array_key_exists($category, $_SESSION['I2CE_FileSearch_Caching']) && is_array($_SESSION['I2CE_FileSearch_Caching'][$category]) && array_key_exists($file_name, $_SESSION['I2CE_FileSearch_Caching'][$category]) && is_array($_SESSION['I2CE_FileSearch_Caching'][$category][$file_name])) { $data = $_SESSION['I2CE_FileSearch_Caching'][$category][$file_name]; if (array_key_exists('time', $data) && array_key_exists('location', $data) && array_key_exists('locale', $data)) { if (is_readable($data['location']) && time() - $data['time'] < $this->stale_time) { $this->found_locales = $data['locale']; return $data['location']; } else { unset($_SESSION['I2CE_FileSearch_Caching'][$category][$file_name]); } } } //did not find the file $location = parent::search($category, $file_name, false); if (!is_string($location) || strlen($location) == 0) { return null; } $_SESSION['I2CE_FileSearch_Caching'][$category][$file_name] = array('time' => time(), 'location' => $location, 'locale' => $this->found_locales); return $location; }
protected function displayConfig($config, $magicNode, $full) { foreach ($config as $key => $child) { if ($config->is_parent($key)) { $path = 'magicDataBrowser/show/' . $config->getPath(false); $node = $this->template->loadFile("browser_node.html", 'li'); $magicNode->appendChild($node); $this->template->setDisplayDataImmediate('erase_action', 'magicDataBrowser/erase/' . $config->getPath(false) . "/{$key}", $node); $this->template->setDisplayDataImmediate('trans_action', 'magicDataBrowser/trans/' . $config->getPath(false) . "/{$key}", $node); $subNode = $this->template->query("./descendant-or-self::node()[@name='magic_data_list']", $node); $this->template->setDisplayDataImmediate('browser_magic_data_key_path', $path . '/' . $key, $node); $this->template->setDisplayDataImmediate('browser_magic_data_key', $key, $node); if ($full && $subNode->length > 0) { $this->displayConfig($child, $subNode->item(0), $full); } else { $valueNode = $this->template->getElementById('browser_magic_data_value', $node); if (!$valueNode instanceof DOMElement) { continue; } if ($this->hasAjax()) { $replacementNode = $this->template->createElement('span', array('class' => 'clickable', 'id' => "magic_data_list_{$path}/{$key}"), 'show values'); $this->addAjaxUpdate("magic_data_list_{$path}/{$key}", "magic_data_list_{$path}/{$key}", 'click', "{$path}/{$key}", 'magic_data_list'); $this->addAjaxCompleteFunction("magic_data_list_{$path}/{$key}", "\$('magic_data_list_{$path}/{$key}').removeClass('clickable')"); } else { $replacementNode = $this->template->createTextNode('*******'); } $valueNode->parentNode->replaceChild($replacementNode, $valueNode); } } else { if ($config->is_scalar($key)) { //just display the value $locale = ''; if ($config->traverse($key, false, false)->hasAttribute('binary') && $config->traverse($key, false, false)->getAttribute('binary')) { $bin = 1; $valueNode = $this->template->loadFile("browser_binary_node.html", 'li'); $this->template->setDisplayDataImmediate('browser_magic_data_value_binary_link', 'magicDataBrowser/download/' . $config->getPath(false) . "/{$key}", $valueNode); } else { $bin = 0; $valueNode = $this->template->loadFile("browser_value_node.html", 'li'); if ($config->is_translatable($key)) { if ($this->request_exists('locale')) { $locale = $this->request('locale'); } else { $locales = I2CE_Locales::getPreferredLocales(); reset($locales); $locale = current($locales); } $child = $config->getTranslation($locale, false, $key); $locale = ' [' . $locale . ']'; } $this->template->setDisplayDataImmediate('browser_magic_data_key', $key, $valueNode); $this->template->setDisplayDataImmediate('browser_magic_data_value', $child, $valueNode); } $this->template->setDisplayDataImmediate('bin_node', $bin, $valueNode); $magicNode->appendChild($valueNode); $this->template->setDisplayDataImmediate('browser_magic_data_key_label', $key . $locale, $valueNode); $change_value_action = 'index.php/magicDataBrowser/set/' . $config->getPath(false); $this->template->setDisplayDataImmediate('change_value_action', $change_value_action, $valueNode); if (!$bin && ($vNode = $this->template->getElementByName('browser_magic_data_value', 0, $valueNode)) instanceof DOMNode) { //if ($this->post_exists('browser_magic_data_value') && $this->post_exists('browser_magic_data_key')) { $js = "var e = \$(this); \ne.setStyle('background-color','yellow');\nnew Request({\n'useSpinner':true,\nurl: '{$change_value_action}',\nmethod: 'post',\n'data':{'browser_magic_data_value': e.get('value'),'browser_magic_data_key':'{$key}'},\nonComplete: function(response) { \n e.setStyle('background-color','white');\n}\n}).send();"; $vNode->setAttribute('onchange', $js); } $this->template->setDisplayDataImmediate('erase_action', 'magicDataBrowser/erase/' . $config->getPath(false) . "/{$key}", $valueNode); $this->template->setDisplayDataImmediate('trans_action', 'magicDataBrowser/trans/' . $config->getPath(false) . "/{$key}", $valueNode); $this->template->setDisplayDataImmediate('upload_action', 'magicDataBrowser/upload/' . $config->getPath(false) . "/{$key}", $valueNode); $this->template->setDisplayDataImmediate('upload_binary_action', 'magicDataBrowser/upload_binary/' . $config->getPath(false) . "/{$key}", $valueNode); $this->template->setDisplayDataImmediate('load_action', 'magicDataBrowser/load/' . $config->getPath(false) . "/{$key}", $valueNode); $keys = array(); foreach (I2CE::getConfig()->getKeys("/modules/magicDataBrowser/transforms") as $key) { $keys[$key] = $key; } $this->template->setDisplayDataImmediate('transform_key', $keys, $valueNode); $this->useDropDown(); } else { if ($config->is_indeterminate($key)) { $valueNode = $this->template->loadFile("browser_value_node_notset.html", 'li'); $magicNode->appendChild($valueNode); $this->template->setDisplayDataImmediate('browser_magic_data_key', $key, $valueNode); $this->template->setDisplayDataImmediate('upload_action', 'magicDataBrowser/upload/' . $config->getPath(false) . "/{$key}", $valueNode); $this->template->setDisplayDataImmediate('upload_binary_action', 'magicDataBrowser/upload_binary/' . $config->getPath(false) . "/{$key}", $valueNode); $this->template->setDisplayDataImmediate('load_action', 'magicDataBrowser/load/' . $config->getPath(false) . "/{$key}", $valueNode); $this->template->setDisplayDataImmediate('erase_action', 'magicDataBrowser/erase/' . $config->getPath(false) . "/{$key}", $valueNode); $this->template->setDisplayDataImmediate('trans_action', 'magicDataBrowser/trans/' . $config->getPath(false) . "/{$key}", $valueNode); $this->template->setDisplayDataImmediate('parent_action', 'magicDataBrowser/parent/' . $config->getPath(false) . "/{$key}", $valueNode); $this->template->setDisplayDataImmediate('scalar_action', 'magicDataBrowser/scalar/' . $config->getPath(false) . "/{$key}", $valueNode); $keys = array(); foreach (I2CE::getConfig()->getKeys("/modules/magicDataBrowser/transforms") as $key) { $keys[$key] = $key; } $this->template->setDisplayDataImmediate('transform_key', $keys, $valueNode); $this->useDropDown(); } else { //echo "weird $key\n"; } } } } $valueNode = $this->template->loadFile("browser_add_node.html", 'li'); if ($valueNode instanceof DOMElement) { $magicNode->appendChild($valueNode); $this->template->setDisplayDataImmediate('add_key_action', 'magicDataBrowser/add/' . $config->getPath(false), $valueNode); $this->template->setDisplayDataImmediate('add_scalar_key_action', 'magicDataBrowser/add_scalar/' . $config->getPath(false), $valueNode); $this->template->setDisplayDataImmediate('add_parent_key_action', 'magicDataBrowser/add_parent/' . $config->getPath(false), $valueNode); } $url_tail = implode('/', $this->config_path); if ($this->get_exists('full')) { $url_tail .= '?full'; } $this->template->setDisplayDataImmediate('caller', $url_tail, $magicNode); }
/** * A path to search for a category of files. * @param string $category the category of files. * @param string $path the parh (or glob pattern for a path) to add. There a a few modifications to the globbing... * A trailing '**' means that the paths should be added recursivley * Paths are automatically checked for localized version by the presence of a 'en_US' subdirectory. * specifically, if a path is added such as /my/path and there is a subdir called /my/path/en_US then * all subdirectories which are in the preffered locales (or $locales below) are added. * * Examples: /usr/share/fonts/ adds in this directory to the search paths * /usr/share/fonts/* adds in all subdirectories * /usr/share/fonts/** recusively adds in all subdirecties * /usr/share/fonts/truetype/ttf* adds in all directories begining with ttf * @param mixed $order. If it is a number, then it indicates the order in which this path is searched. * The lower the number, the higher the priority. * If multiple paths share the same order, the order in which they are searched is not specfied * The are also special string values of $order (all are relative to the category specified): * <ul> * <li>'LAST' -- add at the last added order </li> * <li>'LOWEST' -- add so it has the lowest order thus far </li> * <li>'HIGHEST' -- add so it has the highest order thus far </li> * <li>'EVEN_LOWER' -- add so it has lower order than anything thus far. This is the default behavior </li> * <li>'EVEN_HIGHER' -- add so it has higher order than anything thus far </li> * </ul> * @param boolean $absolut whether or not to try to make a relative path absolut. It will * overide (but not change) the global behaviour of this instance. * @param string $path_prefix. Defaults to null. Any prefix to add to a local class path (if we do make absolute) * @param mixed $locales null(default) , string or array of string. Used to override the default locale settings when not the defaults of null. * It is the list of localized sub-directories to search for, if the given glob is a subdirectory. */ public function addPath($category, $path, $order = 'EVEN_LOWER', $absolut = null, $path_prefix = null, $locales = null) { $path = self::convertPath($path); $path_prefix = self::convertPath($path_prefix); if (!is_string($path) || strlen($path) == 0) { return FALSE; } if ($absolut === null) { $absolut = $this->absolut; } $recurse = false; if (strlen($path) >= 2 && substr($path, strlen($path) - 2) == '**') { $recurse = true; $path = substr($path, 0, -1); } if ($absolut && !$this->isAbsolut($path)) { //relative directorty which we need to change to a absolut directory if ($path_prefix === null || is_string($path_prefix) && strlen($path_prefix) == 0) { $path_prefix = $this->absolut('.' . DIRECTORY_SEPARATOR, 1); } /* see http://us.php.net/manual/en/function.glob.php#86425 for glob and preg_replace */ $path = preg_replace('/(\\*|\\?|\\[)/', '[$1]', $path_prefix) . DIRECTORY_SEPARATOR . $path; } $path = self::convertPath($path, true); if (strlen($path) == 0) { return false; } $t_locales = null; $found_dirs = array(); $globs = array($path => I2CE_Locales::DEFAULT_LOCALE); if (!is_array($locales)) { if (is_string($locales)) { $locales = array($locales); $locales = I2CE_Locales::validateLocales($t_locales); } else { if (array_key_exists($category, $this->preferred_locales) && is_array($this->preferred_locales[$category])) { $locales = $this->preferred_locales[$category]; $locales = I2CE_Locales::validateLocales($locales); } else { $locales = I2CE_Locales::getPreferredLocales(); } } } else { $locales = I2CE_Locales::validateLocales($locales); } while (count($globs) > 0) { end($globs); $glob = key($globs); $locale = array_pop($globs); $dirs = glob($glob, GLOB_ONLYDIR | GLOB_NOSORT); if ($dirs === false) { continue; } foreach ($dirs as $dir) { if ($locale == I2CE_Locales::DEFAULT_LOCALE && is_dir($dir . DIRECTORY_SEPARATOR . I2CE_Locales::DEFAULT_LOCALE . DIRECTORY_SEPARATOR . '.')) { //this directory is localized. foreach ($locales as $t_locale) { $l_dir = $dir . DIRECTORY_SEPARATOR . $t_locale; if (is_dir($l_dir)) { $found_dirs[$l_dir] = $t_locale; if ($recurse) { $globs[preg_replace('/(\\*|\\?|\\[)/', '[$1]', $l_dir) . DIRECTORY_SEPARATOR . '*'] = $t_locale; } } } } else { //this directory is not localized $found_dirs[$dir] = $locale; if ($recurse) { $globs[preg_replace('/(\\*|\\?|\\[)/', '[$1]', $dir) . DIRECTORY_SEPARATOR . '*'] = $locale; } } } } if (count($found_dirs) == 0) { return FALSE; } if (is_string($order)) { if (!array_key_exists($category, $this->ordered_paths) || !is_array($this->ordered_paths[$category]) || count($this->ordered_paths[$category]) == 0) { //nothing added yet. $order = 0; } else { $order = strtoupper($order); switch ($order) { case 'LAST': $order = $this->last_order[$category]; if ($order == null) { //this should not happen but we are being safe $order = 0; } break; case 'LOWEST': $keys = array_keys($this->ordered_paths[$category]); $order = $keys[count($keys) - 1]; break; case 'HIGHEST': $keys = array_keys($this->ordered_paths[$category]); $order = $keys[0]; break; case 'EVEN_HIGHER': $keys = array_keys($this->ordered_paths[$category]); $order = $keys[0] - 1; break; default: // 'EVEN_LOWER' $keys = array_keys($this->ordered_paths[$category]); $order = $keys[count($keys) - 1] + 1; break; } } } else { if (!is_int($order)) { if (class_exists('I2CE', true)) { I2CE::raiseError("Invalid order ({$order}) when setting path ({$path})", E_USER_NOTICE); return FALSE; } else { I2CE::raiseError("Invalid order ({$order}) when setting path ({$path})", E_USER_ERROR); return false; } } } foreach ($found_dirs as $dir => $locale) { $this->ordered_paths[$category][$order][realpath($dir)] = $locale; } ksort($this->ordered_paths[$category]); $this->last_order[$category] = $order; return TRUE; }
/** * construct a swiss swiss factory and create it if it doesn't exist. * @param I2CE_MagicDataNode $storage. The root of the magic data we will be operating on * @param string $swissName. The classname for the root swiss object. * @throws Exception */ public function __construct($page, $options = array()) { $this->child_node_cache = array(); $this->child_node_cache_index = array(); parent::__construct($page); if (!array_key_exists('module', $options) || !$options['module']) { throw new Exception("No modules specified"); } $this->module = $options['module']; $config_file = null; if (!I2CE::getConfig()->setIfIsSet($config_file, "/config/data/{$options['module']}/file")) { throw new Exception("No magic data template found for {$options['module']}"); } $this->configTemplate = new I2CE_MagicDataTemplate(); if (!$this->configTemplate->loadRootFile($config_file)) { throw new Exception("Invalid magic data template found for {$options['module']}"); } $this->xpath = new DOMXPath($this->configTemplate->getDoc()); $this->configNodes = array(); $nodes = $this->xpath->query('/I2CEConfiguration/configurationGroup'); if ($nodes->length != 1) { throw new Exception("No or invalid configuration data for {$options['module']}"); } $this->configNodes['/'] = $nodes->item(0); $this->statii['/'] = $this->configTemplate->getDefaultStatus(); if (!array_key_exists('version', $this->statii['/'])) { if (array_key_exists('version', $options)) { $this->statii['/']['version'] = $options['version']; } else { $this->statii['/']['version'] = 0; } } $file_search = new I2CE_FileSearch(); $mod_factory = I2CE_ModuleFactory::instance(); $mod_factory->loadPaths($this->module, 'CONFIGS', true, $file_search); $translated = $file_search->search('CONFIGS', $config_file, true); $translated_locales = $file_search->getLocaleOfLastSearch(); $preferred_locales = I2CE_Locales::getPreferredLocales(); $this->translatedConfigs = array(); foreach ($preferred_locales as $locale) { if (($index = array_search($locale, $translated_locales)) === false) { continue; } $trans_file = $translated[$index]; $trans_template = new I2CE_MagicDataTemplate(); if (!$trans_template->loadRootFile($trans_file)) { continue; } $this->translatedConfigs[$locale] = $trans_template; } }