Commit e6b6ecf9 authored by Lisa Seeto's avatar Lisa Seeto

Bug 1827811: Exports task

This change creates the modals for exported html pages.
Modals are hard-coded onto page with id's of modal_[artefactid]
Bootstrap and jquery files are copied into export js folder.
Profile page is also exported with any modal content.
Add tagged posts modals
get rid of export warning when no $commentcount set in viewposts.tpl
Add recent posts modals so that first journal post was also a modal
Set Parent journal link text to plain text for exports
Add entire resume modals and one resume field modals
Add File(s) to download modals
refactor export_artefact_metadata_modals
add metadata but not comments to resume page
add metata (license info) but not comments to journal pages
add comment count default to 0 in .tpl's if comment count not present (during export)
remove updating comments modals for profile page as this is no longer needed.

Change-Id: Iff50138285951a4f9a1573423f4f74feba97886f
Signed-off-by: default avatarLisa Seeto <lisaseeto@catalyst.net.nz>
parent 1885a18d
......@@ -37,6 +37,7 @@ class HtmlExportBlog extends HtmlExportArtefactPlugin {
public function get_summary() {
$smarty = $this->exporter->get_smarty();
$blogs = array();
foreach ($this->exporter->get('artefacts') as $artefact) {
if ($artefact->get('artefacttype') == 'blog') {
$blogs[] = array(
......
......@@ -2492,7 +2492,7 @@ class ArtefactTypeImage extends ArtefactTypeFile {
$smarty->assign('title', $this->get('title'));
$smarty->assign('description', $this->get('description'));
$smarty->assign('downloadpath', $downloadpath);
$smarty->assign('metadataurl', $metadataurl);
// $smarty->assign('metadataurl', $metadataurl);
return array('html' => $smarty->fetch('artefact:file:image_render_self.tpl'), 'javascript' => '');
}
$result = parent::render_self($options);
......
......@@ -106,8 +106,7 @@ class PluginBlocktypePlans extends MaharaCoreBlocktype {
$configdata['versioning'] = $versioning;
ArtefactTypeTask::render_tasks($tasks, $template, $configdata, $pagination, $editing, $versioning);
if (($exporter || $versioning) && $tasks['count'] > $tasks['limit']) {
$artefacturl = get_config('wwwroot') . 'artefact/artefact.php?artefact=' . $planid
. '&view=' . $instance->get('view');
$artefacturl = get_config('wwwroot') . 'view/view.php?id=' . $instance->get('view') .'&modal=1&artefact=' . $planid;
$tasks['pagination'] = '<a href="' . $artefacturl . '">' . get_string('alltasks', 'artefact.plans') . '</a>';
}
if ($versioning) {
......
......@@ -29,6 +29,17 @@ class HtmlExportResume extends HtmlExportArtefactPlugin {
array('text' => get_string('resume', 'artefact.resume'), 'path' => 'index.html'),
));
$attachmentids = array();
$exportedmodals = '';
$options = array(
'details' => true,
'metadata' => 1,
'modal' => true,
);
require_once(get_config('docroot') . 'export/html/lib.php');
$rootpath = '../../';
$outputfilter = new HtmlExportOutputFilter($rootpath, $this->exporter);
if ($artefacts = get_column_sql("SELECT id
FROM {artefact}
WHERE \"owner\" = ?
......@@ -38,10 +49,33 @@ class HtmlExportResume extends HtmlExportArtefactPlugin {
foreach ($artefacts as $id) {
$artefact = artefact_instance_from_id($id);
$rendered = $artefact->render_self(array());
$attachments = $artefact->get_attachments();
if (!empty($attachments)) {
foreach ($attachments as $file) {
if (!in_array($file->{'id'}, $attachmentids)) {
array_push($attachmentids, $file->{'id'});
$html = '';
$a = artefact_instance_from_id($file->{'id'});
$modalcontent = $a->render_self($options);
if (!empty($modalcontent['javascript'])) {
$html = '<script>' . $modalcontent['javascript'] . '</script>';
}
$html .= $modalcontent['html'];
$smarty->assign('artefactid', $file->{'id'});
$smarty->assign('content', $html);
$smarty->assign('title', $a->get('title'));
$exportedmodals .= $smarty->fetch('export:html:modal.tpl');
}
}
}
$content = $outputfilter->filter($rendered['html']);
$smarty->assign($artefact->get('artefacttype'), $rendered['html']);
}
}
$content = $smarty->fetch('export:html/resume:index.tpl');
$exportedmodals = $outputfilter->filter($exportedmodals);
$content .= $exportedmodals;
if (false === file_put_contents($this->fileroot . 'index.html', $content)) {
throw new SystemException("Unable to create index.html for resume");
......
......@@ -47,6 +47,12 @@ class PluginExportHtml extends PluginExport {
*/
protected $exportingoneview = false;
/**
* These javascript files will be included in index.html via the
* export/html/templates/header.tpl
*/
private $scripts = array('jquery', 'bootstrap.min', 'dock', 'modal');
/**
* constructor. overrides the parent class
* to set up smarty and the attachment directory
......@@ -200,6 +206,8 @@ class PluginExportHtml extends PluginExport {
$this->notify_progress_callback(55, get_string('exportingviews', 'export'));
$this->dump_view_export_data();
$this->export_artefact_metadata_modals();
if (!$this->exportingoneview) {
$viewcollectionsumary = $this->get_view_collection_summary();
$summaries['view'] = array(100, $viewcollectionsumary['view']);
......@@ -259,12 +267,15 @@ class PluginExportHtml extends PluginExport {
else {
$stylesheets = $this->stylesheets[''];
}
$smarty = smarty_core();
$smarty->assign('user', $this->get('user'));
$smarty->assign('rootpath', $rootpath);
$smarty->assign('export_time', $this->exporttime);
$smarty->assign('sitename', get_config('sitename'));
$smarty->assign('stylesheets', $stylesheets);
$smarty->assign('scripts', $this->scripts);
$smarty->assign('scriptspath', $rootpath . $this->theme_path('js/'));
$smarty->assign('maharalogo', $rootpath . $this->theme_path('images/site-logo.png'));
return $smarty;
......@@ -502,6 +513,239 @@ class PluginExportHtml extends PluginExport {
return $summary;
}
/** Retrieves the comments for a particular artefact
* @param artefact $artefact The artefact containing the comments
* @param View $view The view where the artefact appears
* @return html via comment.tpl Containing comments or '' if comments aren't allowed
*/
private function get_comments_for_modal($artefact, $view) {
safe_require('artefact', 'comment');
if (!$artefact->get('allowcomments')) {
return '';
}
$commentoptions = ArtefactTypeComment::get_comment_options();
$commentoptions->view = $view;
$commentoptions->artefact = $artefact;
$owner = $artefact->get('owner');
$threaded = $owner ? $threaded = get_user_institution_comment_threads($owner) : false;
$commentoptions->threaded = $threaded;
$feedback = ArtefactTypeComment::get_comments($commentoptions);
$smarty = smarty_core();
$smarty->assign('feedback', $feedback);
return $smarty->fetch('blocktype:comment:comment.tpl');
}
/**
* Creates the hard-coded modals for blogs posts (Journal block)
* @param BlockInstance $bi The journal block containing the posts
* @param array &$idarray Existing array that stores ids of modals to be created
*/
private function get_blog_posts_modals(&$idarray, BlockInstance $bi) {
require_once(get_config('docroot') . 'artefact/blog/blocktype/blog/lib.php');
$artefacts = PluginBlocktypeBlog::get_artefacts($bi);
if (!empty($artefacts)) {
$idarray = array_merge($idarray, $artefacts);
}
}
/**
* Creates the hard-coded modals for tagged posts (Tagged journal entries)
* @param BlockInstance $bi The tagged journal entries block containing the posts
* @param array &$idarray Existing array that stores ids of modals to be created
*/
private function get_tagged_posts_modals(&$idarray, BlockInstance $bi) {
require_once(get_config('docroot') . 'artefact/blog/blocktype/taggedposts/lib.php');
$taggedposts = PluginBlocktypeTaggedposts::get_blog_posts_in_block($bi);
$postids = array();
foreach ($taggedposts as $posts) {
array_push($postids, $posts->{'id'});
}
if (!empty($postids)) {
$idarray = array_merge($idarray, $postids);
}
}
/**
* Creates the hard-coded modals for recent posts (Recent journal entries)
* @param BlockInstance $bi The recent journal entries block containing the posts
* @param array &$idarray Exisiting array that stores ids of modals to be created
*/
private function get_recent_posts_modals(&$idarray, BlockInstance $bi) {
require_once(get_config('docroot') . 'artefact/blog/blocktype/recentposts/lib.php');
$recentposts = PluginBlocktypeRecentposts::get_blog_posts_in_block($bi);
$recentpostsids = array();
foreach ($recentposts as $rpids) {
array_push($recentpostsids, $rpids->{'id'});
}
if (!empty($recentpostsids)) {
$idarray = array_merge($idarray, $recentpostsids);
}
}
/**
* Creates the hard-coded modals for all attachments in the entire resume block
* @param BlockInstance $bi The entire resume block containing the attachments
* @param array &$idarray The exisiting array that stores modal ids to be created
*/
private function get_entire_resume_modals(&$idarray, BlockInstance $bi) {
require_once(get_config('docroot') . 'artefact/resume/blocktype/entireresume/lib.php');
$resume = PluginBlocktypeEntireresume::get_artefacts($bi);
$attachmentids = array();
foreach ($resume as $field) {
$res = $bi->get_artefact_instance($field);
if ($attachment = $res->get_attachments()) {
foreach ($attachment as $a) {
array_push($attachmentids, $a->{'id'});
}
}
}
if (!empty($attachmentids)) {
$idarray = array_merge($idarray, $attachmentids);
}
}
/**
* Creates the hard-coded modals for all attachments in the one resume field block
* @param BlockInstance $bi The resume field block containing the attachments
* @param array &$idarray The exisiting array that stores modal ids to be created
*/
private function get_resume_field_modals(&$idarray, BlockInstance $bi) {
$configdata = $bi->get('configdata');
$field = $bi->get_artefact_instance($configdata['artefactid']);
$attachmentids = array();
if ($attachment = $field->get_attachments()) {
foreach ($attachment as $a) {
array_push($attachmentids, $a->{'id'});
}
}
if (!empty($attachmentids)) {
$idarray = array_merge($idarray, $attachmentids);
}
}
/**
* Creates the hard-coded modals for File(s) to download block
* @param BlockInstance $bi The File(s) to download block
* @param array &$idarray The exisiting array that stores modal ids to be created
*/
private function get_folder_modals(&$idarray, BlockInstance $bi) {
require_once(get_config('docroot') . 'artefact/resume/blocktype/entireresume/lib.php');
$artefacts = PluginBlocktypeFolder::get_current_artefacts($bi);
if (!empty($artefacts)) {
$idarray = array_merge($idarray, $artefacts);
}
}
/**
* Exports the hard-coded modals for the blocks into relevant pages.
* This will append to the index.html or any other relevant page created
* previously that needs to contain a modal (including the profile page).
*/
private function export_artefact_metadata_modals() {
foreach ($this->views as $view) {
$content = '';
$blocks = get_records_array('block_instance', 'view', $view->get('id'));
if ($blocks) {
$options = array(
'viewid' => $view->get('id'),
'details' => true,
'metadata' => 1,
'modal' => true,
);
$uniqueids = array();
$smarty = $this->get_smarty();
foreach ($blocks as $b) {
$bi = new BlockInstance($b->id);
$type = $bi->get('artefactplugin');
$configdata = unserialize($b->configdata);
$artefactidarray = array();
if ($b->blocktype == 'blog') {
$this->get_blog_posts_modals($artefactidarray, $bi);
}
else if ($b->blocktype == 'recentposts') {
$this->get_recent_posts_modals($artefactidarray, $bi);
}
else if ($b->blocktype == 'taggedposts') {
$this->get_tagged_posts_modals($artefactidarray, $bi);
}
else if ($b->blocktype == 'entireresume') {
$this->get_entire_resume_modals($artefactidarray, $bi);
}
else if ($b->blocktype == 'resumefield') {
$this->get_resume_field_modals($artefactidarray, $bi);
}
else if ($b->blocktype == 'folder') {
$this->get_folder_modals($artefactidarray, $bi);
}
else if (
//block contains any of these types or matches blocktype
$type == 'image' ||
$type == 'blog' ||
$type == 'audio' ||
$type == 'video' ||
$type == 'html' ||
$type == 'plans' ||
$type == 'internal' && $b->blocktype != 'profileinfo'||
$b->blocktype == 'image' ||
$b->blocktype == 'filedownload'
) {
if (isset($configdata['artefactids']) && !empty($configdata['artefactids'])) {
$artefactidarray = $configdata['artefactids'];
}
else if (isset($configdata['artefactid']) && !empty($configdata['artefactid'])) {
$artefactidarray = array($configdata['artefactid']);
}
}
//Create the modal content for each unique id found
if (!empty($artefactidarray)) {
foreach ($artefactidarray as $artefactid) {
//prevent duplicate modals in same page
if (!in_array($artefactid, $uniqueids)) {
array_push($uniqueids, $artefactid);
$artefact = $bi->get_artefact_instance($artefactid);
$options['blockid'] = $b->id;
$rendered = $artefact->render_self($options);
$html = '';
if (!empty($rendered['javascript'])) {
$html = '<script>' . $rendered['javascript'] . '</script>';
}
$html .= $rendered['html'];
$html .= $this->get_comments_for_modal($artefact, $view);
$smarty->assign('artefactid', $artefactid);
$smarty->assign('content', $html);
$smarty->assign('title', $artefact->get('title'));
$content .= $smarty->fetch('export:html:modal.tpl');
}
}
} #end of if
} #end of foreach block
} #end of if
if (!empty($content)) {
$rootpath = ($this->exportingoneview) ? './' : '../../';
$outputfilter = new HtmlExportOutputFilter($rootpath, $this);
$content = $outputfilter->filter($content);
if ($this->exportingoneview) {
if (!file_put_contents($this->exportdir . '/' . $this->rootdir . '/index.html', $content, FILE_APPEND)) {
throw new SystemException("Could not create artefact metadata for the export");
}
}
else {
$folder = '';
if ($view->get('type') != 'profile') {
$folder = self::text_to_filename($view->get('title'));
if (!file_put_contents($this->exportdir . '/' . $this->rootdir . '/views/' . $folder . '/index.html', $content, FILE_APPEND)) {
throw new SystemException("Could not create artefact metadata for the export");
}
}
}
}#end of if
} #end of foreach view
}
/**
* Copies the static files (stylesheets etc.) into the export
*/
......@@ -541,6 +785,11 @@ class PluginExportHtml extends PluginExport {
// Smilies
$directoriestocopy[get_config('docroot') . 'js/tinymce/plugins/emoticons/img'] = $staticdir . 'smilies/';
// Copy over bootstrap and jquery files
$jsdir = $staticdir . 'theme/' . $theme . '/static/js/';
$directoriestocopy[get_config('docroot') . 'lib/bootstrap/assets/javascripts/bootstrap.min.js'] = $jsdir . 'bootstrap.min.js';
$directoriestocopy[get_config('docroot') . 'js/jquery/jquery.js'] = $jsdir . 'jquery.js';
foreach ($this->pluginstaticdirs as $dir) {
$destinationdir = str_replace('export/html/', '', $dir);
if (!check_dir_exists($staticdir . $destinationdir)) {
......@@ -560,7 +809,6 @@ class PluginExportHtml extends PluginExport {
}
}
}
abstract class HtmlExportArtefactPlugin {
......@@ -607,10 +855,51 @@ abstract class HtmlExportArtefactPlugin {
array('text' => $artefact->get('title'), 'path' => 'index.html'),
));
$rendered = $artefact->render_self(array('hidetitle' => true));
$outputfilter = new HtmlExportOutputFilter('../../../', $this->exporter);
$smarty->assign('rendered', $outputfilter->filter($rendered['html']));
$content = $smarty->fetch('export:html:page.tpl');
if ($artefact instanceof ArtefactTypeBlog && get_config('licensemetadata')) {
$blogid = $artefact->get('id');
$idarray = array();
$exportedmodals = '';
$renderoptions = array(
'details' => true,
'metadata' => 1,
'modal' => true,
);
require_once(get_config('docroot') . 'artefact/blog/lib.php');
$from = "
FROM {artefact} a LEFT JOIN {artefact_blog_blogpost} bp ON a.id = bp.blogpost
WHERE a.artefacttype = 'blogpost' AND a.parent = ?";
$from .= ' AND bp.published = 1';
$count = count_records_sql('SELECT COUNT(*) ' . $from, array($blogid));
$posts = ArtefactTypeBlogPost::get_posts($blogid, $count ? $count : 10, 0);
if ($posts['data']) {
foreach ($posts['data'] as $pid) {
array_push($idarray, $pid->{'id'});
}
}
if (!empty($idarray)) {
foreach ($idarray as $id) {
$html = '';
$a = artefact_instance_from_id($id);
$modalcontent = $a->render_self($renderoptions);
if (!empty($modalcontent['javascript'])) {
$html = '<script>' . $modalcontent['javascript'] . '</script>';
}
$html .= $modalcontent['html'];
$smarty->assign('artefactid', $id);
$smarty->assign('content', $html);
$smarty->assign('title', $a->get('title'));
$exportedmodals .= $smarty->fetch('export:html:modal.tpl');
}
$exportedmodals = $outputfilter->filter($exportedmodals);
$content .= $exportedmodals;
}
}
if (false === file_put_contents($this->fileroot . $dirname . '/index.html', $content)) {
throw new SystemException("Unable to create index.html for artefact " . $artefact->get('id'));
}
......@@ -621,6 +910,20 @@ abstract class HtmlExportArtefactPlugin {
$rendered = $artefact->render_self(array('limit' => $options['perpage'], 'offset' => $i));
$smarty->assign('rendered', $outputfilter->filter($rendered['html']));
$content = $smarty->fetch('export:html:page.tpl');
if ($artefact instanceof ArtefactTypeBlog && get_config('licensemetadata')) {
$modalcontent = $artefact->render_self(array('limit' => $options['perpage'], 'offset' => $i, 'details' => true, 'metadata' => 1, 'modal' => true));
$html ='';
if (!empty($modalcontent['javascript'])) {
$html = '<script>' . $modalcontent['javascript'] . '</script>';
}
$html .= $modalcontent['html'];
$smarty->assign('artefactid', $artefact->get('id'));
$smarty->assign('content', $html);
$smarty->assign('title', $artefact->get('title'));
$exportedmodals .= $smarty->fetch('export:html:modal.tpl');
$exportedmodals = $outputfilter->filter($exportedmodals);
$content .= $exportedmodals;
}
if (false === file_put_contents($this->fileroot . $dirname . "/{$i}.html", $content)) {
throw new SystemException("Unable to create {$i}.html for artefact {$artefact->get('id')}");
......@@ -767,6 +1070,14 @@ class HtmlExportOutputFilter {
array($this, 'replace_tag_link'),
$html
);
// Links to journals
$html = preg_replace_callback(
'#<a[^>]+href="(' . $wwwroot . ')?/?artefact/blog/view/index\.php\?=(\d+)?"[^>]*>([^<]*)</a>#',
array($this, 'replace_journal_link'),
$html
);
return $html;
}
......@@ -968,6 +1279,14 @@ class HtmlExportOutputFilter {
return $matches[1];
}
/**
* Callback to replace links to journals static text in
* the HTML export
*/
function replace_journal_link($matches) {
return $matches[3];
}
/**
* Given a file, returns the folder path for it in the Mahara files area
*
......
......@@ -46,7 +46,7 @@ jQuery(function($) {
}
else {
// Open form here even though it's currently empty (its quicker)
newblock.find('.modal-title').html(get_string('loading'));
newblock.find('.modal-title').html('loading');
if (replaceContent) {
contentArea.html(content);
......
function modal_handler(e) {
var modal = $('#' + e.target.attributes.getNamedItem('data-target').value);
modal.addClass('active').removeClass('closed');
$(modal).find('.deletebutton').on('click', function(e) {
modal.addClass('closed').removeClass('active');
dock.hide();
});
$('.feedbacktable .list-group-lite').addClass('fullwidth');
}
jQuery(function($) {
"use strict";
$('[data-target="#configureblock"]').each(function(i, obj) {
$(obj).attr('data-target', 'modal_' + $(obj).attr('data-artefactid'));
});
var deletebutton = $('#configureblock').find('.deletebutton');
$('.commentlink').on('click', function(e){
modal_handler(e);
});
$('.modal_link').on('click', function(e){
modal_handler(e);
});
});
......@@ -2,7 +2,7 @@
<div class="image">
{if !$editing}
<a class="modal_link" data-toggle="modal-docked" data-target="#configureblock" href="#" >
<img src="{$src}" alt="{$description}" itemprop="contentURL" data-blockid="{$blockid}" data-artefactid="{$artefactid}">
<img src="{$src}" alt="{$description}" itemprop="contentURL" data-blockid="{$blockid}" data-artefactid="{$artefactid}" data-target="#configureblock">
</a>
{else}
<img src="{$src}" alt="{$description}" itemprop="contentURL">
......
......@@ -4,6 +4,6 @@
</a>
<p>{$description}</p>
<div>
<a href="{$metadataurl}">{str tag=Details section=artefact.file}</a>
<!-- <a href="{$metadataurl}">{str tag=Details section=artefact.file}</a> -->
</div>
</div>
......@@ -5,6 +5,9 @@
<title>{str tag=usersportfolio section=export.html args=$user|full_name|escape}</title>
{foreach from=$stylesheets item=sheet}
<link rel="stylesheet" type="text/css" href="{$rootpath}static/{$sheet}">
{/foreach}
{foreach from=$scripts item=script}
<script type='text/javascript' src='{$scriptspath}{$script}.js'></script>
{/foreach}
</head>
<body>
......
<div class="modal modal-shown modal-docked-right modal-docked closed blockinstance configure" id="modal_{$artefactid}" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content" data-height=".modal-body">
<div class="modal-header">
<button class="deletebutton close" name="close_configuration">
<span class="times">&times;</span>
<span class="sr-only">{str tag=closeconfiguration section=view}</span>
</button>
<h4 class="modal-title text-inline">{$title}</h4>
</div>
<div class="modal-body blockinstance-content">
{$content|safe}
</div>
</div>
</div>
</div>
......@@ -7,7 +7,6 @@
<span class="sr-only">{str tag=closeconfiguration section=view}</span>
</button>
<h4 class="modal-title blockinstance-header text-inline"></h4>
<span class="icon icon-cogs icon-2x float-right" role="presentation" aria-hidden="true"></span>
</div>
<div id="modal_messages"></div>
<div class="modal-body blockinstance-content">
......
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