Add improved PHP JSON parsing. Add option to add resources.

This commit is contained in:
Lars Jung 2015-05-16 03:03:17 +02:00
parent fe9c7587d8
commit 1995acab95
7 changed files with 130 additions and 33 deletions

View File

@ -21,9 +21,11 @@ class Bootstrap {
(new Api($context))->apply();
} else if ($context->is_info_request()) {
$public_href = $setup->get('PUBLIC_HREF');
$x_head_tags = $context->get_x_head_html();
require __DIR__ . '/pages/info.php';
} else {
$public_href = $setup->get('PUBLIC_HREF');
$x_head_tags = $context->get_x_head_html();
$fallback_html = (new Fallback($context))->get_html();
require __DIR__ . '/pages/index.php';
}

View File

@ -17,7 +17,7 @@ class Context {
$this->request = $request;
$this->setup = $setup;
$this->options = Util::load_commented_json($this->setup->get('APP_PATH') . '/conf/options.json');
$this->options = Json::load($this->setup->get('APP_PATH') . '/conf/options.json');
$this->passhash = $this->query_option('passhash', '');
$this->options['hasCustomPasshash'] = strcasecmp($this->passhash, Context::$DEFAULT_PASSHASH) !== 0;
@ -51,7 +51,7 @@ class Context {
public function get_types() {
return Util::load_commented_json($this->setup->get('APP_PATH') . '/conf/types.json');
return Json::load($this->setup->get('APP_PATH') . '/conf/types.json');
}
public function login_admin($pass) {
@ -222,7 +222,7 @@ class Context {
if ($dir = opendir($l10n_path)) {
while (($file = readdir($dir)) !== false) {
if (Util::ends_with($file, '.json')) {
$translations = Util::load_commented_json($l10n_path . '/' . $file);
$translations = Json::load($l10n_path . '/' . $file);
$langs[basename($file, '.json')] = $translations['lang'];
}
}
@ -239,7 +239,7 @@ class Context {
foreach ($iso_codes as $iso_code) {
$file = $this->setup->get('APP_PATH') . '/conf/l10n/' . $iso_code . '.json';
$results[$iso_code] = Util::load_commented_json($file);
$results[$iso_code] = Json::load($file);
$results[$iso_code]['isoCode'] = $iso_code;
}
@ -257,4 +257,31 @@ class Context {
return $hrefs;
}
private function prefix_x_head_href($href) {
if (preg_match('@^(https?://|/)@i', $href)) {
return $href;
}
return $this->setup->get('PUBLIC_HREF') . 'ext/' . $href;
}
public function get_x_head_html() {
$scripts = $this->query_option('resources.scripts', []);
$styles = $this->query_option('resources.styles', []);
$tags = '';
foreach ($styles as $href) {
$tags .= '<link rel="stylesheet" href="' . $this->prefix_x_head_href($href) . '" class="x-head">';
}
foreach ($scripts as $href) {
$tags .= '<script src="' . $this->prefix_x_head_href($href) . '" class="x-head"></script>';
}
return $tags;
}
}

View File

@ -0,0 +1,71 @@
<?php
class Json {
const SINGLE = 1;
const MULTI = 2;
public static function load($path) {
if (!is_readable($path)) {
return [];
}
$json = file_get_contents($path);
return Json::decode($json);
}
public static function save($path, $obj) {
$json = json_encode($obj);
return file_put_contents($path, $json) !== false;
}
public static function decode($json) {
$json = Json::strip($json);
return json_decode($json, true);
}
public static function strip($commented_json) {
$insideString = false;
$insideComment = false;
$json = '';
for ($i = 0; $i < strlen($commented_json); $i += 1) {
$char = $commented_json[$i];
$charchar = $char . @$commented_json[$i + 1];
$prevChar = @$commented_json[$i - 1];
if (!$insideComment && $char === '"' && $prevChar !== "\\") {
$insideString = !$insideString;
}
if ($insideString) {
$json .= $char;
} else if (!$insideComment && $charchar === '//') {
$insideComment = Json::SINGLE;
$i += 1;
} else if (!$insideComment && $charchar === '/*') {
$insideComment = Json::MULTI;
$i += 1;
} else if (!$insideComment) {
$json .= $char;
} else if ($insideComment === Json::SINGLE && $charchar === "\r\n") {
$insideComment = false;
$json .= $charchar;
$i += 1;
} else if ($insideComment === Json::SINGLE && $char === "\n") {
$insideComment = false;
$json .= $char;
} else if ($insideComment === Json::MULTI && $charchar === '*/') {
$insideComment = false;
$i += 1;
}
}
return $json;
}
}

View File

@ -125,7 +125,7 @@ class Setup {
$cmds_cache_path = Util::normalize_path($this->get('CACHE_PRV_PATH') . '/cmds.json', false);
$cmds = Util::load_commented_json($cmds_cache_path);
$cmds = Json::load($cmds_cache_path);
if (sizeof($cmds) === 0 || $this->refresh) {
$cmds['command'] = Util::exec_0('command -v command');
$cmds['which'] = Util::exec_0('which which');
@ -141,7 +141,7 @@ class Setup {
$cmds[$c] = ($cmd !== false) && Util::exec_0($cmd . ' ' . $c);
}
Util::save_json($cmds_cache_path, $cmds);
Json::save($cmds_cache_path, $cmds);
}
foreach ($cmds as $c => $has) {
$this->set('HAS_CMD_' . strtoupper($c), $has);

View File

@ -61,26 +61,6 @@ class Util {
return Util::RE_DELIMITER . str_replace(Util::RE_DELIMITER, '\\' . Util::RE_DELIMITER, $pattern) . Util::RE_DELIMITER;
}
public static function load_commented_json($path) {
if (!file_exists($path)) {
return [];
}
$content = file_get_contents($path);
// remove comments to get pure json
$content = preg_replace("/\/\*.*?\*\/|\/\/.*?(\n|$)/s", '', $content);
return json_decode($content, true);
}
public static function save_json($path, $obj) {
$json = json_encode($obj);
return file_put_contents($path, $json) !== false;
}
public static function passthru_cmd($cmd) {
$rc = null;

View File

@ -1,5 +1,3 @@
- var public_href = '<?= $public_href; ?>'
block init
<?php header('Content-type: text/html;charset=utf-8'); ?>
@ -13,11 +11,11 @@ head
title #{title}
meta(name='description', content='#{title}')
meta(name='viewport', content='width=device-width, initial-scale=1')
link(rel='shortcut icon', href!='#{public_href}images/favicon/favicon-16-32.ico')
link(rel='apple-touch-icon-precomposed', type='image/png', href!='#{public_href}images/favicon/favicon-152.png')
link(rel='stylesheet', href='//fonts.googleapis.com/css?family=Roboto:300,400,700')
link(rel='stylesheet', href!='#{public_href}css/styles.css')
script(src!='#{public_href}js/scripts.js', data-module='#{module}')
link(rel='shortcut icon', href!='<?= $public_href; ?>images/favicon/favicon-16-32.ico')
link(rel='apple-touch-icon-precomposed', type='image/png', href!='<?= $public_href; ?>images/favicon/favicon-152.png')
link(rel='stylesheet', href!='<?= $public_href; ?>css/styles.css')
script(src!='<?= $public_href; ?>js/scripts.js', data-module='#{module}')
<?= $x_head_tags; ?>
body#root(class='#{module}')

View File

@ -16,6 +16,25 @@ Options
/*
Resources.
Additional script and style tags added to all pages. Paths not beginning
with "http://", "https://" or "/" will be looked up relative to
"_h5ai/public/ext/" (no check for existence).
- scripts: array of strings
- styles: array of strings
*/
"resources": {
"scripts": [],
"styles": [
"//fonts.googleapis.com/css?family=Roboto:300,400,700"
]
},
/*
General view options.