tas2580
Blog über Webentwicklung

Eigene Berechtigungen

Für manche Extensions ist es nötig das man zusätzliche Berechtigungen einführt um nur bestimmten Benutzern Zugang zu bestimmten Bereichen der Extension zu geben. Dazu kann man zwar schon vorhandene Rechte wie z.B. a_ (alle Administratoren) oder m_ (alle Moderatoren) benutzen, wenn man aber gezieht einzelnen Benutzern oder Gruppen das Recht geben will in der Extension etwas zu tun benötigt man ein komplett neues Recht.

Neues Recht anlegen

Als erstes muss man das Recht in der Datenbank anlegen, dazu benötigt man im Ordner /migrations eine Migrations Datei die bei der Installation der Extension ausgeführt wird. Der Name der Datei ist egal, hier muss man allerdings beachten das jede Migrations Datei nur ein mal ausgeführt wird, wenn man die Datei also später ändern möchte muss man die Extension komplett deinstallieren oder eine weitere Datei anlegen. Das kann beim entwickeln einer Extension teilweise etwas ärgerlich sein da man die Extension nicht schon am Anfang mit mehreren Migration Dateien ausliefern möchte und so mit jeder Änderung die Extension komplett neu installieren muss und so auch jedes mal alle von der Extension gespeicherten Daten verliert.
Am besten man legt für die erste Veröffentlichung eine Datei mit dem Namen initial_module.php an und dann bei jedem Update eine weitere Datei mit dem Namen update_version.php, also z.B. update_0_1_1.php bei einem Update auf Version 0.1.1.

In der Datei kann man Änderungen an der Datenbank durchführen und eben auch neue Rechte anlegen. Der Code Dazu ist recht simpel:

	public function update_data()
	{
		return array(
			array('permission.add', array('u_mein_recht', true, 'u_viewprofile')),
		);
	}

In der Methode update_data werden alle Änderungen die man an Daten in der Datenbank machen möchte angegeben, mit permission.add wird angegeben das man ein neues Recht hinzufügen möchte, wenn man das Recht mit einem späteren Update der Extension wieder entfernen möchte macht man hier einfach permission.remove.
Das Array kann die folgenden Werte enthalten:

  • u_mein_recht Der Name des Rechts das man hinzufügen möchte.
  • true Gibt an das es sich um ein globales Recht handelt, wenn man hier false angibt wird das Recht zu einem lokalen Recht das für jedes Forum einzeln vergeben werden kann.
  • u_viewprofile Gibt das Recht an von dem das neue Recht geerbt werden soll, hier bekommen also nach der Installation alle Benutzer die das Recht u_viewprofile haben auch das Recht u_mein_recht.
Jedes Recht hat einen Präfix der angibt um welche Art von Recht es sich handelt, hier stehen die folgenden Präfixe zur Verfügung:
  • u_ Rechte für normale Benutzer
  • m_ Rechte für Moderatoren.
  • a_ Rechte für Administratoren.
  • f_ Lokale Rechte die nur in bestimmten Foren gelten.

Wenn man ein neues Recht anlegt muss man einen der hier angegebenen Präfixe verwenden, unser Recht u_mein_recht ist also ein Recht für normale Benutzer da der Name des Rechts mit u_ beginnt.

Die komplette Datei /migrations/initial_module.php
<?php
/**
*
* @package phpBB Extension - bar
* @copyright (c) 2015 foo (https://example.com)
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/

namespace foo\bar\migrations;

class initial_module extends \phpbb\db\migration\migration
{
	public function update_data()
	{
		return array(
			array('permission.add', array('u_mein_recht', true, 'u_viewprofile')),
		);
	}
}

Hier ist wichtig das die Klasse gleich wie die Datei heißt, wenn also der Dateiname initial_module.php lautet muss die Klasse auch initial_module heißen (class initial_module extends \phpbb\db\migration\migration).

Wenn man später ein Update machen möchte um z.B. weitere Rechte hinzuzufügen erstellt man einfach eine weitere Migrations Datei mit einem anderen Namen und fügt da noch eine Methode mit dem Namen depends_on hinzu in der man angibt auf welcher Migrations Datei die Änderung bassiert.
	public static function depends_on()
	{
		return array(
			'\foo\bar\migrations\initial_module',
		);
	}

Das Recht in Rechteverwaltung

Damit das Recht auch im Administrationsbereich angezeigt und später geändert werden kann muss man es dort noch hinzufügen. Dazu muss man seine Events der Extension erweitern.
Hier muss zu erst in die Methode getSubscribedEvents das neue Event hinzugefügt werden:

			'core.permissions'			=> 'permissions',

Jetzt kann man seine eigene Methode hinzufügen in der man die neu angelegten Rechte im Administrationsbereich verfügbar macht. Da wir angegeben haben das wir dazu die Methode permissions verwenden muss man die neue Methode auch so nennen.

	/**
	 * Add permissions
	 *
	 * @param	object	$event	The event object
	 * @return	null
	 * @access	public
	 */
	public function permissions($event)
	{
		$permissions = $event['permissions'];
		$permissions += array(
			'u_mein_recht'	=> array(
				'lang'		=> 'ACL_U_MEIN_RECHT',
				'cat'		=> 'misc'
			),
		);
		$event['permissions'] = $permissions;
	}

In der ersten Zeile der Methode wird der Event Parameter einer lokalen Variable zugewiesen die man dann ändern kann ($permissions = $event['permissions'];), danach wird die Variable einfach erweitert ($permissions += array().
Für jedes Recht muss nun $permissions um ein Array mit dem Namen des Rechts erweitert werden, da unser Recht hier u_mein_recht heißt ist der Wert des Arrays auch u_mein_recht. In dem Array wird dann angegeben welche Sprachvariable, die man später noch anlegen muss, verwendet werden soll und in welcher Kategorie das Recht aufgelistet werden soll.
Falls man mehrere Rechte hinzufügen möchte kann man hier einfach das Array beliebig erweitern und für jedes Recht ein weiteres Array hinzufügen.

		$permissions += array(
			'u_mein_recht'	=> array(
				'lang'		=> 'ACL_U_MEIN_RECHT',
				'cat'		=> 'misc'
			),
			'u_noch_ein_recht'	=> array(
				'lang'		=> 'ACL_U_NOCH_EIN_RECHT',
				'cat'		=> 'misc'
			),
		);

Eigene Kategorie

Wer sehr viele neue Rechte anlegt kann auch eine eigene Kategorie dafür anlegen, dazu erweitert man den Code einfach um:

		$categories['meine_kategorie'] = 'ACL_CAT_MEINE_KATEGORIE';
		$event['categories'] = array_merge($event['categories'], $categories);

Man teilt der neuen Kategorie also einfach eine Sprachvariable zu und erweitert dann das Array $event['categories'] um seine hinzugefügte Sprachvariable. Jetzt kann man die Kategorie für seine Rechte verwenden in dem man dort einfach statt 'cat' => 'misc' seine Kategorie angibt 'cat' => 'meine_kategorie'.

Die Sprachdatei

Damit im Administrationsbereich nicht nur die Sprachvariablen ausgegeben werden benötigt man noch eine Sprachdatei für seine Rechte. Die Datei muss den Namen permissions_EXTENSIONNAME.php haben und unter /language/de/ liegen. Der Aufbau der Datei ist wie bei normalen Sprachdateien auch.

Die komplette Datei /language/de/permissions_bar.php
<?php
/**
*
* @package phpBB Extension - bar
* @copyright (c) 2015 foo (https://example.com)
* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
*
*/
/**
* DO NOT CHANGE
*/
if (!defined('IN_PHPBB'))
{
	exit;
}
if (empty($lang) || !is_array($lang))
{
	$lang = array();
}
// DEVELOPERS PLEASE NOTE
//
// All language files should use UTF-8 as their encoding and the files must not contain a BOM.
//
// Placeholders can now contain order information, e.g. instead of
// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows
// translators to re-order the output of data while ensuring it remains correct
//
// You do not need this where single placeholders are used, e.g. 'Message %d' is fine
// equally where a string contains only two placeholders which are used to wrap text
// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine
//
// Some characters you may want to copy&paste:
// ’ » “ ” …
//
$lang = array_merge($lang, array(
	'ACL_U_MEIN_RECHT'				=> 'Kann mein Recht',
	'ACL_CAT_MEINE_KATEGORIE'		=> 'Meine Kategorie',
));

Jetzt hat man das neue Recht vollständig in phpBB intigriert und kann es in seiner Extension benutzen.

Das Recht benutzen

Damit man überhaupt Rechte benutzen kann muss man seinem Controller das Object $auth übergeben, dazu erweitert man zu erst die arguments in seiner config/services.yml um - @auth und fügt das Object in den Controler ein:

public function __construct(\phpbb\auth\auth $auth, ...

Danach noch mit $this->auth = $auth; das Object lokal zuweißen damit man es in allen Methoden innerhalb des Controllers verwenden kann.

Jetzt kann man an beliebiger Stelle abfragen ob der Benutzer der die Seite aufruft das Recht hat oder nicht:

if (!$this->auth->acl_get('u_mein_recht'))
{
	trigger_error('NOT_AUTHORISED');
}

Hier wird den Benutzer eine Fehlermeldung angezeigt wenn er ohne das Recht zu haben versucht die Seite aufzurufen. Wenn man nur bestimmte Code Teile ausführen möchte falls der Benutzer das Recht hat kann man auch das auf dem gleichen Weg tun:

if ($this->auth->acl_get('u_mein_recht'))
{
	// Hier Code der für Benutzer mit dem Recht ausgeführt wird
}
else
{
	// Hier Code der für Benutzer ohne das Recht ausgeführt wird
}

Wenn man das Recht im Template benutzen möchte um bestimmten HTML Code nur für Benutzer anzuzeigen die das Recht haben muss man es in seinem Controller dem Template eine Variable dafür zuweisen. Dafür erweitert man einfach das Array in dem man Variablen an das Template zuweist um 'S_MEIN_RECHT' => $this->auth->acl_get('u_mein_recht') erweitert.
Jetzt kann man über die Variable im Template abfragen ob der aktuelle Benutzer das Recht hat oder nicht.

<!-- IF S_MEIN_RECHT -->
	HTML Code für Benutzer die das Recht haben
<!-- ELSE -->
	HTML Code für Benutzer die das Recht nicht haben
<!-- ENDIF -->