Commit 0262e44c authored by Penny Leach's avatar Penny Leach
Browse files

beginnings of view rendering

parent 9728b211
......@@ -51,5 +51,7 @@ $string['dbconnfailed'] = 'Failed to connect to database, error message was %s';
// as they are duplicated there, in the case that get_string was not available.
$string['unrecoverableerror'] = 'A nonrecoverable error occured. This probably means that you have encountered a bug in the system';
$string['unrecoverableerrortitle'] = '%s - Site Unavailable';
$string['parameterexception'] = 'A required parameter was missing';
$string['accessdeniedexception'] = 'You do not have access to view this page';
?>
......@@ -75,7 +75,7 @@
<KEY NAME="institution" TYPE="foreign" FIELDS="institution" REFTABLE="institution" REFFIELDS="name"/>
</KEYS>
<INDEXES>
<INDEX NAME="usernameuk" UNIQUE="true" FIELDS="LOWER(username)"/>
<INDEX NAME="usernameuk" UNIQUE="true" FIELDS="username,institution"/>
</INDEXES>
</TABLE>
<TABLE NAME="event_type">
......@@ -575,9 +575,9 @@
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" />
<FIELD NAME="title" TYPE="text" NOTNULL="true" />
<FIELD NAME="authorformat" TYPE="text" NOTNULL="true" />
<FIELD NAME="description" TYPE="text" NOTNULL="false" />
<FIELD NAME="owner" TYPE="int" LENGTH="10" NOTNULL="true" />
<FIELD NAME="ownerformat" TYPE="text" NOTNULL="true" />
<FIELD NAME="template" TYPE="text" NOTNULL="true" />
<FIELD NAME="startdate" TYPE="datetime" />
<FIELD NAME="stopdate" TYPE="datetime" />
......@@ -600,6 +600,7 @@
<FIELD NAME="artefact" TYPE="int" LENGTH="10" NOTNULL="true" />
<FIELD NAME="block" TYPE="text" NOTNULL="true" />
<FIELD NAME="ctime" TYPE="datetime" NOTNULL="true" />
<FIELD NAME="format" TYPE="text" NOTNULL="true" />
<!--more? -->
</FIELDS>
<KEYS>
......
......@@ -387,17 +387,27 @@ function exception (Exception $e) {
$sitename = 'Mahara';
}
$outputtitle = get_string('unrecoverableerrortitle', 'error', $sitename);
$parameterexception = get_string('parameterexception', 'error');
$accessdeniedexception = get_string('accessdeniedexception', 'error');
}
else {
// sensible english defaults
$outputmessage = 'A nonrecoverable error occured. '
. 'This probably means you have encountered a bug in the system';
$outputtitle = 'Mahara - Site Unavailable';
$parameterexception = 'A required parameter was missing';
$accessdeniedexception = 'You do not have access to view this page';
}
switch (get_class($e)) {
case 'ConfigSanityException':
$outputmessage = $message = get_string('configsanityexception', 'error', $e->getMessage());
break;
case 'ParameterException':
$outputmessage = $message = $parameterexception . ' ' . $e->getMessage();
break;
case 'AccessDeniedException':
$outputmessage = $message = $accessdeniedexception . ' ' . $e->getMessage();
break;
default:
$message = $e->getMessage();
$outputmessage .= '<br> ' . $e->getMessage();
......@@ -479,4 +489,9 @@ class ViewNotFoundException extends Exception {}
* Exception - anything to do with template parsing
*/
class TemplateParserException extends Exception {}
/**
* Exception - Access denied. Throw this if a user is trying to view something they can't
*/
class AccessDeniedException extends Exception {}
?>
......@@ -25,8 +25,47 @@
*/
defined('INTERNAL') || die();
/**
* render templates in readonly mode (used for viewing templates)
*/
define('TEMPLATE_RENDER_READONLY', 1);
/**
* render templates in editmode mode (for view wizard)
*/
define('TEMPLATE_RENDER_EDITMODE', 2);
/**
* display format for author names in views - firstname
*/
define('FORMAT_NAME_FIRSTNAME', 1);
/**
* display format for author names in views - lastname
*/
define('FORMAT_NAME_LASTNAME', 2);
/**
* display format for author names in views - firstname lastname
*/
define('FORMAT_NAME_FIRSTNAMELASTNAME', 3);
/**
* display format for author names in views - preferred name
*/
define('FORMAT_NAME_PREFERREDNAME', 4);
/**
* display format for author names in views - student id
*/
define('FORMAT_NAME_STUDENTID', 5);
/**
* display format for author names in views - obeys display_name
*/
define('FORMAT_NAME_DISPLAYNNAME', 6);
require_once('artefact.php');
function template_parse($templatename) {
......@@ -261,86 +300,93 @@ function template_render($template, $mode, $data=array()) {
$html .= $t['content'];
}
else {
if ($mode == TEMPLATE_RENDER_READONLY) {
$html .= 'READONLY';
$t = $t['data'];
$attr = array(
'id' => $t['id'],
'class' => array('block'),
);
// @todo I don't think we have to have both...
if (isset($t['width']) && isset($t['height'])) {
$attr['style'][] = 'width: ' . $t['width'] . 'px;height: ' . $t['height'] . 'px;';
}
else {
$t = $t['data'];
$attr = array(
'id' => $t['id'],
'class' => array('block'),
);
if (isset($t['width']) && isset($t['height'])) {
$attr['style'][] = 'width: ' . $t['width'] . 'px;height: ' . $t['height'] . 'px;';
}
$block = '';
switch ($t['type']) {
case 'label';
$block .= template_render_label($t, $data);
$block = '';
switch ($t['type']) {
case 'label';
if ($mode == TEMPLATE_RENDER_EDITMODE) {
$block .= template_render_label_editmode($t, $data);
break;
case 'title';
if (isset($data['title'])) {
$block .= hsc($data['title']);
}
break;
case 'author';
if (isset($data['author'])) {
$block .= hsc($data['author']);
}
break;
case 'description';
if (isset($data['description'])) {
$block .= hsc($data['description']);
}
break;
case 'artefact';
$classes = array('block');
// @todo, this shouldn't be hardcoded
$droplist[$t['id']] = array('render_full');
// @todo need to populate with data if it's available
if ( isset($data[$t['id']]) ) {
$artefact = artefact_instance_from_id($data[$t['id']]['id']);
// @todo, custom rendering
$block .= $artefact->render(FORMAT_ARTEFACT_LISTSELF, null);
}
else {
$block .= '<i>' . get_string('empty_block', 'view') . '</i>';
}
else {
$block .= $data[$t['id']]['value'];
}
case 'title';
if (isset($data['title'])) {
$block .= hsc($data['title']);
}
break;
case 'author';
if (isset($data['author'])) {
// @todo get authorformat here
$block .= hsc($data['author']);
}
break;
case 'description';
if (isset($data['description'])) {
$block .= hsc($data['description']);
}
break;
case 'artefact';
$classes = array('block');
// @todo, this shouldn't be hardcoded
$droplist[$t['id']] = array('render_full');
// @todo need to populate with data if it's available
if ( isset($data[$t['id']]) ) {
$artefact = artefact_instance_from_id($data[$t['id']]['id']);
// @todo, custom rendering
$format = FORMAT_ARTEFACT_LISTSELF;
if (isset($data[$t['id']]['format'])) {
$format = $data[$t['id']]['format'];
}
$block .= $artefact->render($format, null);
}
else {
$block .= '<i>' . get_string('empty_block', 'view') . '</i>';
}
break;
}
break;
}
// span or div?
if (isset($t['tagtype']) && $t['tagtype'] == 'span') {
$html .= '<span';
$html .= template_render_attributes($attr);
$html .= '>';
$html .= $block;
$html .= '</span>';
}
else {
$html .= '<div';
$html .= template_render_attributes($attr);
$html .= '>';
$html .= $block;
$html .= '</div>';
}
// span or div?
if (isset($t['tagtype']) && $t['tagtype'] == 'span') {
$html .= '<span';
$html .= template_render_attributes($attr);
$html .= '>';
$html .= $block;
$html .= '</span>';
}
else {
$html .= '<div';
$html .= template_render_attributes($attr);
$html .= '>';
$html .= $block;
$html .= '</div>';
}
}
}
$droplist = json_encode($droplist);
$spinner_url = json_encode(theme_get_image_path('loading.gif'));
$wwwroot = get_config('wwwroot');
$json_emptylabel = json_encode(get_string('emptylabel', 'view'));
$javascript = <<<EOF
$javascript = '';
if ($mode == TEMPLATE_RENDER_EDITMODE) {
$droplist = json_encode($droplist);
$spinner_url = json_encode(theme_get_image_path('loading.gif'));
$wwwroot = get_config('wwwroot');
$json_emptylabel = json_encode(get_string('emptylabel', 'view'));
$javascript = <<<EOF
<script type="text/javascript">
var droplist = $droplist;
......@@ -415,14 +461,14 @@ function template_render($template, $mode, $data=array()) {
</script>
EOF;
}
return $javascript . $html;
}
/*
* @todo: some documentation
*/
function template_render_label($block, $data) {
function template_render_label_editmode($block, $data) {
if (isset($data[$block['id']]['value'])) {
return '<script type="text/javascript">addLoadEvent(function() { $(' . json_encode($block['id']) . ').labelValue = ' . json_encode($data[$block['id']]['value']) . ';});</script><span class="clickable" onclick="setLabel(' . hsc(json_encode($block['id'])) . ');">' . hsc($data[$block['id']]['value']) . '</span>';
}
......@@ -451,4 +497,40 @@ function template_render_attributes($attr) {
return $html;
}
/**
* This function formats a user's name
* according to their view preference
*
* @param constant $format FORMAT_NAME_(FIRSTNAME|FIRSTNAMELASTNAME|LASTNAME|PREFERREDNAME|STUDENTID)
* @param object $user must contain those ^^ fields (or id, in which case a db lookup will be done)
*
* @return string formatted name
*/
function template_format_owner($format, $user) {
if (is_int($user)) {
$user = get_record('usr', 'id', $user);
}
if (!is_object($user)) {
return ''; // @todo throw exception?
}
switch ($format) {
case FORMAT_NAME_FIRSTNAME:
return $user->firstname;
case FORMAT_NAME_LASTNAME:
return $user->lastname;
case FORMAT_NAME_FIRSTNAMELASTNAME:
return $user->firstname . ' ' . $user->lastname;
case FORMAT_NAME_PREFERREDNAME:
return $user->preferredname;
case FORMAT_NAME_STUDENTID:
return $user->studentid;
case FORMAT_NAME_DISPLAYNAME:
default:
return display_name($user);
}
}
?>
......@@ -32,6 +32,7 @@ class View {
protected $dirty;
protected $id;
protected $owner;
protected $ownerformat;
protected $ctime;
protected $mtime;
protected $atime;
......@@ -43,6 +44,8 @@ class View {
protected $template;
protected $artefact_instances;
protected $artefact_metadata;
protected $contents;
protected $ownerobj;
public function __construct($id=0, $data=null) {
if (!empty($id)) {
......@@ -68,6 +71,13 @@ class View {
$this->atime = time();
}
public function get($field) {
if (!property_exists($this, $field)) {
throw new InvalidArgumentException("Field $field wasn't found in class " . get_class($this));
}
return $this->{$field};
}
public function get_artefact_instances() {
if (!isset($this->artefact_instances)) {
$this->artefact_instances = false;
......@@ -86,7 +96,7 @@ class View {
public function get_artefact_metadata() {
if (!isset($this->artefact_metadata)) {
$prefix = get_config('dbprefix');
$sql = 'SELECT a.*, i.name
$sql = 'SELECT a.*, i.name, va.block, va.format
FROM ' . $prefix . 'view_artefact va
JOIN ' . $prefix . 'artefact a ON va.artefact = a.id
JOIN ' . $prefix . 'artefact_installed_type i ON a.artefacttype = i.name
......@@ -122,7 +132,12 @@ class View {
return get_records_sql_array($sql, array($this->id, $userid));
}
public function get_contents() { // lazy setup.
if (!isset($this->contents)) {
$this->contents = get_records_array('view_content', 'view', $this->id);
}
return $this->contents;
}
public function has_artefacts() {
if ($this->get_artefact_metadata()) {
......@@ -130,7 +145,41 @@ class View {
}
return false;
}
public function get_owner_object() {
if (!isset($this->ownerobj)) {
$this->ownerobj = get_record('usr', 'id', $this->get('owner'));
}
return $this->ownerobj;
}
public function render() {
require_once('template.php');
$artefacts = $this->get_artefact_metadata();
$contents = $this->get_contents();
$data = array();
foreach ($artefacts as $artefact) {
$data[$artefact->block] = array(
'id' => $artefact->id,
'format' => $artefact->format
);
}
foreach ($contents as $content) {
$data[$content->id] = array(
'value' => $content->content,
);
}
$data['title'] = $this->get('title');
$data['description'] = $this->get('description');
$data['author'] = template_format_owner($this->get('ownerformat', $this->get_owner_object()));
$template = template_locate($this->get('template'));
return template_render($template, $data);
}
}
?>
......@@ -26,14 +26,15 @@
define('INTERNAL', 1);
require(dirname(dirname(__FILE__)) . '/init.php');
require(get_config('libroot') . 'view.php');
$viewid = param_integer('view');
$artefactid = param_integer('artefact', null);
$ancestors = param_variable('artefactlist', null);
$view = get_record('view', 'id', $viewid);
$view = new View($viewid);
if (can_view_view($viewid)) {
$content = 'template display here';
if (!can_view_view($viewid)) {
throw new AccessDeniedException();
}
$getstring = quotestrings(array('message', 'makepublic', 'placefeedback',
......@@ -44,7 +45,7 @@ $getstring = quotestrings(array('message', 'makepublic', 'placefeedback',
if ($artefactid) {
$javascript = 'var artefact = ' . $artefactid . ";\n";
$artefact = get_record('artefact', 'id', $artefactid);
$title = '<div><a href="view.php?view=' . $viewid . '">' . $view->title . "</a></div>\n";
$title = '<div><a href="view.php?view=' . $viewid . '">' . $view->get('title') . "</a></div>\n";
if ($ancestors) {
$alist = explode(',',$ancestors);
$links = array();
......@@ -60,7 +61,8 @@ if ($artefactid) {
}
else {
$javascript = "var artefact = undefined;\n";
$title = "<h3>$view->title</h3>\n";
$title = "<h3>" . $view->get('title') . "</h3>\n";
$content = $view->render();
}
$javascript .= <<<JAVASCRIPT
......
......@@ -324,14 +324,14 @@ sub insert_random_views {
$title =~ s/[\x80-\xff]//g;
$description =~ s/[\x80-\xff]//g;
$self->{dbh}->do('INSERT INTO ' . $prefix . 'view (title, authorformat, description, owner, template, startdate, stopdate, ctime, mtime, atime)
$self->{dbh}->do('INSERT INTO ' . $prefix . 'view (title, ownerformat, description, owner, template, startdate, stopdate, ctime, mtime, atime)
VALUES(?, ?, ?, ?, ?, current_timestamp, current_timestamp, current_timestamp, current_timestamp, current_timestamp)', undef,
$title, 'firstnamelastname', $description, $user_id, $template_id);
my $view_id = $self->{dbh}->last_insert_id(undef, undef, $prefix . 'view', undef);
$self->{dbh}->do('INSERT INTO ' . $prefix . 'view_artefact (view, artefact, block, ctime)
(SELECT ' . $view_id . ', id, \'foo\', current_timestamp FROM '. $prefix . 'artefact WHERE owner = ? ORDER BY RANDOM() LIMIT 5)', undef, $user_id);
$self->{dbh}->do('INSERT INTO ' . $prefix . 'view_artefact (view, artefact, block, ctime, format)
(SELECT ' . $view_id . ', id, \'foo\', current_timestamp, \'listself\' FROM '. $prefix . 'artefact WHERE owner = ? ORDER BY RANDOM() LIMIT 5)', undef, $user_id);
}
$self->{dbh}->commit();
}
......
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