Commit f17fad2d authored by Stacey Walker's avatar Stacey Walker Committed by Richard Mansfield
Browse files

Rewrote to enable multiple plans with tasks per plan


Signed-off-by: default avatarStacey Walker <stacey@catalyst.net.nz>
parent c25df546
......@@ -30,5 +30,7 @@ defined('INTERNAL') || die();
$string['title'] = 'Your Plans';
$string['description'] = 'Display your plans list';
$string['newerplans'] = 'Newer plans';
$string['noplansaddone'] = 'No plans yet. %sAdd one%s!';
$string['olderplans'] = 'Older plans';
$string['planstoshow'] = 'Plan to show';
?>
......@@ -44,19 +44,25 @@ class PluginBlocktypePlans extends PluginBlocktype {
public static function render_instance(BlockInstance $instance, $editing=false) {
require_once(get_config('docroot') . 'artefact/lib.php');
safe_require('artefact','plans');
$configdata = $instance->get('configdata');
$plans = ArtefactTypePlan::get_plans();
self::build_plans_html($plans, $editing, $instance);
$smarty = smarty_core();
if (isset($configdata['artefactid'])) {
$tasks = ArtefactTypeTask::get_tasks($configdata['artefactid']);
self::build_plans_html($tasks, $editing, $instance);
$smarty->assign('tasks',$tasks);
}
else {
$smarty->assign('noplans','blocktype.plans/plans');
}
$smarty->assign('blockid', $instance->get('id'));
$smarty->assign('plans', $plans);
return $smarty->fetch('blocktype:plans:content.tpl');
}
public static function build_plans_html(&$plans, $editing=false, BlockInstance $instance) {
public static function build_plans_html(&$tasks, $editing=false, BlockInstance $instance) {
$smarty = smarty_core();
$smarty->assign_by_ref('plans', $plans);
$plans['tablerows'] = $smarty->fetch('blocktype:plans:planrows.tpl');
$smarty->assign_by_ref('tasks', $tasks);
$tasks['tablerows'] = $smarty->fetch('blocktype:plans:taskrows.tpl');
if ($editing) {
return;
}
......@@ -65,18 +71,18 @@ class PluginBlocktypePlans extends PluginBlocktype {
$pagination = build_pagination(array(
'id' => 'block' . $blockid . '_pagination',
'class' => 'center nojs-hidden-block',
'datatable' => 'planstable_' . $blockid,
'datatable' => 'taskstable_' . $blockid,
'url' => $baseurl,
'jsonscript' => 'artefact/plans/blocktype/plans/plans.json.php',
'count' => $plans['count'],
'limit' => $plans['limit'],
'offset' => $plans['offset'],
'jsonscript' => 'artefact/plans/blocktype/plans/tasks.json.php',
'count' => $tasks['count'],
'limit' => $tasks['limit'],
'offset' => $tasks['offset'],
'numbersincludefirstlast' => false,
'resultcounttextsingular' => get_string('plan', 'artefact.plans'),
'resultcounttextplural' => get_string('plans', 'artefact.plans'),
'resultcounttextsingular' => get_string('task', 'artefact.plans'),
'resultcounttextplural' => get_string('tasks', 'artefact.plans'),
));
$plans['pagination'] = $pagination['html'];
$plans['pagination_js'] = 'var paginator' . $blockid . ' = ' . $pagination['javascript'];
$tasks['pagination'] = $pagination['html'];
$tasks['pagination_js'] = 'var paginator' . $blockid . ' = ' . $pagination['javascript'];
}
// My Plans blocktype only has 'title' option so next two functions return as normal
......@@ -85,11 +91,29 @@ class PluginBlocktypePlans extends PluginBlocktype {
}
public static function instance_config_form($instance) {
return array();
$configdata = $instance->get('configdata');
$form = array();
// Which resume field does the user want
$form[] = self::artefactchooser_element((isset($configdata['artefactid'])) ? $configdata['artefactid'] : null);
return $form;
}
public static function artefactchooser_element($default=null) {
return array();
safe_require('artefact', 'plans');
return array(
'name' => 'artefactid',
'type' => 'artefactchooser',
'title' => get_string('planstoshow', 'blocktype.plans/plans'),
'defaultvalue' => $default,
'blocktype' => 'plans',
'selectone' => true,
'search' => false,
'artefacttypes' => array('plan'),
'template' => 'artefact:plans:artefactchooser-element.tpl',
);
}
}
......
......@@ -36,8 +36,9 @@ require_once(get_config('docroot') . 'artefact/plans/blocktype/plans/lib.php');
$limit = param_integer('limit', 10);
$offset = param_integer('offset', 0);
$bi = new BlockInstance(param_integer('block'));
$configdata = $bi->get('configdata');
$plans = ArtefactTypePlan::get_plans($offset, $limit);
PluginBlocktypePlans::build_plans_html($plans, false, $bi);
$tasks = ArtefactTypeTask::get_tasks($configdata['artefactid'], $offset, $limit);
PluginBlocktypePlans::build_plans_html($tasks, false, $bi);
json_reply(false, (object) array('message' => false, 'data' => $plans));
json_reply(false, (object) array('message' => false, 'data' => $tasks));
<div class="blockinstance-content">
{if $plans.data}
<table id="planstable_{$blockid}">
{if $tasks.data}
<table id="taskstable_{$blockid}">
<colgroup width="50%" span="2"></colgroup>
<thead>
<tr>
......@@ -10,18 +10,18 @@
</tr>
</thead>
<tbody>
{$plans.tablerows|safe}
{$tasks.tablerows|safe}
</tbody>
</table>
<div id="plans_page_container">{$plans.pagination|safe}</div>
<div id="plans_page_container">{$tasks.pagination|safe}</div>
<script>
addLoadEvent(function() {literal}{{/literal}
{$plans.pagination_js|safe}
{$tasks.pagination_js|safe}
removeElementClass('plans_page_container', 'hidden');
{literal}}{/literal});
</script>
{else}
<p>{str tag='noplans' section='artefact.plans'}</p>
<p>{str tag='notasks' section='artefact.plans'}</p>
{/if}
</div>
{foreach from=$plans.data item=plan}
{if $plan->completed == -1}
{foreach from=$tasks.data item=task}
{if $task->completed == -1}
<tr class="plan_incomplete">
<td>{$plan->completiondate|escape}</td>
<td>{$plan->title|escape}<div>{$plan->description|escape}</div></td>
<td>{$task->completiondate|escape}</td>
<td>{$task->title|escape}<div>{$task->description|escape}</div></td>
<td>&nbsp;</td>
</tr>
{else}
<tr class="{cycle values='r0,r1'}">
<td>{$plan->completiondate|escape}</td>
<td>{$plan->title|escape}<div>{$plan->description|escape}</div></td>
{if $plan->completed == 1}
<td>{$task->completiondate|escape}</td>
<td>{$task->title|escape}<div>{$task->description|escape}</div></td>
{if $task->completed == 1}
<td><div class="plan_completed"><img src="{$WWWROOT}theme/raw/static/images/success.gif" alt="" /></div></td>
{else}
<td>&nbsp;</td>
......
......@@ -8,15 +8,15 @@
<!-- This table is supposed to have a 1-1 relation with every row in the
artefact table with artefacttype = 'plan'. It contains additional data
that isn't in the artefact table. -->
<TABLE NAME="artefact_plan">
<TABLE NAME="artefact_task">
<FIELDS>
<FIELD NAME="plan" TYPE="int" LENGTH="10" SEQUENCE="true" NOTNULL="true" />
<FIELD NAME="task" TYPE="int" LENGTH="10" SEQUENCE="true" NOTNULL="true" />
<FIELD NAME="completiondate" TYPE="datetime" NOTNULL="false" />
<FIELD NAME="completed" TYPE="int" LENGTH="2" NOTNULL="true" DEFAULT="0" />
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="plan" />
<KEY NAME="artefactfk" TYPE="foreign" FIELDS="plan" REFTABLE="artefact" REFFIELDS="id" />
<KEY NAME="primary" TYPE="primary" FIELDS="task" />
<KEY NAME="artefactfk" TYPE="foreign" FIELDS="task" REFTABLE="artefact" REFFIELDS="id" />
</KEYS>
</TABLE>
</TABLES>
......
......@@ -29,6 +29,33 @@ defined('INTERNAL') || die();
function xmldb_artefact_plans_upgrade($oldversion=0) {
if ($oldversion < 2010072300) {
if (field_exists(new XMLDBTable('artefact_plan'), new XMLDBField('plan'))) {
execute_sql("ALTER TABLE {artefact_plan} RENAME TO {artefact_task}");
if (is_postgres()) {
execute_sql('
ALTER TABLE {artefact_task} RENAME COLUMN plan TO task;
ALTER TABLE {artefact_task} DROP CONSTRAINT {arteplan_pla_fk};
ALTER TABLE {artefact_task} ADD CONSTRAINT {artetask_tas_fk} FOREIGN KEY (task) REFERENCES {artefact}(id);
ALTER INDEX {arteplan_pla_pk} RENAME TO {artetask_tas_pk};
ALTER INDEX {arteplan_pla_ix} RENAME TO {artetask_tas_ix};
');
}
else if (is_mysql()) {
execute_sql('ALTER TABLE {artefact_task} CHANGE plan task TEXT');
execute_sql("ALTER TABLE {artefact_task} DROP FOREIGN KEY {arteplan_pla_fk}");
execute_sql("ALTER TABLE {artefact_task} DROP INDEX {arteplan_pla_ix}");
execute_sql("ALTER TABLE {artefact_task} CHANGE plan task BIGINT(10) DEFAULT NULL");
execute_sql("ALTER TABLE {artefact_task} ADD CONSTRAINT {artetask_tas_fk} FOREIGN KEY {artetask_tas_ix} (task) REFERENCES {artefact}(id)");
}
}
}
if ($oldversion < 2010072301) {
execute_sql("INSERT INTO {artefact_installed_type} (name,plugin) VALUES ('task','plans')");
execute_sql("UPDATE {artefact} SET artefacttype = 'task' WHERE artefacttype = 'plan'");
}
return true;
}
......
......@@ -28,28 +28,21 @@
define('INTERNAL', true);
define('MENUITEM', 'profile/plans');
require_once(dirname(dirname(dirname(__FILE__))) . '/init.php');
require_once(dirname(dirname(dirname(dirname(__FILE__)))) . '/init.php');
require_once('pieforms/pieform.php');
define('TITLE', get_string('deleteplan','artefact.plans'));
safe_require('artefact','plans');
$delete = param_integer('plan');
$plan = new ArtefactTypePlan($delete);
$USER->can_edit_artefact($delete);
define('TITLE', get_string('deleteplan','artefact.plans'));
$todelete = (object) array(
'completiondate' => strftime(get_string('strftimedate'), $plan->get('completiondate')),
'completed' => $plan->get('completed'),
'title' => $plan->get('title'),
'description' => $plan->get('description')
);
$id = param_integer('id');
$todelete = artefact_instance_from_id($id);
$USER->can_edit_artefact($todelete);
$form = array(
$deleteform = array(
'name' => 'deleteplanform',
'plugintype' => 'artefact',
'pluginname' => 'plans',
'pluginname' => 'plan',
'renderer' => 'div',
'elements' => array(
'submit' => array(
'type' => 'submitcancel',
......@@ -58,19 +51,20 @@ $form = array(
),
)
);
$deleteplanform = pieform($form);
$form = pieform($deleteform);
$smarty = smarty();
$smarty->assign('todelete', $todelete);
$smarty->assign('deleteplanform', $deleteplanform);
$smarty->assign('PAGEHEADING', hsc(get_string('deletingplan','artefact.plans',$plan->get('title'))));
$smarty->assign('form', $form);
$smarty->assign('PAGEHEADING', hsc($todelete->get('title')));
$smarty->assign('subheading', get_string('deletethisplan','artefact.plans',$todelete->get('title')));
$smarty->assign('message', get_string('deleteplanconfirm','artefact.plans'));
$smarty->display('artefact:plans:delete.tpl');
// calls this function first so that we can get the artefact and call delete on it
function deleteplanform_submit(Pieform $form, $values) {
global $SESSION, $plan;
global $SESSION, $todelete;
$plan->delete();
$todelete->delete();
$SESSION->add_ok_msg(get_string('plandeletedsuccessfully', 'artefact.plans'));
redirect('/artefact/plans/');
......
<?php
/**
* Mahara: Electronic portfolio, weblog, resume builder and social networking
* Copyright (C) 2006-2009 Catalyst IT Ltd and others; see:
* http://wiki.mahara.org/Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package mahara
* @subpackage artefact-plans
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006-2009 Catalyst IT Ltd http://catalyst.net.nz
*
*/
define('INTERNAL', true);
define('MENUITEM', 'profile/plans');
require_once(dirname(dirname(dirname(dirname(__FILE__)))) . '/init.php');
require_once('pieforms/pieform.php');
safe_require('artefact','plans');
define('TITLE', get_string('deletetask','artefact.plans'));
$id = param_integer('id');
$todelete = artefact_instance_from_id($id);
$USER->can_edit_artefact($todelete);
$deleteform = array(
'name' => 'deletetaskform',
'plugintype' => 'artefact',
'pluginname' => 'plans',
'renderer' => 'div',
'elements' => array(
'submit' => array(
'type' => 'submitcancel',
'value' => array(get_string('deletetask','artefact.plans'), get_string('cancel')),
'goto' => get_config('wwwroot') . '/artefact/plans/plan.php?id='.$todelete->get('parent'),
),
)
);
$form = pieform($deleteform);
$smarty = smarty();
$smarty->assign('form', $form);
$smarty->assign('PAGEHEADING', hsc($todelete->get('title')));
$smarty->assign('subheading', get_string('deletethistask','artefact.plans',$todelete->get('title')));
$smarty->assign('message', get_string('deletetaskconfirm','artefact.plans'));
$smarty->display('artefact:plans:delete.tpl');
// calls this function first so that we can get the artefact and call delete on it
function deletetaskform_submit(Pieform $form, $values) {
global $SESSION, $todelete;
$todelete->delete();
$SESSION->add_ok_msg(get_string('taskdeletedsuccessfully', 'artefact.plans'));
redirect('/artefact/plans/plan.php?id='.$todelete->get('parent'));
}
?>
......@@ -28,7 +28,7 @@
define('INTERNAL', true);
define('MENUITEM', 'profile/myplans');
require_once(dirname(dirname(dirname(__FILE__))) . '/init.php');
require_once(dirname(dirname(dirname(dirname(__FILE__)))) . '/init.php');
require_once('pieforms/pieform.php');
require_once('pieforms/pieform/elements/calendar.php');
require_once(get_config('docroot') . 'artefact/lib.php');
......@@ -36,15 +36,15 @@ safe_require('artefact','plans');
define('TITLE', get_string('editplan','artefact.plans'));
$plan = param_integer('plan');
$id = param_integer('id');
$artefact = artefact_instance_from_id($plan);
$USER->can_edit_artefact($plan);
$artefact = artefact_instance_from_id($id);
$USER->can_edit_artefact($id);
$editplanform = ArtefactTypePlan::get_form($artefact);
$editform = ArtefactTypePlan::get_form($artefact);
$smarty = smarty();
$smarty->assign('editplanform', $editplanform);
$smarty->assign('editform', $editform);
$smarty->assign('PAGEHEADING', hsc(get_string("editingplan", "artefact.plans")));
$smarty->display('artefact:plans:edit.tpl');
......
<?php
/**
* Mahara: Electronic portfolio, weblog, resume builder and social networking
* Copyright (C) 2006-2009 Catalyst IT Ltd and others; see:
* http://wiki.mahara.org/Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package mahara
* @subpackage artefact-plans
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006-2009 Catalyst IT Ltd http://catalyst.net.nz
*
*/
define('INTERNAL', true);
define('MENUITEM', 'profile/myplans');
require_once(dirname(dirname(dirname(dirname(__FILE__)))) . '/init.php');
require_once('pieforms/pieform.php');
require_once('pieforms/pieform/elements/calendar.php');
require_once(get_config('docroot') . 'artefact/lib.php');
safe_require('artefact','plans');
define('TITLE', get_string('edittask','artefact.plans'));
$id = param_integer('id');
$task = artefact_instance_from_id($id);
$USER->can_edit_artefact($task);
$form = ArtefactTypeTask::get_form($task->get('parent'), $task);
$smarty = smarty();
$smarty->assign('editform', $form);
$smarty->assign('PAGEHEADING', hsc(get_string("editingtask", "artefact.plans")));
$smarty->display('artefact:plans:edit.tpl');
?>
......@@ -52,9 +52,9 @@ EOF;
$smarty = smarty(array('paginator'));
$smarty->assign_by_ref('plans', $plans);
$smarty->assign('strnoplanssaddone',
get_string('noplanssaddone', 'artefact.plans',
'<a href="' . get_config('wwwroot') . 'artefact/plans/new/">', '</a>'));
$smarty->assign('strnoplansaddone',
get_string('noplansaddone', 'artefact.plans',
'<a href="' . get_config('wwwroot') . 'artefact/plans/new.php">', '</a>'));
$smarty->assign('PAGEHEADING', hsc(get_string("myplans", "artefact.plans")));
$smarty->assign('INLINEJAVASCRIPT', $js);
$smarty->display('artefact:plans:index.tpl');
......
......@@ -26,17 +26,20 @@
defined('INTERNAL') || die();
$string['newplan'] = 'New plan';
/* Plans */
$string['completed'] = 'Completed';
$string['completiondate'] = 'Completion date';
$string['completeddesc'] = 'Mark your plan completed.';
$string['deleteplan'] = 'Delete plan';
$string['deletingplan'] = 'Deleting Plan: \'%s\'';
$string['description'] = 'Description';
$string['deleteplanconfirm'] = 'Are you sure you wish to delete this plan? Deleting this plan will also remove any tasks it contains.';
$string['deleteplan'] = 'Delete plan';
$string['deletethisplan'] = 'Delete plan: \'%s\'';
$string['editplan'] = 'Edit Plan';
$string['editingplan'] = 'Editing Plan';
$string['managetasks'] = 'Manage tasks';
$string['myplans'] = 'My Plans';
$string['noplanssaddone'] = 'No plans yet. %sAdd one%s!';
$string['newplan'] = 'New plan';
$string['noplansaddone'] = 'No plans yet. %sAdd one%s!';
$string['noplans'] = 'No plans to display';
$string['plan'] = 'Plan';
$string['plans'] = 'Plans';
......@@ -44,6 +47,24 @@ $string['plandeletedsuccessfully'] = 'Plan deleted successfully.';
$string['plannotdeletedsuccessfully'] = 'There was an error deleting plan.';
$string['plannotsavedsuccessfully'] = 'There was an error submitting this form. Please check the marked fields and try again.';
$string['plansavedsuccessfully'] = 'Plan saved successfully.';
$string['planstasks'] = 'Plan \'%s\' tasks.';
$string['saveplan'] = 'Save plan';
$string['title'] = 'Title';
/* Tasks */
$string['deletetaskconfirm'] = 'Are you sure you wish to delete this task?';
$string['deletetask'] = 'Delete task';
$string['deletethistask'] = 'Delete task: \'%s\'';
$string['edittask'] = 'Edit task';
$string['editingtask'] = 'Editing task';
$string['mytasks'] = 'My Tasks';
$string['newtask'] = 'New task';
$string['notasksaddone'] = 'No tasks yet. %sAdd one%s!';
$string['savetask'] = 'Save task';
$string['task'] = 'task';
$string['tasks'] = 'tasks';
$string['taskdeletedsuccessfully'] = 'Task deleted successfully.';
$string['tasksavedsuccessfully'] = 'Task saved successfully.';
?>
......@@ -30,12 +30,13 @@ class PluginArtefactPlans extends PluginArtefact {
public static function get_artefact_types() {
return array(
'task',
'plan',
);
}
public static function get_block_types() {
return array();
return array('plans');
}
public static function get_plugin_name() {
......@@ -57,98 +58,24 @@ class PluginArtefactPlans extends PluginArtefact {
class ArtefactTypePlan extends ArtefactType {
protected $completed = 0;
protected $completiondate;
/**
* We override the constructor to fetch the extra data.
*
* @param integer
* @param object
*/
public function __construct($id = 0, $data = null) {
parent::__construct($id, $data);
if ($this->id) {
if ($pdata = get_record('artefact_plan', 'plan', $this->id, null, null, null, null, '*, ' . db_format_tsfield('completiondate'))) {
foreach($pdata as $name => $value) {
if (property_exists($this, $name)) {
$this->$name = $value;
}
}
}
else {
// This should never happen unless the user is playing around with plan IDs in the location bar or similar
throw new ArtefactNotFoundException(get_string('plandoesnotexist', 'artefact.plans'));
}
}
}
public static function get_links($id) {
return array();
}
/**
* This method extends ArtefactType::commit() by adding additional data
* into the plan table.
*
*/
public function commit() {
if (empty($this->dirty)) {
return;
}
// Return whether or not the commit worked
$success = false;
db_begin();
$new = empty($this->id);
parent::commit();
$this->dirty = true;
$completiondate = $this->get('completiondate');
if (!empty($completiondate)) {
$value = db_format_timestamp($completiondate);
}
$data = (object)array(
'plan' => $this->get('id'),
'completed' => $this->get('completed'),
'completiondate' => $value,
);