/** * Rebuilds the master 0 skin from the PHP files in /cache/{master_skin_dir}/ * * @access public * @param int Set ID to rebuild from * @return array Array of messages * <code> * Exception Codes: * NOT_MASTER_SKIN: Set ID is not linked to a master skin directory * NO_SUCH_DIR: {master_skin_dir} directory cannot be found * CANNOT_READ: cannot read the {master_skin_dir} directory * </code> */ public function rebuildMasterFromPHP($setId = 0) { //----------------------------------------- // INIT //----------------------------------------- $setId = is_numeric($setId) ? intval($setId) : trim($setId); $script_token = 0; $script_jump = 0; $skin_dir = IPS_CACHE_PATH . "cache/skin_cache/" . $this->remapData['templates'][$setId]; $flag = 0; $messages = array(); $templates = array(); /* Got the master skin dir? */ if (!$this->remapData['templates'][$setId]) { throw new Exception("NOT_MASTER_SKIN"); } if (!is_dir($skin_dir)) { throw new Exception("NO_SUCH_DIR"); } if (!is_readable($skin_dir)) { throw new Exception("CANNOT_READ"); } /* Remove current templates... */ if (is_numeric($setId)) { $this->DB->delete('skin_templates', 'template_set_id=' . $setId); } else { $this->DB->delete('skin_templates', 'template_master_key=\'' . $setId . '\''); } /* Fetch all template bits. NOW */ if (is_numeric($setId) and $setId > 0) { $templates = $this->fetchTemplates($setId, 'allTemplates'); } //----------------------------------------- // Set key and ID //----------------------------------------- $set_id = is_numeric($setId) ? $setId : $this->fetchSetIdByKey($setId); $set_key = ''; if ($this->isMasterSet($setId)) { $set_key = is_numeric($setId) ? $this->fetchSetKeyById($setId) : $setId; } /* Loop through the directory */ try { foreach (new DirectoryIterator($skin_dir) as $file) { if (!$file->isDot() and !$file->isDir()) { $_name = $file->getFileName(); if (substr($_name, -4) == '.php') { $name = substr($_name, 0, -4); $fdata = @file_get_contents($skin_dir . "/" . $_name); if (!$fdata) { $messages[] = sprintf($this->lang->words['couldnotopenfile'], $_name); continue; } $fdata = str_replace("\r", "\n", $fdata); $fdata = str_replace("\n\n", "\n", $fdata); if (!preg_match("/\n/", $fdata)) { $messages[] = sprintf($this->lang->words['couldnotfindlineeol'], $_name); continue; } $farray = explode("\n", $fdata); $functions = array(); $added = 0; $updated = 0; foreach ($farray as $f) { //----------------------------------------- // Skip javascript functions... //----------------------------------------- if (stristr($f, '<script')) { $script_token = 1; $script_jump = 0; } if (stristr($f, '</script>')) { $script_token = 0; $script_jump = 0; } //----------------------------------------- // If, in the middle? //----------------------------------------- if ($script_token and $script_jump == 0) { if (preg_match('#<if test=[\'\\"]#', $f)) { $script_jump = 1; $script_token = 0; } } if ($script_token == 0 and $script_jump == 1) { if (preg_match("#</if>#", $f)) { $script_jump = 0; $script_token = 1; } } //----------------------------------------- // NOT IN JS //----------------------------------------- if (!$script_token) { if (preg_match('/^function\\s*([\\w\\_]+)\\s*\\((.*)\\)/i', $f, $matches)) { $functions[$matches[1]] = ''; $config[$matches[1]] = $matches[2]; $flag = $matches[1]; continue; } } else { # Make JS safe (UBE - Ugly, but effective) $f = preg_replace('#if\\s+?\\(#is', "i~f~(~", $f); $f = str_ireplace('else', "e~lse~", $f); $f = preg_replace('#else\\s+?if#is', "e~lse~i~f", $f); } if ($flag) { $functions[$flag] .= $f . "\n"; continue; } } $final = ""; $flag = 0; foreach ($functions as $fname => $ftext) { preg_match("#//--starthtml--//(.+?)//--endhtml--//#s", $ftext, $matches); $content = $this->registry->templateEngine->convertPhpToHtml($matches[1]); //----------------------------------------- // Unconvert JS //----------------------------------------- $content = str_replace("i~f~(~", "if (", $content); $content = str_replace("e~lse~", "else", $content); $content = str_replace("e~lse~i~f", "else if", $content); /* Encode */ $content = IPSText::encodeForXml($content); /* Build array */ $array = array('template_set_id' => $set_id, 'template_group' => $name, 'template_content' => $content, 'template_name' => $fname, 'template_data' => trim($config[$fname]), 'template_updated' => time(), 'template_removable' => (is_numeric($setId) and $setId) ? 1 : 0, 'template_master_key' => $set_key, 'template_added_to' => $set_id); if (!$setId) { $added++; /* All new bits go to 'master' skin */ $array['template_set_id'] = 0; $array['template_added_to'] = 0; $array['template_master_key'] = 'root'; $this->DB->insert('skin_templates', $array); } else { /* Compare for changes? */ if (IPSText::contentToMd5($templates[$name][strtolower($fname)]['template_content']) != IPSText::contentToMd5($content)) { /* It's changed, so update. We create a new row as it might be inherited */ $updated++; $this->DB->insert('skin_templates', $array); } } } $messages[] = sprintf($this->lang->words['tplbitimported'], $name, $added, $updated); $functions = array(); } } } } catch (Exception $e) { } /* Recache */ if (is_numeric($setId) and $setId) { $this->rebuildPHPTemplates($setId); $this->removeDeadPHPCaches($setId); $this->cache->putWithCacheLib('Skin_Store_' . $setId, array(), 1); } if ($set_key == 'mobile') { $this->rebuildMobileSkinUserAgentsFromSetDataXml(); } /* Return */ $messages[] = $this->lang->words['cpltrebuildfromcaches']; return $messages; }
/** * Builds the language db entries from cache * * @param boolean return as normal * @return @e void * @author Josh */ public function importFromCacheFiles($returnAsNormal = TRUE) { //----------------------------------------- // INIT //----------------------------------------- $msg = array(); $lang_id = 1; $LATESTVERSION = IPSLib::fetchVersionNumber(); //----------------------------------------- // Check //----------------------------------------- if (!is_array($_POST['apps'])) { $this->registry->output->global_message = $this->lang->words['l_noapp']; $this->languagesList(); return; } //----------------------------------------- // Loop through apps... //----------------------------------------- foreach (ipsRegistry::$applications as $app => $app_data) { if (in_array($app, $_POST['apps'])) { //----------------------------------------- // Get directory //----------------------------------------- $_dir = IPS_CACHE_PATH . 'cache/lang_cache/master_lang/'; //----------------------------------------- // Go through directories //----------------------------------------- if (is_dir($_dir)) { $dh = opendir($_dir); while ($f = readdir($dh)) { if ($f[0] == '.' || $f == 'index.html') { continue; } if (preg_match("#^" . $app . '_\\S+?\\.php$#', $f)) { //----------------------------------------- // INIT //----------------------------------------- $updated = 0; $inserted = 0; $word_pack = preg_replace("#^" . $app . '_(\\S+?)\\.php$#', "\\1", $f); $lang = array(); $db_lang = array(); //----------------------------------------- // Delete current language bits //----------------------------------------- $this->DB->delete('core_sys_lang_words', "lang_id=1 AND word_app='" . $app . "' AND word_pack='" . $word_pack . "'"); if (IPS_IS_SHELL) { $stdout = fopen('php://stdout', 'w'); fwrite($stdout, 'Processing: ' . $f . "\n"); fclose($stdout); } require $_dir . $f; /*noLibHook*/ //----------------------------------------- // Loop //----------------------------------------- foreach ($lang as $k => $v) { $inserted++; $insert = array('lang_id' => $lang_id, 'word_app' => $app, 'word_pack' => $word_pack, 'word_key' => $k, 'word_default' => IPSText::encodeForXml($v), 'word_default_version' => $LATESTVERSION['long'], 'word_js' => 0); $this->DB->insert('core_sys_lang_words', $insert); } $msg[] = sprintf($this->lang->words['indev_lang_import'], $f, $inserted, $updated); } else { if (preg_match('/(\\.js)$/', $f) and $app == 'core') { $_js_word_pack = ''; if ($f == 'ipb.lang.js') { $_js_word_pack = 'public_js'; } else { if ($f == 'acp.lang.js') { $_js_word_pack = 'admin_js'; } } //----------------------------------------- // Delete current words for this app and word pack //----------------------------------------- $this->DB->delete('core_sys_lang_words', "lang_id=1 AND word_app='" . $app . "' AND word_pack='" . $_js_word_pack . "'"); if (IPS_IS_SHELL) { $stdout = fopen('php://stdout', 'w'); fwrite($stdout, 'Processing: ' . $f . "\n"); fclose($stdout); } //----------------------------------------- // Get each line //----------------------------------------- $js_file = file($_dir . $f); //----------------------------------------- // Loop through lines and import //----------------------------------------- foreach ($js_file as $r) { //----------------------------------------- // preg_match what we want //----------------------------------------- preg_match('#ipb\\.lang\\[\'(.+?)\'\\](.+?)= ["\'](.+?)["\'];#', $r, $matches); //----------------------------------------- // Valid? //----------------------------------------- if ($matches[1] && $matches[3]) { $inserted++; $insert = array('lang_id' => $lang_id, 'word_app' => 'core', 'word_pack' => $_js_word_pack, 'word_key' => $matches[1], 'word_default' => IPSText::encodeForXml($matches[3]), 'word_js' => 1); $this->DB->insert('core_sys_lang_words', $insert); } } } } } closedir($dh); } } } //----------------------------------------- // Done... //----------------------------------------- if ($returnAsNormal === TRUE) { $this->registry->output->setMessage(implode("<br />", $msg), true); if (!$this->__daily) { $this->languagesList(); } } else { return $msg; } }
/** * Rebuilds the master 0 skin from the PHP files in /cache/{master_skin_dir}/ * * @access public * @param int Set ID to rebuild from * @return array Array of messages * <code> * Exception Codes: * NOT_MASTER_SKIN: Set ID is not linked to a master skin directory * NO_SUCH_DIR: {master_skin_dir} directory cannot be found * CANNOT_READ: cannot read the {master_skin_dir} directory * </code> */ public function rebuildMasterFromPHP($setId = 0) { //----------------------------------------- // INIT //----------------------------------------- $setId = intval($setId); $script_token = 0; $script_jump = 0; $skin_dir = IPS_CACHE_PATH . "cache/skin_cache/" . $this->remapData['templates'][$setId]; $flag = 0; $messages = array(); $templates = array(); /* Got the master skin dir? */ if (!$this->remapData['templates'][$setId]) { throw new Exception("NOT_MASTER_SKIN"); } if (!file_exists($skin_dir)) { throw new Exception("NO_SUCH_DIR"); } if (!is_readable($skin_dir)) { throw new Exception("CANNOT_READ"); } /* Remove current templates... */ $this->DB->delete('skin_templates', 'template_set_id=' . $setId); /* Fetch all template bits. NOW */ if ($setId > 0) { $templates = $this->fetchTemplates($setId, 'allTemplates'); } /* Loop through the directory */ try { foreach (new DirectoryIterator($skin_dir) as $file) { if (!$file->isDot() and !$file->isDir()) { $_name = $file->getFileName(); if (substr($_name, -4) == '.php') { $name = substr($_name, 0, -4); $fdata = @file_get_contents($skin_dir . "/" . $_name); if (!$fdata) { $messages[] = "Could not open {$_name} for reading, skipping file..."; continue; } $fdata = str_replace("\r", "\n", $fdata); $fdata = str_replace("\n\n", "\n", $fdata); if (!preg_match("/\n/", $fdata)) { $messages[] = "Could not find any line endings in {$_name}, skipping file..."; continue; } $farray = explode("\n", $fdata); $functions = array(); $added = 0; $updated = 0; foreach ($farray as $f) { //----------------------------------------- // Skip javascript functions... //----------------------------------------- if (stristr($f, '<script')) { $script_token = 1; $script_jump = 0; } if (stristr($f, '</script>')) { $script_token = 0; $script_jump = 0; } //----------------------------------------- // If, in the middle? //----------------------------------------- if ($script_token and $script_jump == 0) { if (preg_match("#<if test=[\\'\"]#", $f)) { $script_jump = 1; $script_token = 0; } } if ($script_token == 0 and $script_jump == 1) { if (preg_match("#</if>#", $f)) { $script_jump = 0; $script_token = 1; } } //----------------------------------------- // NOT IN JS //----------------------------------------- if (!$script_token) { if (preg_match("/^function\\s*([\\w\\_]+)\\s*\\((.*)\\)/i", $f, $matches)) { $functions[$matches[1]] = ''; $config[$matches[1]] = $matches[2]; $flag = $matches[1]; continue; } } else { # Make JS safe (UBE - Ugly, but effective) $f = preg_replace("#if\\s+?\\(#is", "i~f~(~", $f); $f = str_ireplace("else", "e~lse~", $f); $f = preg_replace("#else\\s+?if#is", "e~lse~i~f", $f); } if ($flag) { $functions[$flag] .= $f . "\n"; continue; } } $final = ""; $flag = 0; foreach ($functions as $fname => $ftext) { preg_match("#//--starthtml--//(.+?)//--endhtml--//#s", $ftext, $matches); $content = $this->registry->templateEngine->convertPhpToHtml($matches[1]); //----------------------------------------- // Unconvert JS //----------------------------------------- $content = str_replace("i~f~(~", "if (", $content); $content = str_replace("e~lse~", "else", $content); $content = str_replace("e~lse~i~f", "else if", $content); /* Encode */ $content = IPSText::encodeForXml($content); /* Build array */ $array = array('template_set_id' => $setId, 'template_group' => $name, 'template_content' => $content, 'template_name' => $fname, 'template_data' => trim($config[$fname]), 'template_updated' => time(), 'template_removable' => $setId ? 1 : 0, 'template_added_to' => $setId); if (!$setId or !$templates[$name][strtolower($fname)]) { $added++; /* All new bits go to 'master' skin */ $array['template_set_id'] = 0; $array['template_added_to'] = 0; $this->DB->insert('skin_templates', $array); } else { /* Compare for changes? */ if (IPSText::contentToMd5($templates[$name][strtolower($fname)]['template_content']) != IPSText::contentToMd5($content)) { /* It's changed, so update. We create a new row as it might be inherited */ $updated++; $this->DB->insert('skin_templates', $array); } } } $messages[] = "{$name} imported (Added " . $added . "; updated " . $updated . " template bits)"; $functions = array(); } } } } catch (Exception $e) { } /* Recache */ if ($setId) { $this->rebuildPHPTemplates($setId); $this->removeDeadPHPCaches($setId); } /* Return */ $messages[] = "Completed database rebuild from PHP cache files."; return $messages; }