userXtension

OBSOLETE BY userXtension v2.0

Read in english.

Die userXtension ist eigentlich kein Plugin, sondern eine Erweiterung des Wikis ansich. Ziel war es, bestimmten Benutzern die Möglichkeit zu geben, ähnlich wie bei dem Adminplugin bestimmte Aufgaben zu übernehmen und diese Benutzerspezifisch zu behandeln.

Bsp.: Ich wollte mein Kalender Plugin so auslegen, dass die Benutzer einen eigenen Kalender pflegen können, dabei aber nicht auf Daten anderer Nutzer zugreifen dürfen. Dabei hat der Administrator des Wikis die Möglichkeit alle Kalender zu überwachen.

Die Lösung bestand wie erwähnt in einer kleinen Änderung der Engine:

Datei /inc/actions.php
In der Funktion act_dispatch() sucht ihr den Abschnitt if($ACT == ‘admin’){} und gebt darunter folgenden Code ein:

	//handle user tasks
	if($ACT == 'user'){
		// retrieve user plugin name from $_REQUEST['page']
		if ($_REQUEST['page']) {
			$pluginlist = plugin_list('user');
			if (in_array($_REQUEST['page'], $pluginlist)) {
				// attempt to load the plugin
				if ($plugin =& plugin_load('user',$_REQUEST['page']) !== NULL)
	        		      $plugin->handle();
			}
		}
	}

Das bewirkt, dass der Befehlsaufruf do=user erkannt und verarbeitet wird. Er schaut auch nach, welche Plugins überhaupt die userXtension benutzen.

In der Funktion function act_clean($act) ersetzt Ihr:

	if(!$conf['useacl'] && in_array($act,array('login','logout','register','admin',
                                             'subscribe','unsubscribe','profile',
                                             'resendpwd',))){

durch:

	if(!$conf['useacl'] && in_array($act,array('login','logout','register','admin','user',
                                             'subscribe','unsubscribe','profile',
                                             'resendpwd',))){

Ich glaube, dass hier alle Aktionen gecancelt werden die in das System eingreifen wollen, falls acl abgeschaltet ist.

und ihr ersetzt

	if(array_search($act,array('login','logout','register','save','edit',
                             'preview','search','show','check','index','revisions',
                             'diff','recent','backlink','admin','subscribe',
                             'unsubscribe','profile','resendpwd',)) === false

durch:

	if(array_search($act,array('login','logout','register','save','edit',
                             'preview','search','show','check','index','revisions',
                             'diff','recent','backlink','admin','user','subscribe',
                             'unsubscribe','profile','resendpwd',)) === false

Die Wirkung besteht darin, zu prüfen, welche Befehle überhaupt an das Wiki übergeben werden dürfen.

In der Funktion act_permcheck($act) fügt Ihr unter:

	}elseif($act == 'admin'){
		$permneed = AUTH_ADMIN;

noch zusätzlich den Code:

	}elseif($act == 'user'){
		$permneed = AUTH_CREATE;

Damit stellt ihr sicher, ab welche Authorisierungsstufe die Benutzer die userXtension nutzen dürfen. Ich habe mich für AUTH_CREATE entschieden, was die vorletzte Stufe im System ist. Ich fänd es aber sinnvoll die Rechtestrucktur dahingehen zu ändern, dass ein zusätzliches AUTH_USER eingebaut würde, um die Nutzung zu authorisieren.

Weiter geht es in der Datei /inc/html.php. Dort sind einige Ersetzungen zu tun.

ersetzt:

	function html_admin(){

durch:

	function html_admin($user=NULL){ // extend call for admin page with user page

ersetzt:

	  print p_locale_xhtml('admin');

durch:

	  print p_locale_xhtml($user?'user':'admin'); // call user or admin intro

ersetzt:

	  $pluginlist = plugin_list('admin');

durch:

	  $pluginlist = plugin_list($user?'user':'admin'); // get user or admin plugin list

ersetzt:

	    if($obj =& plugin_load('admin',$p) === NULL) continue;

durch:

	    if($obj =& plugin_load($user?'user':'admin',$p) === NULL) continue; // load user or admin plugin

ersetzt:

	  if (!$conf['openregister']){

durch:

	  if (!$conf['openregister'] && !$user){ // if not open for registering and the call was not from a user, include the 'register new user' part

ersetzt:

	  ptln('  <li><div class="li"><a href="'.wl($ID, 'do=admin&amp;page='.$item['plugin']).'">'.$item['prompt'].'</a></div></li>');

durch:

	  ptln('  <li><div class="li"><a href="'.wl($ID, 'do=' . ($user?'user':'admin') .  '&amp;page='.$item['plugin']).'">'.$item['prompt'].'</a></div></li>'); // create link to plugin with the discision to load the user or admin part

So, das waren alle Änderungen an den System Dateien. Zum Abschluss müsst ihr im Plugin Verzeichniss eine Datei anlegen, die, genauso wie die admin.php, den Prototypen für die User enthält.

/lib/plugins/user.php

<?php
/**
 * User Plugin Prototype
 * 
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Christopher Smith <chris@jalakai.co.uk>
 * @author     Gerry Weissbach <gerry.w@gammaproduction.de>
 */
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');

/**
 * All DokuWiki plugins to extend the user function
 * need to inherit from this class
 */
class DokuWiki_User_Plugin {

  var $localised = false;        // set to true by setupLocale() after loading language dependent strings
  var $lang = array();           // array to hold language dependent strings, best accessed via ->getLang()

  /**
   * General Info
   *
   * Needs to return a associative array with the following values:
   *
   * author - Author of the plugin
   * email  - Email address to contact the author
   * date   - Last modified date of the plugin in YYYY-MM-DD format
   * name   - Name of the plugin
   * desc   - Short description of the plugin (Text only)
   * url    - Website with more information on the plugin (eg. syntax description)
   */
  function getInfo(){
    trigger_error('getInfo() not implemented in '.get_class($this), E_USER_WARNING);
  }

  function getMenuText($language) {
      $menutext = $this->getLang('menu');
      if (!$menutext) {
        $info = $this->getInfo();
        $menutext = $info['name'].' ...';
      }
      return $menutext;
  }

  function getMenuSort() {
    return 1000;
  }

  function handle() {
    trigger_error('handle() not implemented in '.get_class($this), E_USER_WARNING); 
  }

  function html() {
    trigger_error('html() not implemented in '.get_class($this), E_USER_WARNING); 
  }
  
  // private methods (maybe a dokuwiki plugin base class is required for these)
  
  // plugin introspection methods
  // extract from class name, format = <plugin type>_plugin_<name>[_<component name>]
  function getPluginType() { list($t) = explode('_', get_class($this), 2); return $t;  }

  function getPluginName() { list($t, $p, $n) = explode('_', get_class($this), 4); return $n; }
  function getPluginComponent() { list($t, $p, $n, $c) = explode('_', get_class($this), 4); return (isset($c)?$c:''); }

  // localisation methods
  /**
   * getLang($id)
   * use this function to access plugin language strings
   * to try to minimise unnecessary loading of the strings when the plugin doesn't require them
   * e.g. when info plugin is querying plugins for information about themselves.
   *
   * @param   $id     id of the string to be retrieved
   * @return  string  string in appropriate language or english if not available
   */
  function getLang($id) {
    if (!$this->localised) $this->setupLocale();
    
    return (isset($this->lang[$id]) ? $this->lang[$id] : '');
  }
  
  /**
   * locale_xhtml($id)
   *
   * retrieve a language dependent file and pass to xhtml renderer for display
   * plugin equivalent of p_locale_xhtml()
   *
   * @param   $id     id of language dependent wiki page
   * @return  string  parsed contents of the wiki page in xhtml format
   */
  function locale_xhtml($id) {
    return p_cached_xhtml($this->localFN($id));
  }
  
  /**
   * localFN($id)
   * prepends appropriate path for a language dependent filename
   * plugin equivalent of localFN()
   */
  function localFN($id) {
    global $conf;
    $plugin = $this->getPluginName();
    $file = DOKU_PLUGIN.$plugin.'/lang/'.$conf['lang'].'/'.$id.'.txt';
    if(!@file_exists($file)){
      //fall back to english
      $file = DOKU_PLUGIN.$plugin.'/lang/en/'.$id.'.txt';
    }
    return $file;
  }
  
  /**
   *  setupLocale() 
   *  reads all the plugins language dependent strings into $this->lang
   *  this function is automatically called by getLang()
   */
  function setupLocale() {
    if ($this->localised) return;

    global $conf;            // definitely don't invoke "global $lang"
    $path = DOKU_PLUGIN.$this->getPluginName().'/lang/';

    $lang = array();
 
    // don't include once, in case several plugin components require the same language file
    @include($path.'en/lang.php');    
    if ($conf['lang'] != 'en') @include($path.$conf['lang'].'/lang.php');
    
    $this->lang = $lang;
    $this->localised = true;
  }
  
  // standard functions for outputing email addresses and links
  // use these to avoid having to duplicate code to produce links in line with the installation configuration
  function email($email, $name='', $class='', $more='') {
    if (!$email) return $name;
    $email = obfuscate($email);
    if (!$name) $name = $email;
    $class = "class='".($class ? $class : 'mail')."'";
    return "<a href='mailto:$email' $class title='$email' $more>$name</a>";
  }
  
  function external_link($link, $title='', $class='', $target='', $more='') {
    global $conf;
    
    $link = htmlentities($link);
    if (!$title) $title = $link;
    if (!$target) $target = $conf['target']['extern'];
    if ($conf['relnofollow']) $more .= ' rel="nofollow"';
    
    if ($class) $class = " class='$class'";
    if ($target) $target = " target='$target'";
    if ($more) $more = " ".trim($more);
                
    return "<a href='$link'$class$target$more>$title</a>";
  }
                
  // output text string through the parser, allows dokuwiki markup to be used
  // very ineffecient for small pieces of data - try not to use
  function render($text, $format='xhtml') {
    return p_render($format, p_get_instructions($text),$info); 
  }
  
  // deprecated functions
  function plugin_localFN($id) { return $this->localFN($id); }
  function plugin_locale_xhtml($id) { return $this->locale_xhtml($id); }
  function plugin_email($e, $n='', $c='', $m='') { return $this->email($e, $n, $c, $m); }
  function plugin_link($l, $t='', $c='', $to='', $m='') { return $this->external_link($l, $t, $c, $to, $m); }
  function plugin_render($t, $f='xhtml') { return $this->render($t, $f); }
  
}
//Setup VIM: ex: et ts=4 enc=utf-8 :

Wie ihr es es nun von den Adminplugins gewohnt seid erstellt ihr eine user.php im Pluginverzeichniss. Die innere Strucktur ist identisch mit der admin.php.

Wie bei allen Neuentwicklungen gibt es keine 100%ige Garantie, dass bei eurer Implementierung alles auf Anhieb funktioniert. Ich empfehle daher die Änderungen zunächst in einer Testumgebung zu machen. Kopiert dazu am Besten euer Wiki und mach dort zuerst die Anpassung und testet es dann. Bei Fragen, Wünschen oder sonstigem: gerry.w@gammaproduction.de wählen

So, dass war es. Viel Spaß beim Ausprobieren.

authoring tool: counter
content: © 2012 Gerry Weißbach @ gammaproduction.de