172 lines
6.4 KiB
PHP
172 lines
6.4 KiB
PHP
<?php
|
|
|
|
global $cfg;
|
|
|
|
// define('SACY_TRANSFORMER_SASS', 1);
|
|
define('SACY_DEBUG_TOGGLE', 'SMARTY_DEBUG');
|
|
define('SACY_QUERY_STRINGS', 'force-handle');
|
|
define('SACY_WRITE_HEADERS', false);
|
|
define('SACY_TRANSFORMER_FONTICONS', '/usr/local/bin/fontcustom');
|
|
|
|
define('ASSET_COMPILE_OUTPUT_DIR', $cfg['Path']['data'].'tmp/cache/');
|
|
define('ASSET_COMPILE_URL_ROOT', '/'.$cfg['Path']['data'].'tmp/cache/');
|
|
|
|
$_SERVER['DOCUMENT_ROOT'] = './';
|
|
|
|
if (!defined('____SACY_BUNDLED')) {
|
|
include_once $cfg['Path']['shared_class'].'sacy/sacy.php';
|
|
include_once $cfg['Path']['shared_class'].'sacy/phpsass.php';
|
|
include_once $cfg['Path']['shared_class'].'sacy/fragment-cache.php';
|
|
}
|
|
|
|
if (!(defined('ASSET_COMPILE_OUTPUT_DIR') && defined('ASSET_COMPILE_URL_ROOT'))) {
|
|
throw new sacy\Exception('Failed to initialize because path configuration is not set (ASSET_COMPILE_OUTPUT_DIR and ASSET_COMPILE_URL_ROOT)');
|
|
}
|
|
|
|
function smarty_block_asset_compile($params, $content, &$template, &$repeat)
|
|
{
|
|
if (!$repeat) {
|
|
// don't shoot me, but all tried using the dom-parser and removing elements
|
|
// ended up with problems due to the annoying DOM API and braindead stuff
|
|
// like no getDocumentElement() or getElementByID() not working even though
|
|
// loadHTML clearly knows that the content is in fact HTML.
|
|
//
|
|
// So, let's go back to good old regexps :-)
|
|
|
|
$cfg = new sacy\Config($params);
|
|
if ($cfg->getDebugMode() == 1) {
|
|
return $content;
|
|
}
|
|
|
|
// Cache whole compile output
|
|
$cache_key = 'sacy-cache-'.md5($content);
|
|
if ($cfg->getDebugMode() == 0) {
|
|
$patched_content = getCache($cache_key);
|
|
|
|
if ($patched_content) {
|
|
return $patched_content;
|
|
}
|
|
}
|
|
|
|
$tag_pattern = '#\s*<\s*T(?:\s+(.*))?\s*(?:/>|>(.*)</T>)\s*#Uims';
|
|
$tags = [];
|
|
|
|
$aindex = 0;
|
|
|
|
// first assembling all work. The idea is that, if sorted by descending
|
|
// location offset, we can selectively remove tags.
|
|
//
|
|
// We'll need that to conditionally handle tags (like jTemplate's
|
|
// <script type="text/html" that should remain)
|
|
foreach (['link', 'style', 'script'] as $tag) {
|
|
$p = str_replace('T', preg_quote($tag), $tag_pattern);
|
|
if (preg_match_all($p, $content, $ms, PREG_OFFSET_CAPTURE)) {
|
|
foreach ($ms[1] as $i => $m) {
|
|
$tags[] = [
|
|
'tag' => $tag,
|
|
'attrdata' => $m[0],
|
|
'index' => $ms[0][$i][1],
|
|
'tagdata' => $ms[0][$i][0],
|
|
'content' => $ms[2][$i][0] ?? null,
|
|
'page_order' => $aindex++,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
// now sort task list by descending location offset
|
|
usort($tags, function ($a, $b) {
|
|
if ($a['index'] == $b['index']) {
|
|
return 0;
|
|
}
|
|
|
|
return ($a['index'] < $b['index']) ? 1 : -1;
|
|
});
|
|
$ex = new sacy\WorkUnitExtractor($cfg);
|
|
$work_units = $ex->getAcceptedWorkUnits($tags);
|
|
|
|
$renderer = new sacy\CacheRenderer($cfg, $_SERVER['SCRIPT_FILENAME']);
|
|
$patched_content = $content;
|
|
|
|
$render = [];
|
|
$category = function ($work_unit) {
|
|
return implode('', [$work_unit['group'], $work_unit['tag'], (bool) $work_unit['file']]);
|
|
};
|
|
$curr_cat = $work_units ? $category($work_units[0]) : null;
|
|
|
|
$entry = null;
|
|
foreach ($work_units as $i => $entry) {
|
|
$cg = $category($entry);
|
|
|
|
// the moment the category changes, render all we have so far
|
|
// this makes it IMPERATIVE to keep links of the same category
|
|
// together.
|
|
if ($curr_cat != $cg || ($cfg->getDebugMode() == 3 && $i > 0 && $renderer->allowMergedTransformOnly($work_units[$i - 1]['tag']) && count($render))) {
|
|
$render_order = array_reverse($render);
|
|
$res = $renderer->renderWorkUnits($work_units[$i - 1]['tag'], $work_units[$i - 1]['group'], $render_order);
|
|
if ($res === false) {
|
|
// rendering failed.
|
|
// because we don't know which one, we just enter emergency mode
|
|
// and return the initial content unharmed:
|
|
return $content;
|
|
}
|
|
// add rendered stuff to patched content
|
|
$m = null;
|
|
foreach ($render as $r) {
|
|
if ($m == null) {
|
|
$m = $r['position'];
|
|
}
|
|
if ($r['position'] < $m) {
|
|
$m = $r['position'];
|
|
}
|
|
// remove tag
|
|
$patched_content = substr_replace($patched_content, '', $r['position'], $r['length']);
|
|
}
|
|
// splice in replacement
|
|
$patched_content = substr_replace($patched_content, $res, $m, 0);
|
|
$curr_cat = $cg;
|
|
$render = [$entry];
|
|
} else {
|
|
$render[] = $entry;
|
|
}
|
|
}
|
|
$render_order = array_reverse($render);
|
|
$res = '';
|
|
if ($work_units) {
|
|
$res = $renderer->renderWorkUnits($entry['tag'], $entry['group'], $render_order);
|
|
if ($res === false) {
|
|
// see last comment
|
|
return $content;
|
|
}
|
|
}
|
|
$m = 0;
|
|
foreach ($render as $r) {
|
|
if ($m == null) {
|
|
$m = $r['position'];
|
|
}
|
|
if ($r['position'] < $m) {
|
|
$m = $r['position'];
|
|
}
|
|
// remove tag
|
|
$patched_content = substr_replace($patched_content, '', $r['position'], $r['length']);
|
|
}
|
|
$patched_content = substr_replace($patched_content, $res, $m, 0);
|
|
|
|
if ($block_ref = $cfg->get('block_ref')) {
|
|
$sacy = $template->smarty->getTemplateVars('sacy') ?: [];
|
|
$rendered_assets = $sacy['rendered_assets'] ?: [];
|
|
$rendered_assets[$block_ref] = array_merge(
|
|
$rendered_assets[$block_ref] ?: [],
|
|
$renderer->getRenderedAssets()
|
|
);
|
|
$sacy['rendered_assets'] = $rendered_assets;
|
|
$template->smarty->assign('sacy', $sacy);
|
|
}
|
|
|
|
// Save content to cache
|
|
setCache($cache_key, $patched_content);
|
|
|
|
return $patched_content;
|
|
}
|
|
}
|