From 1df3d1544db87ca21196b9a888cc20be783427a9 Mon Sep 17 00:00:00 2001 From: rurban Date: Fri, 19 Nov 2004 19:22:52 +0000 Subject: [PATCH] ModeratePage part1: change status git-svn-id: svn://svn.code.sf.net/p/phpwiki/code/trunk@4154 96ab9672-09ca-45d6-a79d-3d69d39ca109 --- lib/WikiDB.php | 49 +++++++-- lib/WikiGroup.php | 8 +- lib/WikiPlugin.php | 9 +- lib/WikiUserNew.php | 11 +- lib/display.php | 9 +- lib/main.php | 23 ++++- lib/plugin/ModeratedPage.php | 191 +++++++++++++++++++++++++++++++++++ pgsrc/ModeratedPage | 14 +-- 8 files changed, 287 insertions(+), 27 deletions(-) create mode 100644 lib/plugin/ModeratedPage.php diff --git a/lib/WikiDB.php b/lib/WikiDB.php index 575a4079f..02c959c29 100644 --- a/lib/WikiDB.php +++ b/lib/WikiDB.php @@ -1,5 +1,5 @@ $users) { if (glob_match($page, $this->_pagename)) { foreach ($users as $userid => $user) { - if (!empty($user['verified']) and !empty($user['email'])) { + if (!$user) { // handle the case for ModeratePage: no prefs, just userid's. + global $request; + $u = $request->getUser(); + if ($u->UserName() == $userid) { + $prefs = $u->getPreferences(); + } else { + // not current user + if (ENABLE_USER_NEW) { + $u = WikiUser($userid); + $u->getPreferences(); + $prefs = &$u->_prefs; + } else { + $u = new WikiUser($GLOBALS['request'], $userid); + $prefs = $u->getPreferences(); + } + } + $emails[] = $prefs->get('email'); + $userids[] = $userid; + } else { + if (!empty($user['verified']) and !empty($user['email'])) { $emails[] = $user['email']; $userids[] = $userid; - } elseif (!empty($user['email'])) { + } elseif (!empty($user['email'])) { global $request; // do a dynamic emailVerified check update $u = $request->getUser(); @@ -934,12 +953,13 @@ class WikiDB_Page } */ } + } } } } $emails = array_unique($emails); $userids = array_unique($userids); - return array($emails,$userids); + return array($emails, $userids); } /** @@ -1136,8 +1156,6 @@ class WikiDB_Page function getLinks($reversed = true, $include_empty=false) { $backend = &$this->_wikidb->_backend; $result = $backend->get_links($this->_pagename, $reversed, $include_empty=false); - //if (empty($this->_iwpcache) and !$include_empty) - // $this->_iwpcache = $result->asArray(); return new WikiDB_PageIterator($this->_wikidb, $result, array('include_empty' => $include_empty)); } @@ -1153,6 +1171,21 @@ class WikiDB_Page function getPageLinks($include_empty=false) { return $this->getLinks(false, $include_empty=false); } + + /** + * possibly faster link existance check. not yet accelerated. + */ + function existLink($link, $reversed = false) { + $cache = &$this->_wikidb->_cache; + // TODO: check cache if it is possible + $iter = $this->getLinks($reversed, false); + while ($page = $iter->next()) { + if ($page->getName() == $link) + return $page; + } + $iter->free(); + return false; + } /** * Access WikiDB_Page meta-data. @@ -2043,6 +2076,10 @@ function _sql_debuglog_shutdown_function() { } // $Log: not supported by cvs2svn $ +// Revision 1.103 2004/11/16 17:29:04 rurban +// fix remove notification error +// fix creation + update id_cache update +// // Revision 1.102 2004/11/11 18:31:26 rurban // add simple backtrace on such general failures to get at least an idea where // diff --git a/lib/WikiGroup.php b/lib/WikiGroup.php index f380abc00..a5ebc33e4 100644 --- a/lib/WikiGroup.php +++ b/lib/WikiGroup.php @@ -1,5 +1,5 @@ specialGroup($group)) { - return getSpecialMembersOf($group); + return $this->getSpecialMembersOf($group); } trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s", 'getMembersOf', GROUP_METHOD), @@ -1096,6 +1096,10 @@ class GroupLdap extends WikiGroup { } // $Log: not supported by cvs2svn $ +// Revision 1.47 2004/11/19 13:23:47 rurban +// +// Another catch by Charles Corrigan: check against the dbi backend, not the WikiDB class. +// // Revision 1.46 2004/11/18 09:52:23 rurban // more safety, requested by Charles Corrigan // diff --git a/lib/WikiPlugin.php b/lib/WikiPlugin.php index 6211844ca..b29df3223 100644 --- a/lib/WikiPlugin.php +++ b/lib/WikiPlugin.php @@ -1,5 +1,5 @@ $val) { - if ($request->getArg('pagename') == _("PhpWikiAdministration") and - $arg == 'overwrite') + if ($request and $request->getArg('pagename') == _("PhpWikiAdministration") + and $arg == 'overwrite') // silence this warning ; else trigger_error(sprintf(_("argument '%s' not declared by plugin"), $arg), E_USER_NOTICE); } - return $args; } diff --git a/lib/WikiUserNew.php b/lib/WikiUserNew.php index 7e8132a53..416d7a6e3 100644 --- a/lib/WikiUserNew.php +++ b/lib/WikiUserNew.php @@ -1,5 +1,5 @@ _page_split($value); @@ -2022,6 +2022,13 @@ extends UserPreferences */ // $Log: not supported by cvs2svn $ +// Revision 1.117 2004/11/10 15:29:21 rurban +// * requires newer Pear_DB (as the internal one): quote() uses now escapeSimple for strings +// * ACCESS_LOG_SQL: fix cause request not yet initialized +// * WikiDB: moved SQL specific methods upwards +// * new Pear_DB quoting: same as ADODB and as newer Pear_DB. +// fixes all around: WikiGroup, WikiUserNew SQL methods, SQL logging +// // Revision 1.116 2004/11/05 21:03:27 rurban // new DEBUG flag: _DEBUG_LOGIN (64) // verbose login debug-msg (settings and reason for failure) diff --git a/lib/display.php b/lib/display.php index f4194c4d4..6e68ab452 100644 --- a/lib/display.php +++ b/lib/display.php @@ -1,6 +1,6 @@ 'redirectfrom'), fmt("(Redirected from %s)", RedirectorLink($redirect_from))); + // abuse the $redirected template var for some status update notice + } elseif ($request->getArg('errormsg')) { + $redirect_message = $request->getArg('errormsg'); + $request->setArg('errormsg', false); } $request->appendValidators(array('pagerev' => $revision->getVersion(), @@ -215,6 +219,9 @@ function displayPage(&$request, $template=false) { } // $Log: not supported by cvs2svn $ +// Revision 1.59 2004/11/17 20:03:58 rurban +// Typo: call SearchHighlight not SearchHighLight +// // Revision 1.58 2004/11/09 17:11:16 rurban // * revert to the wikidb ref passing. there's no memory abuse there. // * use new wikidb->_cache->_id_cache[] instead of wikidb->_iwpcache, to effectively diff --git a/lib/main.php b/lib/main.php index fae662710..144835428 100644 --- a/lib/main.php +++ b/lib/main.php @@ -1,5 +1,5 @@ __PHP_Incomplete_Class_Name) - // There's no way to demandload it later. (This way its slower but needs less memory than loading all) + // There's no way to demandload it later. (This way it's much slower but needs less memory than loading all) if (ALLOW_BOGO_LOGIN) include_once("lib/WikiUser/BogoLogin.php"); foreach ($GLOBALS['USER_AUTH_ORDER'] as $method) { @@ -924,12 +924,24 @@ TODO: check against these cases: $page = $this->getPage(); $page->set('locked', true); $this->_dbi->touch(); + // check ModeratedPage hook + if ($moderated = $page->get('moderated')) { + require_once("lib/WikiPlugin.php"); + $plugin = WikiPluginLoader::getPlugin("ModeratedPage"); + if ($retval = $plugin->lock_check($this, $page, $moderated)) + $this->setArg('errormsg', $retval); + } + // check if a link to ModeratedPage exists + elseif ($action_page = $page->existLink(_("ModeratedPage"))) { + require_once("lib/WikiPlugin.php"); + $plugin = WikiPluginLoader::getPlugin("ModeratedPage"); + if ($retval = $plugin->lock_add($this, $page, $action_page)) + $this->setArg('errormsg', $retval); + } $this->action_browse(); } function action_unlock () { - // FIXME: This check is redundant. - //$user->requireAuth(WIKIAUTH_ADMIN); $page = $this->getPage(); $page->set('locked', false); $this->_dbi->touch(); @@ -1136,6 +1148,9 @@ if (!defined('PHPWIKI_NOMAIN') or !PHPWIKI_NOMAIN) // $Log: not supported by cvs2svn $ +// Revision 1.190 2004/11/15 15:56:40 rurban +// don't load PagePerm on ENABLE_PAGEPERM = false to save memory. Move mayAccessPage() to main.php +// // Revision 1.189 2004/11/09 17:11:16 rurban // * revert to the wikidb ref passing. there's no memory abuse there. // * use new wikidb->_cache->_id_cache[] instead of wikidb->_iwpcache, to effectively diff --git a/lib/plugin/ModeratedPage.php b/lib/plugin/ModeratedPage.php new file mode 100644 index 000000000..f59b225c9 --- /dev/null +++ b/lib/plugin/ModeratedPage.php @@ -0,0 +1,191 @@ + '[pagename]', + 'moderators' => false, + 'require_level' => false, // 1=bogo + 'require_access' => 'edit,remove,change', + 'id' => '', + 'pass' => '', + ); + } + + function run($dbi, $argstr, &$request, $basepage) { + $args = $this->getArgs($argstr, $request); + + // handle moderation request from the email + if (!empty($args['id']) and !empty($args['pass'])) { + if (!$args['page']) + return $this->error("No page specified"); + $page = $dbi->getPage($args['page']); + $moderation = $page->get("moderation"); + if ($moderation) { + if (isset($moderation['id']) and $moderation['id'] == $args['id']) { + // handle defaults: + // approve or reject + if ($args['pass'] == 'approve') + return $this->approve($args, $moderation); + elseif ($args['pass'] == 'reject') + return $this->reject($args, $moderation); + else + return $this->error("Wrong pass ".$args['pass']); + } else { + return $this->error("Wrong id"); + } + } + } + return ''; + } + + /** + * resolve moderators and require_access from actionpage plugin argstr + */ + function resolve_argstr(&$request, $argstr) { + $args = $this->getArgs($argstr); + $group = $request->getGroup(); + if (empty($args['moderators'])) { + $admins = $group->getSpecialMembersOf(GROUP_ADMIN); + // email or usernames? + $args['moderators'] = array_merge($admins, array(ADMIN_USER)); + } else { + // resolve possible group names + $moderators = explode(',',$args['moderators']); + for ($i=0; $igetMembersOf($moderators[$i]); + if (!empty($members)) { + array_splice($moderators,$i,1,$members); + } + } + if (!$moderators) $moderators = array(ADMIN_USER); + $args['moderators'] = $moderators; + } + //resolve email for $args['moderators'] + $page = $request->getPage(); + $users = array(); + foreach ($args['moderators'] as $userid) { + $users[$userid] = 0; + } + list($args['emails'], $args['moderators']) = $page->getPageChangeEmails(array($page->getName() => $users)); + unset($args['id']); + unset($args['page']); + unset($args['pass']); + return $args; + } + + /** + * Handle moderation change request by the user. + * Hook called on the lock action, if moderation metadata already exists. + */ + function lock_check(&$request, &$page, $moderated) { + $action_page = $request->getPage(_("ModeratedPage")); + $old_moderation = $this->getStatus($request, $page, $action_page); + if (is_array($old_moderation)) { + $page->set('moderation', $moderation); + return $this->notice( + fmt("ModeratedPage status update:\n Moderators: '%s'\n require_access: '%s'", + join(',',$moderation['moderators']), $moderation['require_access'])); + } else { + $page->set('moderation', false); + return $this->notice(HTML($old_moderation, + fmt("'%s' is no ModeratedPage anymore.", $page->getName()))); + } + } + + /** + * Handle moderation change request by the user. + * Hook called on the lock action, if moderation metadata should be added. + * Need to store the the plugin args (who, when) in the page meta-data + */ + function lock_add(&$request, &$page, &$action_page) { + $moderation = $this->getStatus($request, $page, $action_page); + if (is_array($moderation)) { + $page->set('moderation', $moderation); + return $this->notice( + fmt("ModeratedPage status update: '%s' is now a ModeratedPage.\n Moderators: '%s'\n require_access: '%s'", + $page->getName(), join(',',$moderation['moderators']), $moderation['require_access'])); + } + else { // error + return $moderation; + } + } + + function notice($msg) { + return HTML::div(array('class' => 'wiki-edithelp'), $msg); + } + + function getStatus(&$request, &$page, &$action_page) { + $loader = new WikiPluginLoader(); + $rev = $action_page->getCurrentRevision(); + $content = $rev->getPackedContent(); + list($pi) = explode("\n", $content, 2); // plugin ModeratedPage must be first line! + if ($parsed = $loader->parsePI($pi)) { + $plugin =& $parsed[1]; + if ($plugin->getName() != _("ModeratedPage")) + return $this->error(sprintf(_(" not found in first line of %s"), + $action_page->getName())); + if (!$action_page->get('locked')) + return $this->error(sprintf(_("%s is not locked!"), + $action_page->getName())); + return $plugin->resolve_argstr($request, $parsed[2]); + } else { + return $this->error(sprintf(_(" not found in first line of %s"), + $action_page->getName())); + } + } + +}; + +// $Log: not supported by cvs2svn $ + +// For emacs users +// Local Variables: +// mode: php +// tab-width: 8 +// c-basic-offset: 4 +// c-hanging-comment-ender-p: nil +// indent-tabs-mode: nil +// End: +?> \ No newline at end of file diff --git a/pgsrc/ModeratedPage b/pgsrc/ModeratedPage index 834405e24..75391846f 100644 --- a/pgsrc/ModeratedPage +++ b/pgsrc/ModeratedPage @@ -1,9 +1,9 @@ -Date: Fri, 19 Nov 2004 14:27:36 +0100 +Date: Fri, 19 Nov 2004 16:26:00 +0100 Mime-Version: 1.0 (Produced by PhpWiki 1.3.11pre) -X-Rcs-Id: $Id: ModeratedPage,v 1.1 2004-11-19 13:34:51 rurban Exp $ +X-Rcs-Id: $Id: ModeratedPage,v 1.2 2004-11-19 19:22:52 rurban Exp $ Content-Type: application/x-phpwiki; pagename=ModeratedPage; - pgsrc_version="2 $Revision: 1.1 $"; + pgsrc_version="2 $Revision: 1.2 $"; flags=LOCKED; markup=2; charset=iso-8859-1 @@ -18,12 +18,12 @@ Content-Transfer-Encoding: binary A ModeratedPage is a page-internal setting, which restricts certain actions on certain pages. The requested action and page is stored internally and an email is sent to the moderators described in the linked and locked ModeratedPage action page. -Any moderator may approved or rejected the action by simply clicking an url. -When approving the action, the requested action is performed. +Any moderator may approve or reject the action by simply clicking an url. +When approving the action, the requested action (edit, rename, ...) is performed. In both cases the author is notified, so it's recommended for the moderator to click on either the approve or reject links in the moderation email. -First comes, first serves. +In case of multiple moderators: first comes, first serves. !!! How to enable ModeratedPage on a single page? @@ -66,7 +66,7 @@ follow for the moderator. !!! How to enable ModeratedPage on multiple/all pages? -If you enable the config option ENABLE_PAGEMODERATION_ALL, the page moderation status on +If you enable the config option ENABLE_MODERATEDPAGE_ALL, the page moderation status on every page is automatically set to check this action page ModeratedPage. There may come another administrative plugin to change the moderation -- 2.45.0