jenkins-bot has submitted this change and it was merged.

Change subject: GenericTagExtensionHandler: Basic impl.
......................................................................


GenericTagExtensionHandler: Basic impl.

This change adds a generic tag handler mechanism to BlueSpice.

* Adds dependency to ParamProcessor library
* Adds some generic stylings for differen output types (errors,
  hints, ...)

TODO:
* Add unit tests
* Implement more param definitions

Patch Set 11: implemented i18n and cc

Change-Id: I06ea08e5a1ad789806a7648bd4cf03b5b911e12f
---
M .gitignore
M BlueSpice.hooks.php
M BlueSpiceFoundation.php
M composer.json
M i18n/core/de.json
M i18n/core/en.json
M i18n/core/qqq.json
M includes/AutoLoader.php
M includes/CoreHooks.php
M includes/DefaultSettings.php
M includes/ExtensionMW.class.php
M includes/ExtensionManager.class.php
A includes/GenericTagExtensionHandler.php
A includes/exception/BSInvalidParamException.php
R includes/exception/InvalidNamespaceException.class.php
A includes/paramdefinition/BSNamespaceListParam.php
A includes/paramdefinition/BSTitleListParam.php
A includes/parser/BSNamespaceParser.php
A includes/parser/BSTitleParser.php
A includes/validator/BSNamespaceValidator.php
A includes/validator/BSTitleValidator.php
M resources/Resources.php
A resources/bluespice/bluespice.ui.basic.less
23 files changed, 909 insertions(+), 20 deletions(-)

Approvals:
  Mglaser: Looks good to me, approved
  Pwirth: Looks good to me, but someone else must approve
  jenkins-bot: Verified

Objections:
  Raimond Spekking: There's a problem with this change, please improve



diff --git a/.gitignore b/.gitignore
index 8980552..8ba05c5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,6 @@
 config/
 node_modules/**
 vendor/**
+
+composer.lock
+composer.phar
diff --git a/BlueSpice.hooks.php b/BlueSpice.hooks.php
index a6a621c..62b422c 100644
--- a/BlueSpice.hooks.php
+++ b/BlueSpice.hooks.php
@@ -12,7 +12,9 @@
 $wgHooks['UploadVerification'][] = 'BsCoreHooks::onUploadVerification';
 $wgHooks['SkinTemplateOutputPageBeforeExec'][] = 
'BsCoreHooks::onSkinTemplateOutputPageBeforeExec';
 $wgHooks['SkinAfterContent'][] = 'BsCoreHooks::onSkinAfterContent';
+$wgHooks['ParserFirstCallInit'][] = 'BsCoreHooks::onParserFirstCallInit';
 $wgHooks['UserAddGroup'][] = 'BsGroupHelper::addTemporaryGroupToUserHelper';
+#$wgHooks['UnitTestsList'][] = 'BsCoreHooks::onUnitTestsList';
 
 // START cache invalidation hooks
 $wgHooks['PageContentSaveComplete'][] = 
'BsCacheHelper::onPageContentSaveComplete';
diff --git a/BlueSpiceFoundation.php b/BlueSpiceFoundation.php
index bf6cdc7..e117f04 100644
--- a/BlueSpiceFoundation.php
+++ b/BlueSpiceFoundation.php
@@ -53,6 +53,10 @@
        "alt" => "Powered by BlueSpice",
 );
 
+if ( is_readable( __DIR__ . '/vendor/autoload.php' ) ) {
+       include_once( __DIR__ . '/vendor/autoload.php' );
+}
+
 require_once( __DIR__."/includes/AutoLoader.php");
 require_once( __DIR__."/includes/Defines.php" );
 require_once( __DIR__."/includes/DefaultSettings.php" );
@@ -101,6 +105,26 @@
 #$wgSpecialPages['Diagnostics'] = 'SpecialDiagnostics';
 $wgSpecialPages['SpecialCredits'] = 'SpecialCredits';
 
+if( !isset( $GLOBALS['wgParamDefinitions'] ) ) {
+       $GLOBALS['wgParamDefinitions'] = array();
+}
+
+$GLOBALS['wgParamDefinitions'] += array(
+       'titlelist' => array(
+               'definition' => 'BSTitleListParam',
+               'string-parser' => 'BSTitleParser',
+               'validator' => 'BSTitleValidator',
+       ),
+       'namespacelist' => array(
+               'definition' => 'BSNamespaceListParam',
+               'string-parser' => 'BSNamespaceParser',
+               'validator' => 'BSNamespaceValidator',
+       )
+       //TODO:
+       //'title', 'category', 'user', 'usergroup'
+       //'categorylist', 'userlist', 'usergrouplist'
+);
+
 // Register hooks
 require_once( 'BlueSpice.hooks.php' );
 //Setup
diff --git a/composer.json b/composer.json
index fa64b11..c15e12b 100644
--- a/composer.json
+++ b/composer.json
@@ -15,6 +15,9 @@
                        "homepage": "http://www.hallowelt.com";
                }
        ],
+       "require": {
+               "param-processor/param-processor": "~1.2"
+       },
        "require-dev": {
                "jakub-onderka/php-parallel-lint": "0.9.2"
        },
diff --git a/i18n/core/de.json b/i18n/core/de.json
index a9a194d..cac16be 100644
--- a/i18n/core/de.json
+++ b/i18n/core/de.json
@@ -74,5 +74,13 @@
        "bs-pref-anonuserimage": "Avatar für anonyme Benutzer:",
        "bs-pref-deleteduserimage": "Avatar für gelöschte Benutzer:",
        "bs-pref-bspinginterval": "Ping-Intervall (in Sekunden):",
-       "bs-pref-testmode": "Testmodus aktivieren"
+       "bs-pref-testmode": "Testmodus aktivieren",
+       "bs-tag-input-desc": "Wert des Elementinhalts",
+       "bs-tag-param-desc": "Wert der Elementeigenschaft '$1'",
+       "bs-parser-error-invalid-namespace": "Ungültiger Namensraum: $1",
+       "bs-parser-error-invalid-title": "Ungültiger Titel: $1",
+       "bs-validator-error-namespace-does-not-exist": "Namensraum existiert 
nicht: $1",
+       "bs-validator-error-namespace-on-blacklist": "Namensraum nicht erlaubt: 
$1",
+       "bs-validator-error-title-does-not-exist": "Seite existiert nicht: $1",
+       "bs-validator-error-title-namespace-on-blacklist": "Seite nicht 
erlaubt: $1"
 }
diff --git a/i18n/core/en.json b/i18n/core/en.json
index 5d68399..81962db 100644
--- a/i18n/core/en.json
+++ b/i18n/core/en.json
@@ -78,5 +78,13 @@
        "bs-pref-deleteduserimage": "Deleted user avatar:",
        "bs-pref-bspinginterval": "Ping interval (in seconds):",
        "bs-pref-testmode": "Activate test mode",
-       "specialpages-group-bluespice": "{{int:prefs-base}}"
+       "specialpages-group-bluespice": "{{int:prefs-base}}",
+       "bs-tag-input-desc": "Value of element content",
+       "bs-tag-param-desc": "Value of element attribute '$1'",
+       "bs-parser-error-invalid-namespace": "Invalid namespace: $1",
+       "bs-parser-error-invalid-title": "Invalid title: $1",
+       "bs-validator-error-namespace-does-not-exist": "Namespace does not 
exist: $1",
+       "bs-validator-error-namespace-on-blacklist": "Namespace not allowed: 
$1",
+       "bs-validator-error-title-does-not-exist": "Page does not exist: $1",
+       "bs-validator-error-title-namespace-on-blacklist": "Page not allowed: 
$1"
 }
\ No newline at end of file
diff --git a/i18n/core/qqq.json b/i18n/core/qqq.json
index 3511c0a..63bd8f7 100644
--- a/i18n/core/qqq.json
+++ b/i18n/core/qqq.json
@@ -82,5 +82,13 @@
        "bs-pref-deleteduserimage": "Option in 
[{{canonicalurl:Special:WikiAdmin|mode=Preferences}} 
Special:WikiAdmin?mode=Preferences], label for deleted user avatar",
        "bs-pref-bspinginterval": "Option in 
[{{canonicalurl:Special:WikiAdmin|mode=Preferences}} 
Special:WikiAdmin?mode=Preferences], label for ping interval (in seconds)",
        "bs-pref-testmode": "Option in 
[{{canonicalurl:Special:WikiAdmin|mode=Preferences}} 
Special:WikiAdmin?mode=Preferences], label for activate test mode",
-       "specialpages-group-bluespice": "Used in [[Special:SpecialPages]], 
headline of BlueSpice section. Message is referenced to message of BlueSpice 
preference section.\n\nRefers to {{msg-mw|Prefs-base}}."
+       "specialpages-group-bluespice": "Used in [[Special:SpecialPages]], 
headline of BlueSpice section. Message is referenced to message of BlueSpice 
preference section.\n\nRefers to {{msg-mw|Prefs-base}}.",
+       "bs-tag-input-desc": "Description of the 'input' part of a tag 
extension. The 'input' is everything that is placed between the opening and the 
closing element of the tag extension",
+       "bs-tag-param-desc": "Description of a 'parameter' part of a tag 
extension. A 'parameter' is everything that is defined using attributes of the 
tag extension's element.\n\nParameters:\n* $1 - the name of the attribute",
+       "bs-parser-error-invalid-namespace": "Error message in case a string 
could not be parsed into a valid namespace id.\n\nParameters:\n* $1 - the 
original string value",
+       "bs-parser-error-invalid-title": "Error message in case a string could 
not be parsed into a valid Title object.\n\nParameters:\n* $1 - the original 
string value",
+       "bs-validator-error-namespace-does-not-exist": "Error message in case a 
given namespace id does not exist.\n\nParameters:\n* $1 - the namespace id",
+       "bs-validator-error-namespace-on-blacklist": "Error message in case a 
given namespace id is on the blacklist.\n\nParameters:\n* $1 - the namespace 
id",
+       "bs-validator-error-title-does-not-exist": "Error message in case a 
given Title object does not exist.\n\nParameters:\n* $1 - the prefixed text of 
the Title",
+       "bs-validator-error-title-namespace-on-blacklist": "Error message in 
case the namespace of a given Title object is on the 
blacklist.\n\nParameters:\n* $1 - the prefixed text of the Title"
 }
diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php
index f281935..912ac2d 100644
--- a/includes/AutoLoader.php
+++ b/includes/AutoLoader.php
@@ -37,6 +37,13 @@
 $GLOBALS['wgAutoloadClasses']['BSDebug'] = __DIR__."/Debug.php";
 $GLOBALS['wgAutoloadClasses']['BsException'] = __DIR__."/Exception.class.php";
 $GLOBALS['wgAutoloadClasses']['BsExtensionManager'] = 
__DIR__."/ExtensionManager.class.php";
+$GLOBALS['wgAutoloadClasses']['BsGenericTagExtensionHandler'] = 
__DIR__."/GenericTagExtensionHandler.php";
+$GLOBALS['wgAutoloadClasses']['BSTitleListParam'] = 
__DIR__."/paramdefinition/BSTitleListParam.php";
+$GLOBALS['wgAutoloadClasses']['BSTitleParser'] = 
__DIR__."/parser/BSTitleParser.php";
+$GLOBALS['wgAutoloadClasses']['BSTitleValidator'] = 
__DIR__."/validator/BSTitleValidator.php";
+$GLOBALS['wgAutoloadClasses']['BSNamespaceListParam'] = 
__DIR__."/paramdefinition/BSNamespaceListParam.php";
+$GLOBALS['wgAutoloadClasses']['BSNamespaceParser'] = 
__DIR__."/parser/BSNamespaceParser.php";
+$GLOBALS['wgAutoloadClasses']['BSNamespaceValidator'] = 
__DIR__."/validator/BSNamespaceValidator.php";
 $GLOBALS['wgAutoloadClasses']['BsMailer'] = 
__DIR__."/Mailer.class.php";//Deprecated
 $GLOBALS['wgAutoloadClasses']['BsXHRBaseResponse'] = 
__DIR__."/XHRBaseResponse.class.php";
 $GLOBALS['wgAutoloadClasses']['BsXHRJSONResponse'] = 
__DIR__."/XHRBaseResponse.class.php";
@@ -73,7 +80,8 @@
 
 //adapter
 $GLOBALS['wgAutoloadClasses']['BsExtensionMW'] = 
__DIR__."/ExtensionMW.class.php";
-$GLOBALS['wgAutoloadClasses']['BsInvalidNamespaceException'] = 
__DIR__."/InvalidNamespaceException.class.php";
+$GLOBALS['wgAutoloadClasses']['BsInvalidNamespaceException'] = 
__DIR__."/exception/InvalidNamespaceException.class.php";
+$GLOBALS['wgAutoloadClasses']['BSInvalidParamException'] = 
__DIR__."/exception/BSInvalidParamException.php";
 
 //htmlform and htmlformfields
 $GLOBALS['wgAutoloadClasses']['HTMLFormEx'] = 
__DIR__."/html/htmlformfields/HTMLFormFieldOverrides.php";
diff --git a/includes/CoreHooks.php b/includes/CoreHooks.php
index a8ea815..0b72a81 100755
--- a/includes/CoreHooks.php
+++ b/includes/CoreHooks.php
@@ -539,4 +539,38 @@
                        'content' => $oProfilePageSettingsView
                );
        }
+
+       /**
+        *
+        * @param Parser $parser
+        * @return boolean Always true to keep hook running
+        */
+       public static function onParserFirstCallInit( $parser ) {
+               BsGenericTagExtensionHandler::setupHandlers(
+                       BsExtensionManager::getRunningExtensions(),
+                       $parser
+               );
+               return true;
+       }
+
+       /**
+        * Register PHP Unit Tests with MediaWiki framework
+        * @param array $files
+        * @return boolean Always true to keep hook running
+        */
+       public static function onUnitTestsList( &$files ) {
+               $oIterator = new RecursiveIteratorIterator(
+                       new RecursiveDirectoryIterator( dirname( __DIR__ ) . 
'/tests/' )
+               );
+               /**
+                * @var SplFileInfo $oFileInfo
+                */
+               foreach ( $oIterator as $oFileInfo ) {
+                       if ( substr( $oFileInfo->getFilename(), -8 ) === 
'Test.php' ) {
+                               $files[] = $oFileInfo->getPathname();
+                       }
+               }
+
+               return true;
+       }
 }
diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 75b4704..c8b9330 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -209,5 +209,11 @@
        //From http://tools.wmflabs.org/styleguide/desktop/section-2.html
        'bs-color-progressive' => '#347bff',
        'bs-color-contructive' => '#00af89',
-       'bs-color-destructive' => '#d11d13'
-);
+       'bs-color-destructive' => '#d11d13',
+
+       //Message boxes
+       'bs-color-success' => '#dff0d8',
+       'bs-color-warning' => '#fcf8e3',
+       'bs-color-error' => '#f2dede',
+       'bs-color-info' => '#d9edf7',
+);
\ No newline at end of file
diff --git a/includes/ExtensionMW.class.php b/includes/ExtensionMW.class.php
index 64a7f7f..f98369a 100644
--- a/includes/ExtensionMW.class.php
+++ b/includes/ExtensionMW.class.php
@@ -135,4 +135,12 @@
                        $sSubKey
                );
        }
+
+       /**
+        * Returns an array of tag extension definitions
+        * @return array
+        */
+       public function makeTagExtensionDefinitions() {
+               return array();
+       }
 }
diff --git a/includes/ExtensionManager.class.php 
b/includes/ExtensionManager.class.php
index 8c86a69..64128f8 100644
--- a/includes/ExtensionManager.class.php
+++ b/includes/ExtensionManager.class.php
@@ -15,6 +15,10 @@
 class BsExtensionManager {
 
        protected static $prRegisteredExtensions = array();
+       /**
+        *
+        * @var BsExtensionMW[]
+        */
        protected static $prRunningExtensions = array();
        protected static $aContexts = array();
        protected static $aActiveContexts = array();
@@ -68,15 +72,32 @@
                wfProfileOut( 'Performance: ' . __METHOD__ );
        }
 
+       /**
+        *
+        * @return array
+        * @deprecated since version 2.23
+        */
        public static function getRegisteredExtenions() {
                wfDeprecated( __METHOD__ );
                return self::$prRegisteredExtensions;
        }
 
+       /**
+        *
+        * @return array
+        */
        public static function getRegisteredExtensions() {
                return self::$prRegisteredExtensions;
        }
 
+       /**
+        *
+        * @return BsExtensionMW[]
+        */
+       public static function getRunningExtensions() {
+               return self::$prRunningExtensions;
+       }
+
        public static function includeExtensionFiles( $oCore ) {
                wfProfileIn( 'Performance: ' . __METHOD__ );
                global $IP;
diff --git a/includes/GenericTagExtensionHandler.php 
b/includes/GenericTagExtensionHandler.php
new file mode 100644
index 0000000..60eba2b
--- /dev/null
+++ b/includes/GenericTagExtensionHandler.php
@@ -0,0 +1,315 @@
+<?php
+/**
+ * Provides a generic tag extension mechanism for BlueSpice.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This file is part of BlueSpice for MediaWiki
+ * For further information visit http://www.blue-spice.org
+ *
+ * @author     Robert Vogel <[email protected]>
+ * @package    Bluespice_Foundation
+ * @copyright  Copyright (C) 2016 Hallo Welt! - Medienwerkstatt GmbH, All 
rights reserved.
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License v2 or 
later
+ * @filesource
+ */
+
+/**
+ * BsGenericTagExtensionHandler class in BlueSpice
+ * @package BlueSpice_Foundation
+ */
+class BsGenericTagExtensionHandler {
+
+       /**
+        * The registered element name that is used within the WikiText
+        * @var string
+        */
+       protected $sTagName = '';
+
+       /**
+        * An array that contains basic settings fot the tag and includes a
+        * ParamProcessor\ParamDefinition compatible list of parameter settings
+        * @var array
+        */
+       protected $aTagDef = array();
+
+       public function __construct( $sTagName, $aTagDef ) {
+               $this->sTagName = $sTagName;
+               $this->aTagDef = $this->extendTagDefinition( $aTagDef );
+       }
+
+       /**
+        * @param BsExtensionMW[] $aExtensions
+        * @param Parser $parser
+        */
+       public static function setupHandlers( $aExtensions, $parser ) {
+               foreach( $aExtensions as $oExtension ) {
+                       $aExtensionTags = 
$oExtension->makeTagExtensionDefinitions();
+                       foreach( $aExtensionTags as $sTagName => $aTagDef ) {
+                               $oTagHandler = new self( $sTagName, $aTagDef );
+                               $parser->setHook( $sTagName, array( 
$oTagHandler, 'handle' ) );
+                       }
+               }
+       }
+
+       /**
+        * Does the actual tag handling and outputs the HTML
+        * @param string $input
+        * @param array $args
+        * @param Parser $parser
+        * @param PPFrame $frame
+        * @return string
+        */
+       public function handle( $input, array $args, Parser $parser, PPFrame 
$frame ) {
+               if( $this->aTagDef['disableParserCache'] === true ) {
+                       $parser->disableCache();
+               }
+
+               if( $this->aTagDef['parseInput'] === true ) {
+                       $input = $parser->recursiveTagParse( $input );
+               }
+
+               if( $this->aTagDef['parseParams'] === true ) {
+                       foreach( $args as $iKey => $sValue ) {
+                               $args[$iKey] = $parser->recursiveTagParse( 
$sValue );
+                       }
+               }
+
+               $aElementClasses = $this->aTagDef['classes'];
+               $aElementClasses[] = 'bs-tag';
+               $aElementClasses[] = $this->makeElementClassName();
+
+               $aAttributes = array();
+               if( $this->aTagDef['titleMsg'] !== null ) {
+                       $aAttributes[ 'title' ] = wfMessage( 
$this->aTagDef['titleMsg'] )->plain();
+               }
+
+               $sContent = '';
+               try {
+                       $aProcessedInput = $this->processInput( $input );
+                       $aProcessedArgs = $this->processArgs( $args );
+
+                       $aAttributes['params'] = FormatJson::encode( 
$aProcessedArgs );
+                       $parser->getOutput()->setProperty(
+                               'bs-tag-'.$this->sTagName, 
$aAttributes['params']
+                       );
+
+                       if( is_callable( $this->aTagDef['callback'] ) ) {
+                               $sContent = call_user_func_array(
+                                       $this->aTagDef['callback'],
+                                       array(
+                                               $aProcessedInput, 
$aProcessedArgs, $parser, $frame
+                                       )
+                               );
+                       }
+               } catch ( Exception $ex ) {
+                       $sContent = $this->makeExceptionOutput( $ex );
+                       $aElementClasses[] = 'bs-tag-error';
+               }
+
+               $aAttributes['class'] = implode( ' ', $aElementClasses );
+
+               return Html::rawElement(
+                       $this->aTagDef['element'],
+                       $aAttributes,
+                       $sContent
+               );
+       }
+
+       /**
+        * Checks if a type/validation definition for the input content of an
+        * element exists and processes it accordingly
+        * @param string $input
+        * @return mixed
+        * @throws Exception
+        */
+       protected function processInput( $input ) {
+               if( $this->aTagDef['input'] === null ) {
+                       return $input;
+               }
+
+               $aInputParams = array(
+                       'input' => $input
+               );
+
+               $oProcessor = ParamProcessor\Processor::newDefault();
+               $oProcessor->setParameters(
+                       $aInputParams,
+                       array(
+                               array(
+                                       'name' => 'input',
+                                       'message' => wfMessage( 
'bs-tag-input-desc' )->plain()
+                               )
+                               + $this->aTagDef['input']
+                       )
+               );
+
+               $oResult = $oProcessor->processParameters();
+               $this->checkForProcessingErrors( $oResult );
+               $aProcessedParams = $oResult->getParameters();
+
+               return $aProcessedParams['input']->getValue();
+       }
+
+       /**
+        * Checks if a type/validation definition for the arguments of an
+        * element exists and processes them accordingly
+        * @param array $args
+        * @return array
+        * @throws Exception
+        */
+       protected function processArgs( $args ) {
+               $oProcessor = ParamProcessor\Processor::newDefault();
+               $oProcessor->setParameters(
+                       $args,
+                       $this->makeParamDefinitions()
+               );
+
+               $oResult = $oProcessor->processParameters();
+               $this->checkForProcessingErrors( $oResult );
+               $aProcessedParams = $oResult->getParameters();
+
+               $aProcessedValues = array();
+               foreach( $aProcessedParams as $oProcessedParam ) {
+                       $aProcessedValues[$oProcessedParam->getName()] = 
$oProcessedParam->getValue();
+               }
+
+               return $aProcessedValues;
+       }
+
+       /**
+        * Adds default values for missing pieces of the tag definition
+        * @param array $aTagDef
+        * @return array
+        */
+       protected function extendTagDefinition( $aTagDef ) {
+               return array_merge(
+                       $this->makeDefaultTagDefinition(),
+                       $aTagDef
+               );
+       }
+
+       /**
+        * All default values that may be needed to process a tag definition
+        * @return array
+        */
+       protected function makeDefaultTagDefinition() {
+               return array(
+                       'input' => null, //Param definition for the contents of 
a tag
+                       'params' => array(), //Param definition for the 
arguments of a tag
+                       'disableParserCache' => false, //Whether or not to 
disable the parser cache for the page the tag is used on
+                       'classes' => array(), //Additional CSS classes that 
should be added to the container element
+                       'titleMsg' => null, //A message key for the title 
attribute of the container element
+                       'element' => 'div', //The element name of the container 
element. Allows for inline tags.
+                       'parseInput' => true, //Wether ot not to do a 
recursiceTagParse on the input before further processing. Allowes for 
variables, templates, parserfunctions in tag input
+                       'parseParams' => true, //Wether ot not to do a 
recursiceTagParse on the arguments before further processing. Allowes for 
variables, templates, parserfunctions in tag arguments
+                       'callback' => null, //A optional Callable that 
generates the actual content within the container element
+                       'modules' => array(), //ResourceLoader modules to be 
added to the ParserOutput
+                       'moduleStyles' => array() //ResourceLoader modules 
(only CSS) to be added to the ParserOutput
+               );
+       }
+
+       /**
+        * Generates a standard CSS class for the container element
+        * @return string
+        */
+       protected function makeElementClassName() {
+               $sPrefix = 'bs-';
+               if( strpos( $this->sTagName, 'bs:' ) === 0 ) {
+                       $sPrefix = '';
+               }
+               return str_replace( ':', '-', $sPrefix.$this->sTagName );
+       }
+
+
+       /**
+        * Generates the output in case of an exception
+        * @param Exception $ex
+        * @return string
+        */
+       public function makeExceptionOutput( $ex ) {
+               if( $ex instanceof BSInvalidParamException ) {
+                       return $this->makeInvalidParamExceptionOutput( $ex );
+               }
+
+               return Html::element(
+                       $this->sTagName,
+                       array(
+                               'class' => 'bs-error bs-tag'
+                       ),
+                       $ex->getMessage()
+               );
+       }
+
+       /**
+        * Creates ParamProcessor\ParamDefinition compatible definitions based 
on
+        * the tag definition
+        * @return array
+        */
+       public function makeParamDefinitions() {
+               $aParamDefs = array();
+               foreach( $this->aTagDef['params'] as $sParamName => $aParamDef 
) {
+                       $aParamDefs[] = array(
+                               'name' => $sParamName,
+                               'message' => wfMessage( 'bs-tag-param-desc', 
$sParamName )->plain()
+                       ) + $aParamDef;
+               }
+
+               return $aParamDefs;
+       }
+
+       /**
+        * Checks if ParamProcessrs has found any errors on the parameters that
+        * did not result in an exception already and throw an exception to 
display
+        * the errors to the user.
+        *
+        * TODO: This is somewhat bad behavior. Unfortunately at the moment
+        * ParamProcessor does not provide a better mechanism for this, or I am 
not
+        * aware of it.
+        * @param \ParamProcessor\ProcessingResult $oResult
+        * @throws BSInvalidParamException
+        */
+       public function checkForProcessingErrors( $oResult ) {
+               $aErrors = $oResult->getErrors();
+               if( !empty( $aErrors ) ) {
+                       $ex = new BSInvalidParamException();
+                       $ex->setErrors( $aErrors );
+                       throw $ex;
+               }
+       }
+
+       /**
+        * Generates the HTML output that tells the user what went wrong
+        * @param BSInvalidParamException $ex
+        * @return string
+        */
+       public function makeInvalidParamExceptionOutput( $ex ) {
+               $sHtml = '';
+               foreach( $ex->getErrors() as $oProcessingError ) {
+                       $sHtml .= Html::element(
+                               'div',
+                               array(),
+                               $oProcessingError->getMessage()
+                       );
+               }
+               return Html::rawElement(
+                       'div',
+                       array(
+                               'class' => 'bs-error bs-tag'
+                       ),
+                       $sHtml
+               );
+       }
+}
\ No newline at end of file
diff --git a/includes/exception/BSInvalidParamException.php 
b/includes/exception/BSInvalidParamException.php
new file mode 100644
index 0000000..1f3aeb6
--- /dev/null
+++ b/includes/exception/BSInvalidParamException.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Exception thrown and processed in case a param processing resulted in an
+ * error
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This file is part of BlueSpice for MediaWiki
+ * For further information visit http://www.blue-spice.org
+ *
+ * @author     Robert Vogel <[email protected]>
+ * @package    Bluespice_Foundation
+ * @copyright  Copyright (C) 2016 Hallo Welt! - Medienwerkstatt GmbH, All 
rights reserved.
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License v2 or 
later
+ * @filesource
+ */
+
+/**
+ * BSInvalidParamException class in BlueSpice
+ * @package BlueSpice_Foundation
+ */
+class BSInvalidParamException extends Exception {
+       /**
+        *
+        * @var \ParamProcessor\ProcessingError[]
+        */
+       protected $aErrors = array();
+
+       /**
+        *
+        * @param \ParamProcessor\ProcessingError[] $aErrors
+        */
+       public function setErrors( $aErrors ) {
+               $this->aErrors = $aErrors;
+       }
+
+       /**
+        *
+        * @return \ParamProcessor\ProcessingError[]
+        */
+       public function getErrors() {
+               return $this->aErrors;
+       }
+}
\ No newline at end of file
diff --git a/includes/InvalidNamespaceException.class.php 
b/includes/exception/InvalidNamespaceException.class.php
similarity index 72%
rename from includes/InvalidNamespaceException.class.php
rename to includes/exception/InvalidNamespaceException.class.php
index 5c32cdd..c9ed4bf 100644
--- a/includes/InvalidNamespaceException.class.php
+++ b/includes/exception/InvalidNamespaceException.class.php
@@ -1,15 +1,9 @@
 <?php
 /**
- * This class is the basetype for Exceptions within the Blue spice framework.
+ * This class is the basetype for Exceptions within the BlueSpice framework.
  *
- * @copyright Copyright (c) 2007-2011, HalloWelt! Medienwerkstatt GmbH, All 
rights reserved.
+ * @copyright Copyright (c) 2016, HalloWelt! Medienwerkstatt GmbH, All rights 
reserved.
  * @author Robert Vogel
- * @version 0.1.0 beta
- *
- * $LastChangedDate: 2013-06-13 09:29:57 +0200 (Do, 13 Jun 2013) $
- * $LastChangedBy: rvogel $
- * $Rev: 9715 $
-
  */
 
 class BsInvalidNamespaceException extends BsException {
@@ -19,7 +13,7 @@
        /**
         * Setter for internal list of invalid namespaces
         * @param array $aInvalidNamespaces
-        * @throws InvalidArgumentException 
+        * @throws InvalidArgumentException
         */
        public function setListOfInvalidNamespaces( $aInvalidNamespaces ){
                if (is_array( $aInvalidNamespaces ) ) {
@@ -30,16 +24,16 @@
 
        /**
         * Getter for internal list of invalid namespaces
-        * @return array 
+        * @return array
         */
        public function getListOfInvalidNamespaces(){
                return $this->mListOfInvalidNamespaces;
        }
-       
+
        /**
         * Setter for internal list of valid namespaces
         * @param array $aValidNamespaces
-        * @throws InvalidArgumentException 
+        * @throws InvalidArgumentException
         */
        public function setListOfValidNamespaces( $aValidNamespaces ){
                if (is_array( $aValidNamespaces ) ) {
@@ -50,7 +44,7 @@
 
        /**
         * Getter for internal list of valid namespaces
-        * @return array 
+        * @return array
         */
        public function getListOfValidNamespaces(){
                return $this->mListOfValidNamespaces;
diff --git a/includes/paramdefinition/BSNamespaceListParam.php 
b/includes/paramdefinition/BSNamespaceListParam.php
new file mode 100644
index 0000000..2858045
--- /dev/null
+++ b/includes/paramdefinition/BSNamespaceListParam.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Simple class for a list-of-namespaces ParameterDefinition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This file is part of BlueSpice for MediaWiki
+ * For further information visit http://www.blue-spice.org
+ *
+ * @author     Robert Vogel <[email protected]>
+ * @package    Bluespice_Foundation
+ * @copyright  Copyright (C) 2016 Hallo Welt! - Medienwerkstatt GmbH, All 
rights reserved.
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License v2 or 
later
+ * @filesource
+ */
+
+/**
+ * BSNamespaceListParam class in BlueSpice
+ * @package BlueSpice_Foundation
+ */
+class BSNamespaceListParam extends \ParamProcessor\ParamDefinition {
+       protected $delimiter = '|';
+
+       public function isList() {
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/includes/paramdefinition/BSTitleListParam.php 
b/includes/paramdefinition/BSTitleListParam.php
new file mode 100644
index 0000000..e7a2394
--- /dev/null
+++ b/includes/paramdefinition/BSTitleListParam.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ * Simple class for a list-of-titles ParameterDefinition
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This file is part of BlueSpice for MediaWiki
+ * For further information visit http://www.blue-spice.org
+ *
+ * @author     Robert Vogel <[email protected]>
+ * @package    Bluespice_Foundation
+ * @copyright  Copyright (C) 2016 Hallo Welt! - Medienwerkstatt GmbH, All 
rights reserved.
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License v2 or 
later
+ * @filesource
+ */
+
+/**
+ * BSTitleListParam class in BlueSpice
+ * @package BlueSpice_Foundation
+ */
+class BSTitleListParam extends \ParamProcessor\ParamDefinition {
+       protected $delimiter = '|';
+
+       public function isList() {
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/includes/parser/BSNamespaceParser.php 
b/includes/parser/BSNamespaceParser.php
new file mode 100644
index 0000000..43167d0
--- /dev/null
+++ b/includes/parser/BSNamespaceParser.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Turns an string into a valid Namespace ID integer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This file is part of BlueSpice for MediaWiki
+ * For further information visit http://www.blue-spice.org
+ *
+ * @author     Robert Vogel <[email protected]>
+ * @package    Bluespice_Foundation
+ * @copyright  Copyright (C) 2016 Hallo Welt! - Medienwerkstatt GmbH, All 
rights reserved.
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License v2 or 
later
+ * @filesource
+ */
+
+/**
+ * BSNamespaceParser class in BlueSpice
+ * @package BlueSpice_Foundation
+ */
+class BSNamespaceParser extends \ValueParsers\StringValueParser {
+
+       /**
+        *
+        * @param string $value
+        * @return int
+        */
+       protected function stringParse( $value ) {
+               if( is_int( $value ) ) {
+                       return (int)$value;
+               }
+
+               $iNSId = BsNamespaceHelper::getNamespaceIndex( $value );
+               if( $iNSId === false ) {
+                       throw new \ValueParsers\ParseException(
+                               wfMessage( 'bs-parser-error-invalid-namespace' 
, $value )->plain()
+                       );
+               }
+
+               return $iNSId;
+       }
+}
\ No newline at end of file
diff --git a/includes/parser/BSTitleParser.php 
b/includes/parser/BSTitleParser.php
new file mode 100644
index 0000000..a129835
--- /dev/null
+++ b/includes/parser/BSTitleParser.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Turns an string into a valid Title object
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This file is part of BlueSpice for MediaWiki
+ * For further information visit http://www.blue-spice.org
+ *
+ * @author     Robert Vogel <[email protected]>
+ * @package    Bluespice_Foundation
+ * @copyright  Copyright (C) 2016 Hallo Welt! - Medienwerkstatt GmbH, All 
rights reserved.
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License v2 or 
later
+ * @filesource
+ */
+
+/**
+ * BSTitleParser class in BlueSpice
+ * This is a very simmilar implementation to ParamProcessor\TitleParser from
+ * "Validator" extension. It would be better to require this extension and
+ * maybe contribute to it than to duplicate code
+ * @package BlueSpice_Foundation
+ */
+class BSTitleParser extends \ValueParsers\StringValueParser {
+       /**
+        * @see StringValueParser::stringParse
+        *
+        * @param string $value
+        * @return Title
+        * @throws ParseException
+        */
+       protected function stringParse( $value ) {
+               $oTitle = Title::newFromText( $value );
+
+               if ( $oTitle instanceof Title === false ) {
+                       throw new \ValueParsers\ParseException(
+                               wfMessage( 'bs-parser-error-invalid-title' , 
$value )->plain()
+                       );
+               }
+
+               return $oTitle;
+       }
+}
\ No newline at end of file
diff --git a/includes/validator/BSNamespaceValidator.php 
b/includes/validator/BSNamespaceValidator.php
new file mode 100644
index 0000000..3569c8d
--- /dev/null
+++ b/includes/validator/BSNamespaceValidator.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Validates a namespace id based on various settings
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This file is part of BlueSpice for MediaWiki
+ * For further information visit http://www.blue-spice.org
+ *
+ * @author     Robert Vogel <[email protected]>
+ * @package    Bluespice_Foundation
+ * @copyright  Copyright (C) 2016 Hallo Welt! - Medienwerkstatt GmbH, All 
rights reserved.
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License v2 or 
later
+ * @filesource
+ */
+
+/**
+ * BSNamespaceValidator class in BlueSpice
+ * @package BlueSpice_Foundation
+ */
+class BSNamespaceValidator extends \ValueValidators\ValueValidatorObject {
+
+       /**
+        *
+        * @var boolean
+        */
+       protected $hasToExist = false;
+
+       /**
+        *
+        * @var array
+        */
+       protected $aBlacklist = array();
+
+       /**
+        *
+        * @param boolean $hasToExist
+        */
+       public function setHasToExist( $hasToExist ) {
+               $this->hasToExist = $hasToExist;
+       }
+
+       /**
+        *
+        * @param array $aBlacklist
+        */
+       public function setBlacklist( $aBlacklist ) {
+               $this->aBlacklist = $aBlacklist;
+       }
+
+       public function doValidation( $value ) {
+
+               //TODO: finalize implementation
+               if( $this->hasToExist && !MWNamespace::exists( $value ) ) {
+                       $this->addErrorMessage(
+                               wfMessage(
+                                       
'bs-validator-error-namespace-does-not-exist',
+                                       $value
+                               )->plain()
+                       );
+               }
+
+               if( in_array( $value, $this->aBlacklist ) ) {
+                       $this->addErrorMessage(
+                               wfMessage(
+                                       
'bs-validator-error-namespace-on-blacklist',
+                                       $value
+                               )->plain()
+                       );
+               }
+       }
+
+       /**
+        *
+        * @param array $options
+        */
+       public function setOptions( array $options ) {
+               parent::setOptions( $options );
+
+               if ( isset( $options['hastoexist'] ) ) {
+                       $this->setHasToExist( $options['hastoexist'] );
+               }
+
+               if ( isset( $options['blacklist'] ) ) {
+                       $this->setBlacklist( $options['blacklist'] );
+               }
+       }
+}
\ No newline at end of file
diff --git a/includes/validator/BSTitleValidator.php 
b/includes/validator/BSTitleValidator.php
new file mode 100644
index 0000000..f5910bf
--- /dev/null
+++ b/includes/validator/BSTitleValidator.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Validates a Title object based on various settings
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This file is part of BlueSpice for MediaWiki
+ * For further information visit http://www.blue-spice.org
+ *
+ * @author     Robert Vogel <[email protected]>
+ * @package    Bluespice_Foundation
+ * @copyright  Copyright (C) 2016 Hallo Welt! - Medienwerkstatt GmbH, All 
rights reserved.
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License v2 or 
later
+ * @filesource
+ */
+
+/**
+ * BSTitleValidator class in BlueSpice
+ * @package BlueSpice_Foundation
+ */
+class BSTitleValidator extends \ValueValidators\TitleValidator {
+
+       /**
+        *
+        * @var array
+        */
+       protected $aNamespaceBlacklist = array();
+
+       /**
+        *
+        * @param array $aNamespaceBlacklist
+        */
+       public function setNamespaceBlacklist( $aNamespaceBlacklist ) {
+               $this->aNamespaceBlacklist = $aNamespaceBlacklist;
+       }
+
+       /**
+        *
+        * @param Title $oTitle
+        */
+       public function doValidation( $oTitle ) {
+               if( $this->hasToExist && !$oTitle->exists() ) {
+                       $this->addErrorMessage(
+                               wfMessage(
+                                       
'bs-validator-error-title-does-not-exist',
+                                       $oTitle->getPrefixedText()
+                               )->plain()
+                       );
+               }
+
+               if( in_array( $oTitle->getNamespace(), 
$this->aNamespaceBlacklist ) ) {
+                       $this->addErrorMessage(
+                               wfMessage(
+                                       
'bs-validator-error-title-namespace-on-blacklist',
+                                       $oTitle->getPrefixedText()
+                               )->plain()
+                       );
+               }
+       }
+
+       /**
+        *
+        * @param array $options
+        */
+       public function setOptions( array $options ) {
+               parent::setOptions( $options );
+
+               if ( isset( $options['namespaceblacklist'] ) ) {
+                       $this->setNamespaceBlacklist( 
$options['namespaceblacklist'] );
+               }
+       }
+}
\ No newline at end of file
diff --git a/resources/Resources.php b/resources/Resources.php
index 09403b3..e390fe1 100644
--- a/resources/Resources.php
+++ b/resources/Resources.php
@@ -48,7 +48,8 @@
 $wgResourceModules['ext.bluespice.styles'] = array(
        'styles' => array(
                'bluespice/bluespice.css',
-               'bluespice/bluespice.icons.css'
+               'bluespice/bluespice.icons.css',
+               'bluespice/bluespice.ui.basic.less'
        ),
        'position' => 'top'
 ) + $aResourceModuleTemplate;
diff --git a/resources/bluespice/bluespice.ui.basic.less 
b/resources/bluespice/bluespice.ui.basic.less
new file mode 100644
index 0000000..82437cd
--- /dev/null
+++ b/resources/bluespice/bluespice.ui.basic.less
@@ -0,0 +1,19 @@
+.bs-error {
+       background-color: @bs-color-error;
+}
+
+.bs-success {
+       background-color: @bs-color-success;
+}
+
+.bs-info {
+       background-color: @bs-color-info;
+}
+
+.bs-warning {
+       background-color: @bs-color-warning;
+}
+
+.bs-error, .bs-success, .bs-info, .bs-warning {
+       padding: 0.3em;
+}
\ No newline at end of file

-- 
To view, visit https://gerrit.wikimedia.org/r/278280
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I06ea08e5a1ad789806a7648bd4cf03b5b911e12f
Gerrit-PatchSet: 11
Gerrit-Project: mediawiki/extensions/BlueSpiceFoundation
Gerrit-Branch: master
Gerrit-Owner: Robert Vogel <[email protected]>
Gerrit-Reviewer: Dvogel hallowelt <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: Ljonka <[email protected]>
Gerrit-Reviewer: Mglaser <[email protected]>
Gerrit-Reviewer: Paladox <[email protected]>
Gerrit-Reviewer: Pwirth <[email protected]>
Gerrit-Reviewer: Raimond Spekking <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to