Extension:Tasks Extension

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manual
Crystal Clear action run.png
Tasks Extension

Release status: stable

Implementation Tag
Description provide a tasklist
Author(s) various
Latest version 0.5.4 (see version history below)
MediaWiki < mw 1.13
License This code is distributed under the same terms as MediaWiki itself
Download see below

Translate the Tasks Extension extension if it is available at translatewiki.net

Check usage and version matrix; code metrics

This extension provides the ability to create tasks on any page of your MediaWiki. Tasks may have severity, priority, status, and owner properties set. Also included is a highly configurable Special page for aggregateing tasks on your site by various criteria. All tasks are stored in MySQL, so the Special page is extremely fast.

Original author is Aran Deltac, but he no longer maintained it. I don't guarantee that I'll maintain this extension, but I write here all necessary to make it work, 'cause Aran Deltac only propose the archive to download. Fortunately google cache gave me instructions to make it work! --Iubito 15:54, 10 February 2006 (UTC)

News[edit | edit source]

  • 2007-05-05: Released version 0.5.4 for the specialpage, fix the problem with missing articles, fix the extension to work also in different Namespaces e.g. Templates --Ozz 12:35, 5 May 2008 (UTC)
  • 2007-03-22: Released version 0.5.3, fixed the regexp responsible for locating the user name in task text. Now the task description can contain parentheses ( and ) --User:SebM
  • 2006-10-10: Released version 0.5.2, fixed multiple tasks tags in the same page + clicking on a user show this user's tasks instead of the user personnal page --Guillaumep 18:28, 10 October 2006 (UTC)
    • Patched the 0.5.2 SpecialTasks.php to avoid "Undefined index" notices that appeared in recent MW. --Iubito 04:22, 22 February 2007 (UTC)
  • 2006-06-08: Released version 0.5.1, compatible MediaWiki 1.6.7 (parser changes), probably don't work with earlier version of MW, don't know. --Iubito 07:19, 7 July 2006 (UTC)
    • Initializing the parser in SpecialTasks
    • A function to feed the tasks_buffer array seperately from the hook
  • 2006-06-24: Released version 0.5. Affects SpecialTasks.php only. --Dangerville 22:14, 24 June 2006 (UTC)
    • Added extension credits/info visible on your Special:Version
    • Added customizable message for link text on Special:Specialpages (Tasks instead of <tasks>)
    • Added option to restrict access
    • Modified to follow guidelines/examples from Writing_a_new_special_page
    • Created subclass special page (more customizable)
  • 2006-04-03: Released version 0.4.3
    • fixed warning about hidden. Mod by James.
  • 2006-03-12: Released version 0.4.2
    • fixed bug with category links. Mod by Filo.
  • 2006-03-12: Released version 0.4.1
    • now compatible with popular Calendar extension. Mod by mhc.
  • 2006-02-10: Released version 0.4
    • compatible with MediaWiki 1.4
    • now special page list correctly task in namespaces
    • alt and title on images
    • Iubito write instructions here because Aran Deltac has changed his website.
  • 2005-11-04: Released version 0.3, fixing a bug in the display of the task images.
  • 2005-11-03: Released version 0.2 with the ability to hide tasks.
  • 2005-11-02: Released version 0.1.
  • 2005-11-01: Re-wrote the format of writing tasks and the parameters accepted.
  • 2005-10-31: First version of MediaWiki Tasks released.

Compatibility[edit | edit source]

Aran Deltac has tested it on MediaWiki 1.5.1, Iubito tested it on MediaWiki 1.4.14 (as of version 0.4). User:Smilner could not get it to work out of the box on 1.5.6. Use at your own risk.

Version 0.4.3[edit | edit source]

  • Working on 1.5.8 for James.
  • Working on v1.15.2 for Carl. I am running PostgreSQL v 8.3.12. Several minor modifications were needed to port this from MySQL to Postgres

1. Change the SQL code that makes the tasks table as

create type task_status as ENUM('!','1','2','3',' ','x');
create type yes_no as ENUM('y','n');

CREATE TABLE tasks (
    page_id INT NOT NULL DEFAULT 0,
    STATUS task_status NOT NULL DEFAULT ' ',
    owner varCHAR(255) NOT NULL,
    summary text NOT NULL,
    hidden yes_no NOT NULL DEFAULT 'n'
);

create index owner_idx  on tasks (owner);

2. Conform 3 lines of SpecialTasks.php to convert double quotes to single quotes in where clause. Change line

$where[] = 'status<="'.$args['status'].'"';

to

$where[] = 'status<='. "'". $args['status']."'";

and

$where[] = 'owner="'.$args['owner'].'"';

to

$where[] = 'owner='. "'" . $args['owner'] . "'";

and

$where[] = 'hidden="n"';

to

$where[] = 'hidden=' . "'n'";

3. My system is case sensitive. Tasks.php code did not match the image names and I liked the image hack by tbhot3ww anyway, so I changed Tasks.php formatTask function line. You could just as easily change the image names too.

From

$img = '<img src="'.$wgScriptPath.'/images/task';

to

$img = '<img src="'.$wgScriptPath.'/images/Ntask';

Version 0.5[edit | edit source]

  • Working on 1.5.8 for Sider.
  • Working on 1.6.5 for Dangerville.

0.5.1[edit | edit source]

  • Not working on 1.5.8 for Sider.
  • Working on 1.6.7 and 1.9.3 for Iubito.
  • Working on 1.7.1 for Rob Thijssen
  • Working on 1.8.2 for neverhood
  • Working on 1.14.0 for Monster (not a registered user)

0.5.2[edit | edit source]

0.5.3[edit | edit source]

0.5.4[edit | edit source]

  • run under 1.11
  • does not work for me under 1.17 (did work in 1.15): "Warning: Parameter 3 to tasksHook() expected to be a reference, value given in ~/wiki/includes/parser/Parser.php on line 3470" --Kebap 17:24, 1 September 2011 (UTC)
  • replaced &$parser by $parser in Tasks.php and it seems to fix the previous mentioned error message -- Eric Lacroix 13:53, 12 November 2011 (UTC)
  • previously mentioned fix seems to work for 1.18 as well -- David Raher 16 January 2012
  • The version from this page's discussion page worked for me out of the box under 1.18.1 -- Opfeifer 22:18, 26 January 2012 (UTC)
  • Stopped working after upgrading from PHP 5.1 to PHP 5.3, but was fixed by the above $parser fix in Tasks.php -- Ted Popesco 25 March 2012

Usage[edit | edit source]

Each task must be on its own line and start with [ ]. All the tasks must be grouped with a <tasks>..</tasks>

<tasks>
[ ] Regular task (Owner User)
[1] High priority task.
[2] Medium priority task.
[3] Low priority task (Owner User)
[!] Urgent task (must be completed immediately!!!) (Owner user).
[x] Closed task.
</tasks>

According to the regular expression, owner parsing doesn't work when there is anything, even a space character, after ')'. e.g. [ ] Regular task (Owner User) works fine, but [ ] Regular task (Owner User). (note the trailing dot) does not work right.

The tasks tag may have an optional parameter, called hidden, which hides the tasks from being viewed. To use it you would write the beginning tasks tag like <tasks hidden>.

Tasks Special Page[edit | edit source]

This page finds all tasks on all pages of your site and displays them all on one page. To view all tasks access index.php?title=Special:Tasks (or Special pages » Tasks). You can provide several arguments to limit the tasks that are returned.

  • status - Show all tasks with the specified status or higher. So, specifying "status=2" would include tasks with the status codes 2, 1, and !.
  • owner - Only tasks assigned to this user.
  • limit - Number of total tasks to list.
  • hidden - Enable the display of hidden tasks.

These arguments are specified by adding a / after and adding them as regular name/value pairs.

Installation[edit | edit source]

Copy/paste the following codes in files.

extensions/Tasks.php[edit | edit source]

<?php
 
# MediaWiki Tasks version 0.5.4
# Copyright (c) 2005 Aran Clary Deltac
# http://arandeltac.com/MediaWiki_Tasks
# Copyright (c) 2006 Sylvain Machefert, mods by mhc, Filo, James,
# Guillaume Pratte, Dangerville
# http://www.mediawiki.org/wiki/Extension:Tasks_Extension
# Distributed under that same terms as MediaWiki itself.

$wgExtensionFunctions[] = "wfTasksExtension";
$wgHooks['ArticleSave'][] = 'clearTasks';
$wgHooks['ArticleSaveComplete'][] = 'saveTasks';
global $tasks_buffer;
 
#-----------------------------------------------#
# Purpose   : Declare parser extensions.
function wfTasksExtension() {
	global $wgParser;
	$wgParser->setHook( "tasks", "tasksHook" );
}
 
#-----------------------------------------------#
# Purpose   : Display a list of tasks.
# Parameters: content, A list of tasks, one per line.
#             args, An array of arguments.
# Arguments : hidden, All tasks will be hidden in the HTML.
# Returns   : Tasks HTML.
function tasksHook( $content, $args = null, &$parser) {
	global $tasks_buffer;
	clearTasks();
	addToTaskBuffer($content);
 
	$hidden = '';
	if (isset($args['hidden'])) {
		$hidden = 'y';
	}
	else {
		$hidden = 'n';
	}
 
	$output = '';
#if you want tasks create a new section...
#	$parserOutput = $parser->parse('== [[Special:Tasks|Tasks]] ==', $parser->mTitle, $parser->mOptions, false, false);
#	$output .= $parserOutput->getText();
	foreach ($tasks_buffer as $task) {
		$task['hidden'] = $hidden;
		$output .= formatTask(
					$task['status'],
					$task['summary'],
					$task['owner'],
					'',
					$parser);
	}
	return $output;
}
 
function addToTaskBuffer($content) {
	global $tasks_buffer;
	$tasks = preg_split("/[\n\r]+/", $content);
	foreach ($tasks as $task) {
		if (preg_match('/^\s*\[([123x! ])\]\s*(.*)$/',$task,$matches)) {
			$status = $matches[1];
			$summary = $matches[2];
 
			$owner = '';
                        # the regexp updated by SebM (sebm@seren-com-pl) 22 March 2007    
                        # to allow parentheses ( ) in task description                                   
			if (preg_match('/^(.+?)\s*\(([^()]+)\)$/',$summary,$matches)) {
				$summary = $matches[1];
				$owner = $matches[2];
			}
 
			$tasks_buffer[] = array(
				'summary' => $summary,
				'status' => $status,
				'owner' => $owner,
				'hidden' => 'n'
			);
		}
	}
}
 
#-----------------------------------------------#
# Purpose   : HTML format a task.
function formatTask( $status, $summary, $owner='', $page='', &$parser ) {
	global $wgScriptPath, $wgTitle;
	$imgTitle = 'Regular task'; $alt = '[ ]';
	$img = '<img src="'.$wgScriptPath.'/images/task';
	switch ($status) {
		case 'x': $img .= '_done'; $alt = '[x]'; $imgTitle = 'Closed task'; break;
		case '!': $img .= '_alert'; $alt = '[!]'; $imgTitle = 'Urgent task'; break;
		case '1': $img .= '_1'; $alt = '[1]'; $imgTitle = 'High priority task'; break;
		case '2': $img .= '_2'; $alt = '[2]'; $imgTitle = 'Medium priority task'; break;
		case '3': $img .= '_3'; $alt = '[3]'; $imgTitle = 'Low priority task'; break;
	}
	$img .= '.png" width="13" height="13" alt="'.$alt.'" title="'.$imgTitle.'" /> ';
 
	if ($owner) { $summary .= ' ([[Special:Tasks/owner='.$owner.'|'.$owner.']])'; }
	if ($page) { $summary = "[[:$page]]: ".$summary; }
 
	$parserOutput = $parser->parse($summary, $parser->mTitle, $parser->mOptions, false, false);
	return $img . ' ' . $parserOutput->getText() . '<br />';
}
 
#-----------------------------------------------#
# Purpose   : Used before saveing a page to clear the tasks buffer.
function clearTasks() {    
	global $tasks_buffer;
	$tasks_buffer = array();
	return 1;
}
 
#-----------------------------------------------#
# Purpose   : Used after a page is saved to first delete
#             all tasks and then save the new ones created
#             in the tasks buffer.
# Parameters: article, The article object.
# rev: 2006-03-12: <calendar> extension will cause double-logging of
# tasks rendered on a sub-page.  "Rebuild" section prevents this.
function saveTasks( $article, $user, $text ) {
	global $tasks_buffer;
	$page_id = $article->getID();
	$dbr =& wfGetDB( DB_MASTER );
	# Delete all tasks for this page.
	$dbr->delete(
		'tasks',
		array( 'page_id' => $page_id )
	);
 
	# Rebuild the $tasks_buffer array (in case we're on a <calendar> page)
	clearTasks();
	$matches = array();
	$elements[] = 'tasks';
 
	$text = Parser::extractTagsAndParams( $elements, $text, $matches );
	foreach( $matches as $marker => $data ) {
		list( $element, $content, $params, $tag ) = $data;
		addToTaskBuffer($content);
	}
 
	# Re-insert all tasks that were created when parseing this page.
	foreach ($tasks_buffer as $task) {
		$task['page_id'] = $page_id;
		$dbr->insert(
				'tasks',
				$task
		);
	}
	return 1;
}

includes/SpecialTasks.php[edit | edit source]

<?php
# MediaWiki Tasks version 0.5.4
# Copyright (c) 2005 Aran Clary Deltac
# http://arandeltac.com/MediaWiki_Tasks
# Copyright (c) 2006 Sylvain Machefert, mods by mhc, Filo, James,
# Guillaume Pratte, Dangerville, OZZ
# http://www.mediawiki.org/wiki/Extension:Tasks_Extension
# Distributed under that same terms as MediaWiki itself.
 
if (!defined('MEDIAWIKI')) die();
 
$wgExtensionFunctions[] = 'wfSpecialTasks' ;
$wgExtensionCredits['specialpage'][] = array(
        'name'=>'Tasks',
        'author'=>'Aran Clary Deltac, [http://meta.wikimedia.org/wiki/User:Iubito Sylvain Machefert]',
        'url'=>'http://www.mediawiki.org/wiki/Extension:Tasks_Extension',
        'description'=>'provides the ability to create tasks on any page of your MediaWiki',
        'version'=>'0.5.4'
);
 
function wfSpecialTasks() {
        require_once('SpecialPage.php');
 
        # complete the messages that will be used :
        global $wgMessageCache ;
                $wgMessageCache->addMessages(array(
                'tasks' => 'Tasks' ,
        ));
 
        class SpecialPage_Tasks extends SpecialPage
        {
                # constructor
                function SpecialPage_Tasks($restriction = '')
                {
                        SpecialPage::SpecialPage('Tasks', $restriction ) ;
                }
 
                # override of the abstract execute() function, manages the output
                function execute($args_string) 
                {
                        global $wgOut, $wgTitle, $wgParser;
                        $page_titles = array();
                        $dbr =& wfGetDB( DB_MASTER );
 
                        # Parse arguments.
                        $args = array();
                        if ($args_string != '') {
                                foreach (explode('&',$args_string) as $pair) {
                                        $pair = explode('=',$pair);
                                        $args[$pair[0]] = $pair[1];
                                }
                        }
 
                        # Define options for the SQL.
                        $options = array( 'ORDER BY'=>'status' );
                        if (isset($args['limit'])) {
                                $options['LIMIT'] = $args['limit'];
                        }
                        if (isset($args['owner'])) {
                                $args['owner'] = str_replace( '_', ' ', $args['owner'] );
                        }
 
                        # Create the WHERE clause.
                        $where = array();
                        //$where[]='tasks.page_id=page.page_id';
                        $where[]='t.page_id=p.page_id';
                        if (isset($args['status'])) {
                                $where[] = 'status<="'.$args['status'].'"';
                        }
                        if (isset($args['owner'])) {
                                $where[] = 'owner="'.$args['owner'].'"';
                        }
                        if (!isset($args['hidden'])) {
                                $where[] = 'hidden="n"';
                        }
 
                        # Run the SQL.
                        
                        /*
                        $res = $dbr->
                        select( array('tasks','page'),
                        array('page.page_id','status','owner','summary','page_namespace'),
                        $where, 'Database::select',$options);
                        */
 
                        $res = $dbr->
                        select( array($dbr->tableName('tasks').' as t',$dbr->tableName('page').' as p'),
                        array('p.page_id','status','owner','summary','page_namespace'),
                        $where, 'Database::select',$options);
                        #select( $table, $vars, $conds='', $fname = 'Database::select', $options = array() )
                        if (!$res) { return; }
 
                        # Set the title for this page.
                        if (isset($args['owner'])) {
                                $wgOut->setPageTitle( $args['owner'].'\'s Tasks' );
                        }
                        else {
                                $wgOut->setPageTitle( 'Tasks' );
                        }
                        # Generate HTML list of tasks.
                        #attach title and options
                        $wgParser->parse('nothing', $wgTitle, new ParserOptions(), false, true);
                        $count = 0;
                        $last_severity = '';
                        while ($task = $dbr->fetchRow( $res )) {
                                if (!isset($page_titles[$task['page_id']])) {
                                        $page_titles[$task['page_id']] =
                                        Title::makeTitle( $task['page_namespace'],
                                        Title::newFromID($task['page_id'])->getText()
                                        );
 
                                }
                                $page_title = $page_titles[$task['page_id']];
                                $wgOut->addHTML(
                                        formatTask(
                                                $task['status'],
                                                $task['summary'],
                                                $task['owner'],
                                                $page_title,
                                                $wgParser)
                                        );
                                $count++;
                        }
                        $dbr->freeResult( $res );
 
                        # Display a message if there are no tasks.
                        if (!$count) {
                                $wgOut->addWikiText('No tasks found!');
                        }
 
                        # http://meta.wikimedia.org/wiki/Talk:Permissions (Error message with MediaWiki v1.6.5)
                        # explains line below
                        $wgOut->setArticleFlag( false );
                }
        }
 
        SpecialPage::addPage ( new SpecialPage_Tasks() ) ;
}

You can restrict access to the page by replacing in the source

SpecialPage::addPage ( new SpecialPage_Tasks() ) ;

by

SpecialPage::addPage ( new SpecialPage_Tasks('onlyuser') ) ;

This will restrict the access to the users with the "onlyuser"-right. If 'onlyuser' is not a naturally available right in MediaWiki (i.e. not listed on User_rights#Available_rights),

  1. add 'onlyuser' to the available rights with this line in LocalSettings.php:
    $wgAvailableRights[] = 'onlyuser';
    
  2. add this line in LocalSettings.php (replace 'user' with any other defined user group you want to give the 'onlyuser' privilege):
    $wgGroupPermissions['user']['onlyuser'] = true;
    

When you go to the SpecialPages as a user with 'onlyuser' right, the Tasks link should appear at the bottom under Restricted special pages (tested on 1.6.5). See also Preventing access to some SpecialPages. --Dangerville 22:14, 24 June 2006 (UTC)

Execute SQL[edit | edit source]

If you are using a prefix on your tables, replace PREFIX_ with your prefix. Otherwise you should create a table just named 'tasks'.

CREATE TABLE PREFIX_tasks (
    page_id INT UNSIGNED NOT NULL DEFAULT 0,
    STATUS ENUM('!','1','2','3',' ','x') NOT NULL DEFAULT ' ',
    owner CHAR(255) NOT NULL,
    summary MEDIUMTEXT NOT NULL,
    hidden ENUM('y','n') NOT NULL DEFAULT 'n',
    KEY owner_idx (owner)
);

Images[edit | edit source]

Right click and save these images into your images/ folder (image names should be lowercase).

Task.png Task 1.png Task 2.png Task 3.png Task alert.png Task done.png

Images hack by tbhot3ww[edit | edit source]

These are other images you can use in your todo

Ntask.png Ntask 1.png Ntask 2.png Ntask 3.png Ntask alert.png Ntask done.png

In order to work as expected modify file Tasks.php and change this line in formatTask function

$img .= '.png" width="13" height="13" alt="'.$alt.'" title="'.$imgTitle.'" /> ';

with this line

$img .= '.png" width="14" height="15" style="margin-top:-3px;" alt="'.$alt.'" title="'.$imgTitle.'" /> ';

LocalSettings.php[edit | edit source]

At the end of LocalSettings.php, add :

include("extensions/Tasks.php");
include("includes/SpecialTasks.php");


All done !

Online demo[edit | edit source]

Somebody please link to a working installation.

License[edit | edit source]

This code is distributed under the same terms as MediaWiki itself.


See also[edit | edit source]