325 lines
11 KiB
PHP
325 lines
11 KiB
PHP
|
<?php
|
||
|
|
||
|
require_once __DIR__.'/config.inc.php';
|
||
|
|
||
|
define('PROTECTOR_SKIP_DOS_CHECK', 1);
|
||
|
define('PROTECTOR_SKIP_FILESCHECKER', 1);
|
||
|
|
||
|
// disable query logger
|
||
|
define('XOOPS_LOGGER_ADDQUERY_DISABLED', true);
|
||
|
|
||
|
// ----
|
||
|
if (!file_exists($mainfile)) {
|
||
|
echo 'ERROR : mainfile.php not found'.PHP_EOL;
|
||
|
exit(1);
|
||
|
}
|
||
|
$xoops_path = '';
|
||
|
$xoops_url = '';
|
||
|
|
||
|
foreach (file($mainfile) as $line) {
|
||
|
if (preg_match('/^\s*define\s*\(\s*[\'"]XOOPS_ROOT_PATH[\'"]\s*,\s*[\'"](.+)[\'"]\)\s*;\s*$/', $line, $matches)) {
|
||
|
$xoops_path = $matches[1];
|
||
|
}
|
||
|
if (preg_match('/^\s*define\s*\(\s*[\'"]XOOPS_URL[\'"]\s*,\s*[\'"](.+)[\'"]\)\s*;\s*$/', $line, $matches)) {
|
||
|
$xoops_url = $matches[1];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (isset($method) && 'POST' == strtoupper($method)) {
|
||
|
$method = 'POST';
|
||
|
} else {
|
||
|
$method = 'GET';
|
||
|
}
|
||
|
$_SERVER['HTTP_USER_AGENT'] = 'php-cli';
|
||
|
$_SERVER['REQUEST_METHOD'] = $method;
|
||
|
$_ENV['HTTP_REFERER'] = $xoops_url.'/index.php';
|
||
|
$_SERVER['QUERY_STRING'] = '/index.php';
|
||
|
$_SERVER['REMOTE_ADDR'] = '192.168.0.1';
|
||
|
|
||
|
if (file_exists($xoops_path.'/modules/xoonips/include/common.inc.php')) {
|
||
|
require_once $xoops_path.'/modules/xoonips/include/common.inc.php';
|
||
|
} else {
|
||
|
require_once $xoops_path.'/mainfile.php';
|
||
|
require_once $xoops_path.'/modules/xoonips/condefs.php';
|
||
|
require_once $xoops_path.'/modules/xoonips/include/functions.php';
|
||
|
}
|
||
|
|
||
|
if (defined('XOOPS_DB_PROXY') && XOOPS_DB_PROXY == 1 && 'POST' == $method) {
|
||
|
die('Error: not accept POST request'."\n");
|
||
|
}
|
||
|
|
||
|
error_reporting(E_ALL);
|
||
|
|
||
|
// remove ob fileters
|
||
|
while (ob_get_level()) {
|
||
|
ob_end_clean();
|
||
|
}
|
||
|
|
||
|
define('MYDUMPTOOL_OUTPUTDIR', __DIR__.'/data');
|
||
|
MyDumpTool::makeDirectory('');
|
||
|
MyDumpTool::makeDirectory('src');
|
||
|
MyDumpTool::makeDirectory('public');
|
||
|
|
||
|
class MyDumpTool
|
||
|
{
|
||
|
public static function decode(&$data)
|
||
|
{
|
||
|
foreach ($data as $k => $v) {
|
||
|
if (is_string($v)) {
|
||
|
$v = html_entity_decode($v, ENT_QUOTES | ENT_HTML5);
|
||
|
$v = mb_decode_numericentity($v, [0x0, 0x10000, 0, 0xfffff], 'UTF-8');
|
||
|
$data[$k] = \Normalizer::normalize(trim($v), \Normalizer::FORM_C);
|
||
|
} elseif (null === $v) {
|
||
|
$data[$k] = '';
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function convertToInt(&$data, $keys, $zerofill = false)
|
||
|
{
|
||
|
foreach ($keys as $key) {
|
||
|
if (isset($data[$key])) {
|
||
|
$data[$key] = '' === $data[$key] ? ($zerofill ? 0 : null) : (int) $data[$key];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function dropColumn(&$data, $keys)
|
||
|
{
|
||
|
foreach ($keys as $key) {
|
||
|
if (isset($data[$key])) {
|
||
|
unset($data[$key]);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function fileCopy($from, $to)
|
||
|
{
|
||
|
system('rsync -aq '.escapeshellarg($from).' '.escapeshellarg($to), $ret);
|
||
|
|
||
|
return 0 === $ret;
|
||
|
}
|
||
|
|
||
|
public static function fixHtml($text)
|
||
|
{
|
||
|
static $config = [
|
||
|
//'clean' => true,
|
||
|
'hide-comments' => true,
|
||
|
'indent' => true,
|
||
|
'output-xhtml' => true,
|
||
|
'preserve-entities' => true,
|
||
|
'show-body-only' => true,
|
||
|
'drop-proprietary-attributes' => true,
|
||
|
'logical-emphasis' => true,
|
||
|
'wrap' => 0,
|
||
|
'input-encoding' => 'utf8',
|
||
|
'output-encoding' => 'utf8',
|
||
|
'output-bom' => false,
|
||
|
];
|
||
|
$text = tidy_repair_string($text, $config);
|
||
|
$text = preg_replace('/<table([^>]*)>((?:\s*<caption[^>]*>.*<\/caption>)?\s*)<tr([^>]*)>/Us', '<table\1>\2<tbody><tr\3>', $text);
|
||
|
$text = preg_replace('/<\/tr>(\s*)<\/table>/s', '</tr></tbody>\1</table>', $text);
|
||
|
$text = tidy_repair_string($text, $config);
|
||
|
|
||
|
return $text;
|
||
|
}
|
||
|
|
||
|
public static function tableExists($name)
|
||
|
{
|
||
|
global $xoopsDB;
|
||
|
$prefix = $xoopsDB->prefix();
|
||
|
$sql = <<< SQL
|
||
|
SELECT 1
|
||
|
FROM `${prefix}_${name}`
|
||
|
LIMIT 1
|
||
|
SQL;
|
||
|
if (!($res = $xoopsDB->query($sql))) {
|
||
|
return false;
|
||
|
}
|
||
|
$xoopsDB->freeRecordSet($res);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public static function makeDirectory($dirname)
|
||
|
{
|
||
|
$path = MYDUMPTOOL_OUTPUTDIR.('' !== $dirname ? '/'.$dirname : '');
|
||
|
if (!is_dir($path)) {
|
||
|
if (!@mkdir($path, 0755, true)) {
|
||
|
exit('Failed to create directory: '.$path.PHP_EOL);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function saveJson($fname, $data)
|
||
|
{
|
||
|
$path = MYDUMPTOOL_OUTPUTDIR.'/'.$fname;
|
||
|
$data = json_encode($data, JSON_UNESCAPED_UNICODE);
|
||
|
if (false === $data) {
|
||
|
echo json_last_error_msg().PHP_EOL;
|
||
|
exit('Failed to encode json data: '.$path.PHP_EOL);
|
||
|
}
|
||
|
if (false === file_put_contents($path, $data)) {
|
||
|
exit('Failed to save json file: '.$path.PHP_EOL);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function fileDownload($url, $fpath)
|
||
|
{
|
||
|
$fp = fopen($fpath, 'w');
|
||
|
if (false === $fp) {
|
||
|
exit('Failed to open file: '.$fpath.PHP_EOL);
|
||
|
}
|
||
|
$curl = curl_init();
|
||
|
curl_setopt($curl, CURLOPT_URL, $url);
|
||
|
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
|
||
|
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
|
||
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||
|
curl_setopt($curl, CURLOPT_FAILONERROR, true);
|
||
|
curl_setopt($curl, CURLOPT_FILE, $fp);
|
||
|
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
|
||
|
$ret = curl_exec($curl);
|
||
|
fclose($fp);
|
||
|
if (false === $ret) {
|
||
|
unlink($fpath);
|
||
|
echo 'Failed to download file, unexpected error: '.$url.PHP_EOL;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||
|
if (200 !== $code) {
|
||
|
unlink($fpath);
|
||
|
echo 'Failed to download file, invalid status code('.$code.'): '.$url.PHP_EOL;
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
curl_close($curl);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
public static function getMimeType($fpath)
|
||
|
{
|
||
|
$finfo = finfo_open(FILEINFO_MIME);
|
||
|
$mime = finfo_file($finfo, $fpath);
|
||
|
finfo_close($finfo);
|
||
|
$mime = preg_replace('/(;.*)$/', '', $mime);
|
||
|
|
||
|
return $mime;
|
||
|
}
|
||
|
|
||
|
public static function getModule($dirname)
|
||
|
{
|
||
|
$moduleHandler = xoops_gethandler('module');
|
||
|
$moduleObj = $moduleHandler->getByDirname($dirname);
|
||
|
|
||
|
return [
|
||
|
'id' => (int) $moduleObj->get('mid'),
|
||
|
'name' => $moduleObj->get('name'),
|
||
|
'dirname' => $moduleObj->get('dirname'),
|
||
|
'version' => (int) $moduleObj->get('version'),
|
||
|
'lastupdate' => (int) $moduleObj->get('last_update'),
|
||
|
];
|
||
|
}
|
||
|
|
||
|
public static function canModuleRead($dirname, $uid)
|
||
|
{
|
||
|
$moduleHandler = xoops_gethandler('module');
|
||
|
$moduleObj = $moduleHandler->getByDirname($dirname);
|
||
|
$moduleId = (int) $moduleObj->get('mid');
|
||
|
$memberHandler = xoops_gethandler('member');
|
||
|
$groupIds = 0 === $uid ? [XOOPS_GROUP_ANONYMOUS] : $memberHandler->getGroupsByUser($uid);
|
||
|
$groupPermHandler = xoops_gethandler('groupperm');
|
||
|
$ret = $groupPermHandler->checkRight('module_read', $moduleId, $groupIds);
|
||
|
|
||
|
return $ret;
|
||
|
}
|
||
|
|
||
|
public static function mlang($s, $url, $lang)
|
||
|
{
|
||
|
if (!defined('CUBE_UTILS_ML_LANGS')) {
|
||
|
exit('Error: cubeUtils is not loaded'.PHP_EOL);
|
||
|
}
|
||
|
$mLanguage = $lang;
|
||
|
$mLanguages = explode(',', CUBE_UTILS_ML_LANGS);
|
||
|
$mLanguageNames = explode(',', CUBE_UTILS_ML_LANGNAMES);
|
||
|
// escape brackets inside of <input type="text" value="...">
|
||
|
$s = preg_replace_callback('/(\<input)([^>]*)(\>)/isU', 'self::mlang_escapeBracketTextBox', $s);
|
||
|
// escape brackets inside of <textarea></textarea>
|
||
|
$s = preg_replace_callback('/(\<textarea[^>]*\>)(.*)(<\/textarea\>)/isU', 'self::mlang_escapeBracket', $s);
|
||
|
// multilanguage image tag
|
||
|
$langimages = explode(',', CUBE_UTILS_ML_LANGIMAGES);
|
||
|
$langnames = explode(',', CUBE_UTILS_ML_LANGNAMES);
|
||
|
@list($url, $query) = explode('?', $url);
|
||
|
if (empty($query)) {
|
||
|
$link_base = '?'.CUBE_UTILS_ML_PARAM_NAME.'=';
|
||
|
} elseif (false === ($pos = strpos($query, CUBE_UTILS_ML_PARAM_NAME.'='))) {
|
||
|
$link_base = '?'.htmlspecialchars($query, ENT_QUOTES).'&'.CUBE_UTILS_ML_PARAM_NAME.'=';
|
||
|
} elseif ($pos < 2) {
|
||
|
$link_base = '?'.CUBE_UTILS_ML_PARAM_NAME.'=';
|
||
|
} else {
|
||
|
$link_base = '?'.htmlspecialchars(substr($query, 0, $pos - 1), ENT_QUOTES).'&'.CUBE_UTILS_ML_PARAM_NAME.'=';
|
||
|
}
|
||
|
$link_base = $url.$link_base;
|
||
|
$langimage_html = '';
|
||
|
foreach ($mLanguages as $l => $lang) {
|
||
|
$langimage_html .= '<a rel="nofollow" href="'.$link_base.$lang.'"><img src="'.XOOPS_URL.'/'.$langimages[$l].'" alt="flag" title="'.$langnames[$l].'" /></a>';
|
||
|
}
|
||
|
$s = preg_replace('/\['.CUBE_UTILS_ML_IMAGETAG.'\]/', $langimage_html, $s);
|
||
|
|
||
|
$s = preg_replace('/\['.CUBE_UTILS_ML_URLTAG.':([^\]]*?)\]/', $link_base.'$1', $s);
|
||
|
|
||
|
// simple pattern to strip selected lang_tags
|
||
|
$s = preg_replace('/\[(\/)?([^\]]+\|)?'.preg_quote($mLanguage).'(\|[^\]]+)?\](\<br \/\>)?/i', '', $s);
|
||
|
|
||
|
// eliminate description between the other language tags.
|
||
|
foreach ($mLanguages as $lang) {
|
||
|
if ($mLanguage == $lang) {
|
||
|
continue;
|
||
|
}
|
||
|
$s = preg_replace_callback('/\[(?:^\/[^\]]+\|)?'.preg_quote($lang).'(?:\|[^\]]+)?\].*\[\/(?:^\/[^\]]+\|)?'.preg_quote($lang).'(?:\|[^\]]+)?(?:\]\<br \/\>|\])/isU', 'self::mlang_checkNeverCross', $s);
|
||
|
}
|
||
|
|
||
|
// escape brackets inside of <input type="text" value="...">
|
||
|
$s = preg_replace_callback('/(\<input)([^>]*)(\>)/isU', 'self::mlang_unEscapeBracketTextBox', $s);
|
||
|
|
||
|
// escape brackets inside of <textarea></textarea>
|
||
|
$s = preg_replace_callback('/(\<textarea[^>]*\>)(.*)(<\/textarea\>)/isU', 'self::mlang_unEscapeBracket', $s);
|
||
|
|
||
|
return $s;
|
||
|
}
|
||
|
|
||
|
public static function mlang_escapeBracketTextBox($matches)
|
||
|
{
|
||
|
if (preg_match('/type=["\']?(?=text|hidden)["\']?/i', $matches[2])) {
|
||
|
return $matches[1].str_replace('[', '__ml[ml__', $matches[2]).$matches[3];
|
||
|
} else {
|
||
|
return $matches[1].$matches[2].$matches[3];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function mlang_escapeBracket($matches)
|
||
|
{
|
||
|
return $matches[1].str_replace('[', '__ml[ml__', $matches[2]).$matches[3];
|
||
|
}
|
||
|
|
||
|
public static function mlang_unEscapeBracketTextBox($matches)
|
||
|
{
|
||
|
if (preg_match('/type=["\']?(?=text|hidden)["\']?/i', $matches[2])) {
|
||
|
return $matches[1].str_replace('__ml[ml__', '[', $matches[2]).$matches[3];
|
||
|
} else {
|
||
|
return $matches[1].$matches[2].$matches[3];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function mlang_unEscapeBracket($matches)
|
||
|
{
|
||
|
return $matches[1].str_replace('__ml[ml__', '[', $matches[2]).$matches[3];
|
||
|
}
|
||
|
|
||
|
public static function mlang_checkNeverCross($matches)
|
||
|
{
|
||
|
return preg_match(CUBE_UTILS_ML_NEVERCROSSREGEX, $matches[0]) ? $matches[0] : '';
|
||
|
}
|
||
|
}
|