$config) { $data = [ 'en' => StaticFiles::getPage($page, 'en'), 'ja' => StaticFiles::getPage($page, 'ja'), ]; MyDumpTool::makeDirectory(dirname($config['file'])); switch ($config['type']) { case 'json': MyDumpTool::saveJson($config['file'], $data); break; case 'tsx': StaticFiles::saveTsx($config['file'], $data); break; } } class StaticFiles { public static function saveTsx($fname, $data) { $path = MYDUMPTOOL_OUTPUTDIR.'/'.$fname; $cname = basename($fname, '.tsx'); $content_ja = self::makeJsx($data['ja']); $content_en = self::makeJsx($data['en']); $tsx = <<< TSX import React, { Component } from 'react'; import { Link } from 'react-router-dom'; import { MultiLang } from '../config'; import Functions from '../functions'; interface Props { lang: MultiLang; } interface State { isOpen: boolean; } class ${cname} extends Component { constructor(props: Props) { super(props); this.state = { isOpen: false }; } getContent(lang: MultiLang) { const contents = { en: <> ${content_en} , ja: <> ${content_ja} ; } return contents[lang]; } render() { const { lang } = this.props; return this.getContent(lang); } } export default ${cname}; TSX; file_put_contents($path, $tsx); } private static function makeJsx($text) { $text = preg_replace_callback('/<([a-z0-9]+)((?: +[a-z]+(?:="[^"]*")?)*)( *\/?)>/Us', function ($matches) { $tag = $matches[1]; preg_match_all('/ +([a-z]+?)(?:="([^"]*)")??/Us', $matches[2], $out, PREG_SET_ORDER); $attribs = []; foreach ($out as $_out) { $key = $_out[1]; $value = html_entity_decode(trim($_out[2]), ENT_QUOTES | ENT_HTML5); $attribs[$key] = $value; } $styles = []; if (isset($attribs['style'])) { foreach (array_map('trim', explode(';', $attribs['style'])) as $style) { if ('' === $style) { continue; } [$key, $value] = array_map('trim', explode(':', $style)); $key = lcfirst(str_replace(' ', '', ucwords(str_replace('-', ' ', $key)))); $styles[$key] = preg_replace('/ +/U', ' ', $value); } } $close = str_replace('/', ' /', trim($matches[3])); if (isset($attribs['class'])) { $attribs['className'] = $attribs['class']; unset($attribs['class']); } if ('a' === $tag && isset($attribs['target']) && '_blank' === $attribs['target'] && !isset($attribs['rel'])) { $attribs['rel'] = 'noopener noreferrer'; } foreach (['align', 'width', 'height'] as $key) { $kmap = ['align' => 'textAlign']; $skey = isset($kmap[$key]) ? $kmap[$key] : $key; if (isset($attribs[$key])) { $styles[$skey] = $attribs[$key]; unset($attribs[$key]); } } $x = []; foreach ($styles as $key => $style) { $x[] = $key.': "'.$style.'"'; } if (empty($x)) { unset($attribs['style']); } else { $attribs['style'] = '{'.implode(', ', $x).'}'; } $x = ''; foreach ($attribs as $key => $value) { if ('' !== $x) { $x .= ' '; } switch ($key) { case 'style': $x .= $key.'={'.$value.'}'; break; case 'controls': if ('' === $value) { $x .= $key; } break; default: $x .= $key.'="'.str_replace(''', '\'', htmlspecialchars($value, ENT_QUOTES)).'"'; } } if ('' !== $x) { $x = ' '.$x; } return '<'.$tag.$x.$close.'>'; }, $text); return $text; } public static function getPage($page, $lang) { $url = XOOPS_URL.$page; $html = self::fetch($url.(false !== strpos($page, '?') ? '&' : '?').'ml_lang='.$lang); $xml = self::getXml($html, 'content'); return normalizeHtml($xml, $url); } public static function getXml($html, $id) { $text = MyDumpTool::fixHtml($html); $text = str_replace('&', '&', $text); $xml = simplexml_load_string($text); if (false === $xml) { die('failed to load xml: '.$text.PHP_EOL); } $objs = $xml->xpath('//*[@id="'.$id.'"]/*'); if (false === $objs || empty($objs)) { die('failed to find id attribute: '.$id.PHP_EOL); } $ret = ''; foreach ($objs as $obj) { $ret .= $obj->asXml(); } $ret = str_replace('&', '&', $ret); return $ret; } public static function fetch($url) { $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_TIMEOUT, 10); if (isset($GLOBALS['_CURLOPT_RESOLVE_VALUE'])) { curl_setopt($curl, CURLOPT_RESOLVE, $GLOBALS['_CURLOPT_RESOLVE_VALUE']); } $ret = curl_exec($curl); if (false === $ret) { exit('Failed to fetch, unexpected error: '.$url.PHP_EOL); } $code = curl_getinfo($curl, CURLINFO_HTTP_CODE); if (200 !== $code) { exit('Failed to download file, invalid status code('.$code.'): '.$url.PHP_EOL); } curl_close($curl); return $ret; } }