nimg.neuroinf.jp/etc/dumpStaticPage.php
2022-06-20 17:51:03 +09:00

208 lines
6.3 KiB
PHP

<?php
require_once __DIR__.'/common.inc.php';
require_once __DIR__.'/extras.inc.php';
foreach ($XOOPS_STATIC_PAGES as $page => $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<Props, State> {
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('&#039;', '\'', 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('&', '&amp;', $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('&amp;', '&', $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;
}
}