First a warning, I am new to php and mysql, what I did was mostly trial and trial and trial and lots of errors - so if you find redudant code or you have suggestions for improvements , please tell me!
What does it do?
This hack of mine gives the users the possibility to mark pageupdates as minor changes (typos etc.). I also wrote an action called "recentmajorchanges" which allows the user to see only major, only minor or all changes during a number of days.What has to be changed?
- a new field calles "minorchanges" has to be added to the table "wikka_pages" in the MYSQL database
- the function SavePage in wakka.class.php has to be changed
- the function ChangedDuringLastDays is "new"
- the edit handler has to be updated
- the action recentmajorchanges is "new"
Known Issues
the handler "clone" throws a warning. Just add a ",0" to the SavePage(...) function call, i.e. $this->SavePage($to, $pagecontent, $note,0); #create target page.
I don't know if there are calls to SavePage anywhere else. If so, these actions etc. will also throw a warning, but they should work despite the warning.
to do
- better layout of recentmajorchanges
- mark minor changes when 'all' changes are beeing displayed
- userspecific default number of days to display?
- maybe sort all edits of one particular Page together, show only edit notes, date and history link if Page is not latest
- Layout of this page
- ...
Change to the MYSQL Database
As a fist step you have to add a cell to the table "pages" in the MYSQL Database called "minorchange", which consists of a boolean value. FALSE or 0 meaning "no minor change", TRUE or !=0 means "minorchange"
the MYSQL Query is:
NOTE: I'm assuming you use the standart table prefix wikka_ here!
The PHP Code
Changes in /libs/wakka.class.php
SavePage
The function SavePage in /libs/wakka.class.php has to be altered to be able to save the minorchange flag. inserted lines are commented function SavePage($tag, $body, $note, $minorchange) //editet by FishPete
{
if (!isset($minorchange)) $minorchange='0';// inserted by FishPete; if SavePage is called without the $minorchange parameter, assume no minorchange and continue
// get current user
$user = $this->GetUserName();
// TODO: check write privilege
if ($this->HasAccess("write", $tag))
{
// is page new?
if (!$oldPage = $this->LoadPage($tag))
{
// current user is owner if user is logged in, otherwise, no owner.
if ($this->GetUser()) $owner = $user;
}
else
{
// aha! page isn't new. keep owner!
$owner = $oldPage["owner"];
}
// set all other revisions to old
$this->Query("update ".$this->config["table_prefix"]."pages set latest = 'N' where tag = '".mysql_real_escape_string($tag)."'");
// add new revision
$this->Query("insert into ".$this->config["table_prefix"]."pages set ".
"tag = '".mysql_real_escape_string($tag)."', ".
"time = now(), ".
"owner = '".mysql_real_escape_string($owner)."', ".
"user = '".mysql_real_escape_string($user)."', ".
"note = '".mysql_real_escape_string($note)."', ".
"latest = 'Y', ".
"minorchange = ".$minorchange.", ". // inserted by FishPete
"body = '".mysql_real_escape_string($body)."'");
if ($pingdata = $this->GetPingParams($this->config["wikiping_server"], $tag, $user, $note))
$this->WikiPing($pingdata);
}
}
{
if (!isset($minorchange)) $minorchange='0';// inserted by FishPete; if SavePage is called without the $minorchange parameter, assume no minorchange and continue
// get current user
$user = $this->GetUserName();
// TODO: check write privilege
if ($this->HasAccess("write", $tag))
{
// is page new?
if (!$oldPage = $this->LoadPage($tag))
{
// current user is owner if user is logged in, otherwise, no owner.
if ($this->GetUser()) $owner = $user;
}
else
{
// aha! page isn't new. keep owner!
$owner = $oldPage["owner"];
}
// set all other revisions to old
$this->Query("update ".$this->config["table_prefix"]."pages set latest = 'N' where tag = '".mysql_real_escape_string($tag)."'");
// add new revision
$this->Query("insert into ".$this->config["table_prefix"]."pages set ".
"tag = '".mysql_real_escape_string($tag)."', ".
"time = now(), ".
"owner = '".mysql_real_escape_string($owner)."', ".
"user = '".mysql_real_escape_string($user)."', ".
"note = '".mysql_real_escape_string($note)."', ".
"latest = 'Y', ".
"minorchange = ".$minorchange.", ". // inserted by FishPete
"body = '".mysql_real_escape_string($body)."'");
if ($pingdata = $this->GetPingParams($this->config["wikiping_server"], $tag, $user, $note))
$this->WikiPing($pingdata);
}
}
ChangedDuringLastDays
I wrote a function to display changes during the last days to be used instead of LoadRecentlyChanged() Just insert it right after the function LoadRecentlyChanged()
/*$interval: number of days which should be displayed
* $show: whether to show all, only major or only minor changes
* returns array of pages which were changed during the last ($interval) days and are according to $show criteria
*/
function LoadChangedDuringLastDays($interval, $show)
{
switch ($show)
{
case 'all':
$param=''; //no additional parameter in the MYSQL Query
break;
case 'major':
$param='AND minorchange = 0'; //to be used in the MYSQL Query
break;
case 'minor':
$param='AND minorchange !=0'; //to be used in the MYSQL Query
break;
}
if ($pages = $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where time> DATE_SUB(now(),INTERVAL ".$interval." DAY) ".$param." order by time desc"))
{
foreach ($pages as $page)
{
$this->CachePage($page);
}
return $pages;
}
}
* $show: whether to show all, only major or only minor changes
* returns array of pages which were changed during the last ($interval) days and are according to $show criteria
*/
function LoadChangedDuringLastDays($interval, $show)
{
switch ($show)
{
case 'all':
$param=''; //no additional parameter in the MYSQL Query
break;
case 'major':
$param='AND minorchange = 0'; //to be used in the MYSQL Query
break;
case 'minor':
$param='AND minorchange !=0'; //to be used in the MYSQL Query
break;
}
if ($pages = $this->LoadAll("select * from ".$this->config["table_prefix"]."pages where time> DATE_SUB(now(),INTERVAL ".$interval." DAY) ".$param." order by time desc"))
{
foreach ($pages as $page)
{
$this->CachePage($page);
}
return $pages;
}
}
Changes in /handlers/page/edit.php
The next thing to do is add a checkbox to /handlers/pages/edit.php which allows the user to mark a change as a minor one. Since the little code changes are all over the place in this file I'll post the whole file on MinorEditHackEditPHP. The lines I changed are commented with " edited by FishPete. Just search for FishPete in the file and it should take you to the new lines.
29.6.06: I just added a line to edit.php to show the checkbox during "preview mode". -FishPete
The action RecentMajorChanges
This file is mainly the action recentchanges which I altered a bit. Save this code as /actions/recentmajorchanges.php
I took out the user specific maximum of changes to show, but its easy to take it back in. just un-comment the lines .
Pages which were edited twice appear twice in the list. That's a feature, not a bug ;-)
- 4.7.2006: minor change, I just altered RECENT_MAJOR_CHANGES_HEADER etc. to get rid of WORD_FOR_DAY and altered the echo statement which uses these definitions. The lines are marked with edited 4.7.2006 --FishPete
<?php
/**
* Display a list of recently changed pages, distinguishes between major and minor changes
*
* @package Actions
* @name RecentChanges
*
* @author {@link http://www.mornography.de/ Hendrik Mans} (wakka code)
* @author {@link http://wikkawiki.org/DarTar Dario Taraborelli} (preliminary code cleanup)
* @author {@link http://wikkawiki.org/FishPete Peter Fischaleck} (minor changes hack)
* @param: $days_to_show: how many days of changes should be displayed.
* @param: $what_to_show: eather 'minor', 'major' or 'all' changes should be displayed
*
*/
//defaults
if(!defined('REVISION_DATE_FORMAT')) define('REVISION_DATE_FORMAT', 'D, d M Y');
if(!defined('REVISION_TIME_FORMAT')) define('REVISION_TIME_FORMAT', 'H:i T');
if (!defined('PAGE_EDITOR_DIVIDER')) define ('PAGE_EDITOR_DIVIDER', '→');
if (!defined('MAX_REVISION_NUMBER')) define ('MAX_REVISION_NUMBER', '50');
//i18n
if (!defined('RECENT_MAJOR_CHANGES_HEADING')) define('RECENT_MAJOR_CHANGES_HEADING', '=====Major Changes During the Last %s Day(s)====='); //edited 4.7.2006
if (!defined('RECENT_MINOR_CHANGES_HEADING')) define('RECENT_MINOR_CHANGES_HEADING', '=====Minor Changes During the Last %s Day(s)====='); //edited 4.7.2006
if (!defined('All_RECENT_CHANGES_HEADING')) define('ALL_RECENT_CHANGES_HEADING', '=====Changes During the Last %s Day(s)====='); //edited 4.7.2006
// if (!defined('WORD_FOR_DAY')) define ('WORD_FOR_DAY', ' Day(s)'); //edited 4.7.2006
if (!defined('SHOW_ALL_BUTTON_TEXT')) define ('SHOW_ALL_BUTTON_TEXT', 'show all changes');
if (!defined('SHOW_MINOR_BUTTON_TEXT')) define ('SHOW_MINOR_BUTTON_TEXT', 'show only minor changes');
if (!defined('SHOW_MAJOR_BUTTON_TEXT')) define ('SHOW_MAJOR_BUTTON_TEXT', 'show only major changes');
if (!defined('UNREGISTERED_USER')) define('UNREGISTERED_USER', 'unregistered user ');
if (!defined('LABEL_HISTORY')) define('LABEL_HISTORY', 'history');
if (!defined('TITLE_REVISION_LINK')) define('TITLE_REVISION_LINK', 'View recent revisions list for %s');
if (!defined('TITLE_HISTORY_LINK')) define('TITLE_HISTORY_LINK', 'View edit history of %s');
if (!defined('WIKIPING_ENABLED')) define('WIKIPING_ENABLED', 'WikiPing enabled: Changes on this wiki are broadcast to <a href="http://%1$s">http://%1$s</a>');
if (!defined('NO_RECENTLY_CHANGED_PAGES')) define ('NO_RECENTLY_CHANGED_PAGES', 'There are no recently changed pages.');
if (!defined('NO_READABLE_RECENTLY_CHANGED_PAGES')) define ('NO_READABLE_RECENTLY_CHANGED_PAGES', 'There are no recently changed pages you have access to.');
//initialization
//$max = 0;
$readable = 0;
//defaults
if ( !isset($days_to_show)) $days_to_show = 7;
$what_to_show = 'major';
$heading=RECENT_MAJOR_CHANGES_HEADING;
// get the parameters
if (is_array($vars))
{
foreach ($vars as $param => $value)
{
switch ($param)
{
case 'days':
$days_to_show = $value;
break;
case 'show':
switch ($value)
{
case ('all'):
$what_to_show='all';
$heading = ALL_RECENT_CHANGES_HEADING;
break;
case ('minor'):
$what_to_show='minor';
$heading = RECENT_MINOR_CHANGES_HEADING;
break;
case ('major'):
$what_to_show='major';
$heading=RECENT_MAJOR_CHANGES_HEADING;
break;
}
}
}
}
if (isset($_REQUEST['show_minor']))
{
if (isset($_REQUEST['days']) && ($_REQUEST['days']>0)) $days_to_show=$_REQUEST['days'];
$what_to_show='minor';
$heading = RECENT_MINOR_CHANGES_HEADING;
}
if (isset($_REQUEST['show_major']))
{
if (isset($_REQUEST['days'])&& ($_REQUEST['days']>0)) $days_to_show=$_REQUEST['days'];
$what_to_show='major';
$heading = RECENT_MAJOR_CHANGES_HEADING;
}
if (isset($_REQUEST['show_all']))
{
if (isset($_REQUEST['days'])&& ($_REQUEST['days']>0)) $days_to_show=$_REQUEST['days'];
$what_to_show='all';
$heading = ALL_RECENT_CHANGES_HEADING;
}
echo $this->FormOpen("", "", "get");
echo('
<p>
Show pages changed up unto
<input name="days" type="text", size="1" maxlenght="2" value="'.$days_to_show.'"> days ago<br>
<input name="show_major" type="submit" value="'.SHOW_MAJOR_BUTTON_TEXT.'">
<input name="show_minor" type="submit" value="'.SHOW_MINOR_BUTTON_TEXT.'">
<input name="show_all" type="submit" value="'.SHOW_ALL_BUTTON_TEXT.'"></p>
');
echo $this->FormClose();
echo $this->Format(sprintf($heading, $days_to_show).' --- '); //edited 4.7.2006
if ($pages = $this->LoadChangedDuringLastDays($days_to_show, $what_to_show)) //edited by FishPete
{
$curday = '';
//print feed link icon
//echo '<p><a href="'.$this->href('recentchanges.xml', $this->page['tag']).'"><img src="images/xml.png" width="36" height="14" alt="XML" /></a></p>'."\n";
/*if ($user = $this->GetUser())
{
$max = $user['changescount'];
} else
{
$max = MAX_REVISION_NUMBER;
}*/
//foreach ($pages as $i => $page)
foreach ($pages as $page)
{
//if (($i < $max) && $this->HasAccess('read', $page['tag']))
if ($this->HasAccess('read', $page['tag'])) //edited by FishPete
{
$readable++;
// day header
list($day, $time) = explode(' ', $page['time']);
if ($day != $curday)
{
$dateformatted = date(REVISION_DATE_FORMAT, strtotime($day));
if ($curday)
{
echo '</span><br />'."\n";
}
echo '<strong>'.$dateformatted.':</strong><br />'."\n".'<span class="recentchanges">'."\n";
$curday = $day;
}
$timeformatted = date(REVISION_TIME_FORMAT, strtotime($page["time"]));
$page_edited_by = $page['user'];
if (!$this->LoadUser($page_edited_by)) $page_edited_by .= ' ('.UNREGISTERED_USER.')';
// print entry
if ($page['note'])
{
$note = ' <span class="pagenote">['.$this->htmlspecialchars_ent($page['note']).']</span>';
}
else
{
$note = '';
}
echo ' ('.$this->Link($page['tag'], 'revisions', $timeformatted, 0, 1, sprintf(TITLE_REVISION_LINK, $page['tag'])).') ['.$this->Link($page['tag'], 'history', LABEL_HISTORY, 0, 1, sprintf(TITLE_HISTORY_LINK, $page['tag'])).'] - '.$this->Link($page['tag'], '', '', 0).' '.PAGE_EDITOR_DIVIDER.' '.$page_edited_by.' '.$note.'<br />'."\n";
}
}
if ($readable == 0)
{
echo '<em>'.NO_READABLE_RECENTLY_CHANGED_PAGES.'</em>';
}
echo '</span>'."\n";
//wikiping instructions
$wikipingserver = $this->config['wikiping_server'];
if (!$wikipingserver == '')
{
$wikipingserver_url_parsed = parse_url($wikipingserver);
$wikipingserver_host = $wikipingserver_url_parsed['host'];
printf('<br /><br />['.WIKIPING_ENABLED.']', $wikipingserver_host);
}
}
else
{
echo '<em>'.NO_RECENTLY_CHANGED_PAGES.'</em>';
}
echo $this->Format(' ::c:: ');
?>
/**
* Display a list of recently changed pages, distinguishes between major and minor changes
*
* @package Actions
* @name RecentChanges
*
* @author {@link http://www.mornography.de/ Hendrik Mans} (wakka code)
* @author {@link http://wikkawiki.org/DarTar Dario Taraborelli} (preliminary code cleanup)
* @author {@link http://wikkawiki.org/FishPete Peter Fischaleck} (minor changes hack)
* @param: $days_to_show: how many days of changes should be displayed.
* @param: $what_to_show: eather 'minor', 'major' or 'all' changes should be displayed
*
*/
//defaults
if(!defined('REVISION_DATE_FORMAT')) define('REVISION_DATE_FORMAT', 'D, d M Y');
if(!defined('REVISION_TIME_FORMAT')) define('REVISION_TIME_FORMAT', 'H:i T');
if (!defined('PAGE_EDITOR_DIVIDER')) define ('PAGE_EDITOR_DIVIDER', '→');
if (!defined('MAX_REVISION_NUMBER')) define ('MAX_REVISION_NUMBER', '50');
//i18n
if (!defined('RECENT_MAJOR_CHANGES_HEADING')) define('RECENT_MAJOR_CHANGES_HEADING', '=====Major Changes During the Last %s Day(s)====='); //edited 4.7.2006
if (!defined('RECENT_MINOR_CHANGES_HEADING')) define('RECENT_MINOR_CHANGES_HEADING', '=====Minor Changes During the Last %s Day(s)====='); //edited 4.7.2006
if (!defined('All_RECENT_CHANGES_HEADING')) define('ALL_RECENT_CHANGES_HEADING', '=====Changes During the Last %s Day(s)====='); //edited 4.7.2006
// if (!defined('WORD_FOR_DAY')) define ('WORD_FOR_DAY', ' Day(s)'); //edited 4.7.2006
if (!defined('SHOW_ALL_BUTTON_TEXT')) define ('SHOW_ALL_BUTTON_TEXT', 'show all changes');
if (!defined('SHOW_MINOR_BUTTON_TEXT')) define ('SHOW_MINOR_BUTTON_TEXT', 'show only minor changes');
if (!defined('SHOW_MAJOR_BUTTON_TEXT')) define ('SHOW_MAJOR_BUTTON_TEXT', 'show only major changes');
if (!defined('UNREGISTERED_USER')) define('UNREGISTERED_USER', 'unregistered user ');
if (!defined('LABEL_HISTORY')) define('LABEL_HISTORY', 'history');
if (!defined('TITLE_REVISION_LINK')) define('TITLE_REVISION_LINK', 'View recent revisions list for %s');
if (!defined('TITLE_HISTORY_LINK')) define('TITLE_HISTORY_LINK', 'View edit history of %s');
if (!defined('WIKIPING_ENABLED')) define('WIKIPING_ENABLED', 'WikiPing enabled: Changes on this wiki are broadcast to <a href="http://%1$s">http://%1$s</a>');
if (!defined('NO_RECENTLY_CHANGED_PAGES')) define ('NO_RECENTLY_CHANGED_PAGES', 'There are no recently changed pages.');
if (!defined('NO_READABLE_RECENTLY_CHANGED_PAGES')) define ('NO_READABLE_RECENTLY_CHANGED_PAGES', 'There are no recently changed pages you have access to.');
//initialization
//$max = 0;
$readable = 0;
//defaults
if ( !isset($days_to_show)) $days_to_show = 7;
$what_to_show = 'major';
$heading=RECENT_MAJOR_CHANGES_HEADING;
// get the parameters
if (is_array($vars))
{
foreach ($vars as $param => $value)
{
switch ($param)
{
case 'days':
$days_to_show = $value;
break;
case 'show':
switch ($value)
{
case ('all'):
$what_to_show='all';
$heading = ALL_RECENT_CHANGES_HEADING;
break;
case ('minor'):
$what_to_show='minor';
$heading = RECENT_MINOR_CHANGES_HEADING;
break;
case ('major'):
$what_to_show='major';
$heading=RECENT_MAJOR_CHANGES_HEADING;
break;
}
}
}
}
if (isset($_REQUEST['show_minor']))
{
if (isset($_REQUEST['days']) && ($_REQUEST['days']>0)) $days_to_show=$_REQUEST['days'];
$what_to_show='minor';
$heading = RECENT_MINOR_CHANGES_HEADING;
}
if (isset($_REQUEST['show_major']))
{
if (isset($_REQUEST['days'])&& ($_REQUEST['days']>0)) $days_to_show=$_REQUEST['days'];
$what_to_show='major';
$heading = RECENT_MAJOR_CHANGES_HEADING;
}
if (isset($_REQUEST['show_all']))
{
if (isset($_REQUEST['days'])&& ($_REQUEST['days']>0)) $days_to_show=$_REQUEST['days'];
$what_to_show='all';
$heading = ALL_RECENT_CHANGES_HEADING;
}
echo $this->FormOpen("", "", "get");
echo('
<p>
Show pages changed up unto
<input name="days" type="text", size="1" maxlenght="2" value="'.$days_to_show.'"> days ago<br>
<input name="show_major" type="submit" value="'.SHOW_MAJOR_BUTTON_TEXT.'">
<input name="show_minor" type="submit" value="'.SHOW_MINOR_BUTTON_TEXT.'">
<input name="show_all" type="submit" value="'.SHOW_ALL_BUTTON_TEXT.'"></p>
');
echo $this->FormClose();
echo $this->Format(sprintf($heading, $days_to_show).' --- '); //edited 4.7.2006
if ($pages = $this->LoadChangedDuringLastDays($days_to_show, $what_to_show)) //edited by FishPete
{
$curday = '';
//print feed link icon
//echo '<p><a href="'.$this->href('recentchanges.xml', $this->page['tag']).'"><img src="images/xml.png" width="36" height="14" alt="XML" /></a></p>'."\n";
/*if ($user = $this->GetUser())
{
$max = $user['changescount'];
} else
{
$max = MAX_REVISION_NUMBER;
}*/
//foreach ($pages as $i => $page)
foreach ($pages as $page)
{
//if (($i < $max) && $this->HasAccess('read', $page['tag']))
if ($this->HasAccess('read', $page['tag'])) //edited by FishPete
{
$readable++;
// day header
list($day, $time) = explode(' ', $page['time']);
if ($day != $curday)
{
$dateformatted = date(REVISION_DATE_FORMAT, strtotime($day));
if ($curday)
{
echo '</span><br />'."\n";
}
echo '<strong>'.$dateformatted.':</strong><br />'."\n".'<span class="recentchanges">'."\n";
$curday = $day;
}
$timeformatted = date(REVISION_TIME_FORMAT, strtotime($page["time"]));
$page_edited_by = $page['user'];
if (!$this->LoadUser($page_edited_by)) $page_edited_by .= ' ('.UNREGISTERED_USER.')';
// print entry
if ($page['note'])
{
$note = ' <span class="pagenote">['.$this->htmlspecialchars_ent($page['note']).']</span>';
}
else
{
$note = '';
}
echo ' ('.$this->Link($page['tag'], 'revisions', $timeformatted, 0, 1, sprintf(TITLE_REVISION_LINK, $page['tag'])).') ['.$this->Link($page['tag'], 'history', LABEL_HISTORY, 0, 1, sprintf(TITLE_HISTORY_LINK, $page['tag'])).'] - '.$this->Link($page['tag'], '', '', 0).' '.PAGE_EDITOR_DIVIDER.' '.$page_edited_by.' '.$note.'<br />'."\n";
}
}
if ($readable == 0)
{
echo '<em>'.NO_READABLE_RECENTLY_CHANGED_PAGES.'</em>';
}
echo '</span>'."\n";
//wikiping instructions
$wikipingserver = $this->config['wikiping_server'];
if (!$wikipingserver == '')
{
$wikipingserver_url_parsed = parse_url($wikipingserver);
$wikipingserver_host = $wikipingserver_url_parsed['host'];
printf('<br /><br />['.WIKIPING_ENABLED.']', $wikipingserver_host);
}
}
else
{
echo '<em>'.NO_RECENTLY_CHANGED_PAGES.'</em>';
}
echo $this->Format(' ::c:: ');
?>
CategoryUserContributions