Files
invbrain.neuroinf.jp/etc/fixPicoWraps.php
T
2020-01-06 13:03:45 +09:00

312 lines
12 KiB
PHP

<?php
require_once __DIR__.'/common.inc.php';
if (!isset($XOOPS_MODULE_PICO) || empty($XOOPS_MODULE_PICO)) {
exit('Not configured for pico module'.PHP_EOL);
}
error_reporting(0);
require_once XOOPS_TRUST_PATH.'/modules/pico/include/main_functions.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/include/common_functions.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/include/transact_functions.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/pico.textsanitizer.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoUriMapper.class.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoPermission.class.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoModelCategory.class.php';
require_once XOOPS_TRUST_PATH.'/modules/pico/class/PicoModelContent.class.php';
require_once XOOPS_TRUST_PATH.'/libs/altsys/class/AltsysBreadcrumbs.class.php';
error_reporting(E_ALL);
foreach ($XOOPS_MODULE_PICO as $dirname) {
$pico = new FixPicoWraps($dirname);
if ($pico->isWrapsMode()) {
$pico->fixCategories();
$pico->fixContents();
}
}
class FixPicoWraps
{
private $mDirname;
private $mModule;
private $mModuleConfig;
private $mWrapsPath;
public function __construct($dirname)
{
$this->mDirname = $dirname;
$moduleHandler = xoops_gethandler('module');
$this->mModule = $moduleHandler->getByDirname($dirname);
$moduleConfigHandler = xoops_gethandler('config');
$this->mModuleConfig = $moduleConfigHandler->getConfigsByDirname($dirname);
$this->mWrapsPath = XOOPS_TRUST_PATH.'/wraps/'.$dirname;
}
public function isWrapsMode()
{
$key = 'use_wraps_mode';
return isset($this->mModuleConfig[$key]) && '1' === $this->mModuleConfig[$key];
}
public function getWrapsFiles()
{
exec(sprintf('find "%s" -type f -name "*.html" -o -name "*.htm"', $this->mWrapsPath), $fpaths);
$ret = [];
foreach ($fpaths as $fpath) {
$ret[] = preg_replace('/^'.preg_quote($this->mWrapsPath, '/').'/', '', $fpath);
}
return $ret;
}
public function getWrapsFilesDirectory()
{
$files = $this->getWrapsFiles();
$dirs = array_map('dirname', $files);
$ret = array_unique($dirs);
sort($ret);
return $ret;
}
public function fixCategories()
{
$catVpaths = $this->getWrapsFilesDirectory();
$registeredCatVpaths = ['/' => 0];
$categories = $this->getAllCategories();
foreach ($categories as $category) {
$contents = $category->getContents(true);
$data = $category->getData();
if (empty($contents)) {
// remove empty category.
echo "empty category found. deleting...\n";
$this->deleteCategory($category);
continue;
}
if (null !== $data['cat_vpath']) {
if (!in_array($data['cat_vpath'], $catVpaths)) {
echo 'category vpath not found. '.$data['cat_vpath'].' need to confirm by manual.'."\n";
} else {
$registeredCatVpaths[$data['cat_vpath']] = intval($data['cat_id']);
}
}
}
// register not registered wraps directory.
$notRegisteredCatVpaths = array_diff($catVpaths, array_keys($registeredCatVpaths));
foreach ($notRegisteredCatVpaths as $catVpath) {
$title = basename($catVpath);
$this->createCategory($title, '', 0, $catVpath, 0);
}
// update parent directory
$categories = $this->getAllCategories();
$cmap = ['/' => ['cat_id' => '0', 'cat_vpath' => '/']];
foreach ($categories as $category) {
$data = $category->getData();
if (null !== $data['cat_vpath']) {
$cmap[$data['cat_vpath']] = $data;
}
}
foreach ($cmap as $cvpath => $data) {
if ('0' === $data['cat_id']) {
continue;
}
$pcvpath = dirname($cvpath);
if (!isset($cmap[$pcvpath])) {
echo 'parent category vpath not found: '.$pcvpath.PHP_EOL;
} else {
$pdata = $cmap[$pcvpath];
if ($data['pid'] !== $pdata['cat_id']) {
echo 'parent category id mismatched: '.$data['cat_vpath'].' need to confirm by manual.'."\n";
}
}
}
}
public function fixContents()
{
$wrapFiles = $this->getWrapsFiles();
$foundFiles = [];
foreach ($this->getAllCategories() as $category) {
$cdata = $category->getData();
$cvpath = null === $cdata['cat_vpath'] ? '/' : $cdata['cat_vpath'];
$contents = $category->getContents(true);
foreach ($contents as $content) {
$data = $content->getData4Html();
$vpath = $data['vpath'];
if ($cvpath !== dirname($vpath)) {
echo 'vpath and cat_vpath is not matched..:'.$vpath."\n";
}
$filters = array_map('trim', explode('|', $data['filters']));
if (in_array('wraps', $filters)) {
$fpath = $this->mWrapsPath.$data['vpath'];
if (!file_exists($fpath)) {
echo 'wraps file not found: '.$data['vpath'].PHP_EOL;
}
}
$html = trim($data['body_cached']);
if (0 === strlen($html)) {
echo 'Empty file found: '.$data['vpath'].PHP_EOL;
}
if (in_array($data['vpath'], $wrapFiles)) {
$foundFiles[] = $data['vpath'];
} else {
echo 'Real wraps file not found: '.$data['vpath'].PHP_EOL;
}
if (preg_match('/<script/', $html)) {
echo 'Javascript found : '.$data['vpath'].PHP_EOL;
var_dump($html);
exit();
}
if (preg_match('/onclick=/', $html)) {
echo 'Javascript found : '.$data['vpath'].PHP_EOL;
var_dump($html);
exit();
}
$hasError = false;
$html = $this->checkMlang($html, $hasError);
if ($hasError) {
echo 'mlang error detected: '.$data['vpath'].PHP_EOL;
var_dump($html);
exit();
}
}
}
sort($foundFiles);
$missingFiles = array_diff($wrapFiles, $foundFiles);
if (!empty($missingFiles)) {
echo 'Missing file found: '.implode(', ', $missingFiles).PHP_EOL;
}
}
private function getAllCategories()
{
$permObj = PicoPermission::getInstance();
$perms = $permObj->getPermissions($this->mDirname);
$categoryHandler = new PicoCategoryHandler($this->mDirname, $perms);
return $categoryHandler->getAllCategories(true);
}
private function createCategory($title, $desc, $weight, $vpath, $pid)
{
$db = XoopsDatabaseFactory::getDatabaseConnection();
list($cid) = $db->fetchRow($db->query('SELECT MAX(cat_id)+1 FROM '.$db->prefix($this->mDirname.'_categories')));
list($permId) = $db->fetchRow($db->query('SELECT cat_permission_id FROM '.$db->prefix($this->mDirname.'_categories').' WHERE cat_id='.intval($pid)));
$vars = [
'cat_id' => intval($cid),
'cat_permission_id' => intval($permId),
'cat_vpath' => ('' === $vpath ? 'NULL' : $db->quoteString($vpath)),
'pid' => intval($pid),
'cat_title' => $db->quoteString($title),
'cat_desc' => $db->quoteString($desc),
'cat_path_in_tree' => $db->quoteString(''),
'cat_unique_path' => $db->quoteString(''),
'cat_weight' => intval($weight),
'cat_options' => $db->quoteString(pico_common_serialize([])),
];
$set = [];
foreach ($vars as $key => $value) {
$set[] = sprintf('`%s`=%s', $key, $value);
}
$sql = sprintf('INSERT INTO `%s` SET %s', $db->prefix($this->mDirname.'_categories'), implode(', ', $set));
if (!$db->queryF($sql)) {
var_dump($db);
die(_MD_PICO_ERR_DUPLICATEDVPATH.' or '._MD_PICO_ERR_SQL.__LINE__);
}
pico_sync_cattree($this->mDirname);
echo 'category created: '.$title."\n";
return true;
}
private function deleteCategory($category)
{
global $xoopsModule;
$data = $category->getData();
if (0 == $data['id']) {
echo "cannot delete root(Top) category\n";
return false;
}
if (!empty($data['redundants']['subcattree_raw'])) {
echo "child categories exist\n";
return false;
}
var_dump($data['cat_id'], $data['cat_vpath']);
$backupModule = $xoopsModule;
$xoopsModule = $this->mModule;
pico_delete_category($this->mDirname, $data['cat_id']);
$xoopsModule = $backupModule;
return true;
}
private function checkMlang($text, &$hasError)
{
$hasError = false;
if (!isset($GLOBALS['cubeUtilMlang'])) {
return $text;
}
$errtags = [];
$hls = '<span style="font-weight:bold; color:red">';
$hle = '</span>';
foreach ($GLOBALS['cubeUtilMlang']->mLanguages as $lang) {
$tags = '['.$lang.']';
$tage = '[/'.$lang.']';
$pos = 0;
$is_error = false;
while ($pos < strlen($text)) {
$poss = strpos($text, $tags, $pos);
$pose = strpos($text, $tage, $pos);
if (false === $poss && false === $pose) {
// finished
break;
} elseif (false === $poss && false !== $pose) {
// end tag only found.
$text = substr($text, 0, $pose).$hls.$tage.$hle.substr($text, $pose + strlen($tage));
$is_error = true;
break;
} elseif (false !== $poss && false === $pose) {
// end tag not found.
$text = substr($text, 0, $poss).$hls.$tags.$hle.substr($text, $poss + strlen($tags));
$is_error = true;
break;
}
if ($poss > $pose) {
// end tag found before start tag.
$text = substr($text, 0, $pose).$hls.$tage.$hle.substr($text, $pose + strlen($tage));
$is_error = true;
break;
}
$poss2 = strpos($text, $tags, $poss + strlen($tags));
if (false === $poss2) {
// finished
break;
}
if ($pose > $poss2) {
// next start tag found before end tag
$text = substr($text, 0, $poss2).$hls.$tags.$hle.substr($text, $poss2 + strlen($tags));
$is_error = true;
break;
}
$pos = $pose + strlen($tage);
}
if ($is_error) {
$errtags[] = $lang;
$text = $error.$text;
$text = str_replace([$tags, $tage], ['&lsqb;'.$lang.'&rsqb;', '&lsqb;/'.$lang.'&rsqb;'], $text);
}
}
if (!empty($errtags)) {
$text = '<div class="error">'.$hls.'Unmatched ml tag(s) found: '.implode(', ', $errtags).$hle.'</div>'.$text;
$hasError = true;
}
return $text;
}
}