Commit 24691400 authored by Nigel McNie's avatar Nigel McNie
Browse files

Filter all output from views and artefacts to convert links into relative ones for the HTML export.

Uses a new helper class to do the gruntwork, and a lot of preg_replace stuff. It's a little bit hacky perhaps, but it's the simplest thing that could possibly work.
parent 1b281dcc
......@@ -48,7 +48,8 @@ class HtmlExportBlog extends HtmlExportArtefactPlugin {
array('text' => $blog->get('title'), 'path' => 'index.html'),
));
$rendered = $blog->render_self(array());
$smarty->assign('rendered_blog', $rendered['html']);
$outputfilter = new HtmlExportOutputFilter('../../../');
$smarty->assign('rendered_blog', $outputfilter->filter($rendered['html']));
$content = $smarty->fetch('export:html/blog:index.tpl');
if (false === file_put_contents($this->fileroot . $dirname . '/index.html', $content)) {
......@@ -61,7 +62,7 @@ class HtmlExportBlog extends HtmlExportArtefactPlugin {
if ($postcount > $perpage) {
for ($i = 2; $i <= ceil($postcount / $perpage); $i++) {
$rendered = $blog->render_self(array('page' => $i));
$smarty->assign('rendered_blog', $rendered['html']);
$smarty->assign('rendered_blog', $outputfilter->filter($rendered['html']));
$content = $smarty->fetch('export:html/blog:index.tpl');
if (false === file_put_contents($this->fileroot . $dirname . "/{$i}.html", $content)) {
......
......@@ -34,7 +34,8 @@ class HtmlExportInternal extends HtmlExportArtefactPlugin {
// Profile page
$smarty->assign('breadcrumbs', array(array('text' => 'Profile page', 'path' => 'profilepage.html')));
$view = $this->exporter->get('user')->get_profile_view();
$smarty->assign('view', $view->build_columns());
$outputfilter = new HtmlExportOutputFilter('../../');
$smarty->assign('view', $outputfilter->filter($view->build_columns()));
$content = $smarty->fetch('export:html/internal:profilepage.tpl');
if (!file_put_contents($this->fileroot . 'profilepage.html', $content)) {
......
TODOs for export HTML plugin
============================
* blogs - render without javascript
* rewrite all links and images to point to the right places
- blog attachments
- smilies
* views - render in proper structure
* resume display tidyup
* i18n
......
......@@ -177,7 +177,8 @@ class PluginExportHtml extends PluginExport {
throw new SystemException("Could not create directory for view $viewid");
}
$smarty->assign('view', $view->build_columns());
$outputfilter = new HtmlExportOutputFilter('../../');
$smarty->assign('view', $outputfilter->filter($view->build_columns()));
$content = $smarty->fetch('export:html:view.tpl');
if (!file_put_contents("$directory/index.html", $content)) {
throw new SystemException("Could not write view page for view $viewid");
......@@ -264,4 +265,152 @@ abstract class HtmlExportArtefactPlugin {
}
/**
* Provides a mechanism for converting the HTML generated by views and
* artefacts for the HTML export.
*
* Mostly, this means rewriting links to artefacts to point the correct place
* in the export.
*/
class HtmlExportOutputFilter {
/**
* The relative path to the root of the generated export - used for link munging
*/
private $basepath = '';
/**
* A cache of view titles. See replace_view_link()
*/
private $viewtitles = array();
/**
* A cache of folder data. See get_path_for_file()
*/
private $folderdata = null;
/**
* @param string $basepath The relative path to the root of the generated export
*/
public function __construct($basepath) {
$this->basepath = preg_replace('#/$#', '', $basepath);
}
/**
* Filters the given HTML for HTML export purposes
*
* @param string $html The HTML to filter
* @return string The filtered HTML
*/
public function filter($html) {
$wwwroot = preg_quote(get_config('wwwroot'));
$html = preg_replace(
array(
// We don't care about javascript
'#<script[^>]*>.*?</script>#si',
// Fix simlies from tinymce
'#<img src="(' . $wwwroot . ')?/?js/tinymce/plugins/emotions/images/([^"]+)"([^>]+)>#',
),
array(
'',
'<img src="' . $this->basepath . '/static/smilies/$2"$3>',
),
$html
);
// Links to views
$html = preg_replace_callback(
'#' . $wwwroot . 'view/view\.php\?id=(\d+)#',
array($this, 'replace_view_link'),
$html
);
// Links to artefacts
$html = preg_replace_callback(
'#<a[^>]+href="(' . preg_quote(get_config('wwwroot')) . ')?/?view/artefact\.php\?artefact=(\d+)(&amp;view=\d+)?(&amp;page=\d+)?"[^>]*>([^<]*)</a>#',
array($this, 'replace_artefact_link'),
$html
);
// Links to download files
$html = preg_replace_callback(
'#(' . preg_quote(get_config('wwwroot')) . ')?/?artefact/file/download\.php\?file=(\d+)(&amp;view=\d+)?#',
array($this, 'replace_download_link'),
$html
);
return $html;
}
/**
* Callback to replace links to views to point to the correct location in
* the HTML export
*/
private function replace_view_link($matches) {
$viewid = $matches[1];
if (!isset($this->viewtitles[$viewid])) {
$this->viewtitles[$viewid] = PluginExportHtml::text_to_path(get_field('view', 'title', 'id', $viewid));
}
return $this->basepath . '/views/' . $this->viewtitles[$viewid] . '/index.html';
}
/**
* Callback to replace links to artefact to point to the correct location
* in the HTML export
*/
private function replace_artefact_link($matches) {
$artefactid = $matches[2];
$artefact = artefact_instance_from_id($artefactid);
switch ($artefact->get('artefacttype')) {
case 'blog':
$page = ($matches[4]) ? intval(substr($matches[4], strlen('&amp;page='))) : 1;
$page = ($page == 1) ? 'index' : $page;
return '<a href="' . $this->basepath . '/files/blog/' . PluginExportHtml::text_to_path($artefact->get('title')) . '/' . $page . '.html">' . $matches[5] . '</a>';
case 'file':
case 'image':
$folderpath = $this->get_path_for_file($artefact);
return '<a href="' . $this->basepath . '/files/file/' . $folderpath . $artefact->get('title') . '">' . $matches[5] . '</a>';
default:
return $matches[5];
}
}
/**
* Callback to replace links to artefact/file/download.php to point to the
* correct file in the HTML export
*/
private function replace_download_link($matches) {
$artefactid = $matches[2];
$artefact = artefact_instance_from_id($artefactid);
// If artefact type not something that would be served by download.php,
// replace link with nothing
if ($artefact->get_plugin_name() != 'file') {
return '';
}
$folderpath = $this->get_path_for_file($artefact);
return $this->basepath . '/files/file/' . $folderpath . $artefact->get('title');
}
/**
* Given a file, returns the folder path in the HTML export for it
*
* TODO: slash escaping in file/folder names
*
* @param ArtefactTypeFileBase $file The file to get the folder path for
* @return string
*/
private function get_path_for_file(ArtefactTypeFileBase $file) {
if ($this->folderdata === null) {
$this->folderdata = get_records_select_assoc('artefact', "artefacttype = 'folder' AND owner = ?", array($file->get('owner')));
}
$folderpath = ArtefactTypeFileBase::get_full_path($file->get('parent'), $this->folderdata);
return $folderpath;
}
}
?>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment