Foxtrott has uploaded a new change for review.
https://gerrit.wikimedia.org/r/280581
Change subject: Add StashingDOMDocument; error handling for invalid link targets
......................................................................
Add StashingDOMDocument; error handling for invalid link targets
Change-Id: I028ef68e6e73f55a58f7c46ccb72b6b54645cd5b
---
M extension.json
M i18n/en.json
M i18n/qqq.json
M src/Element.php
M src/Lingo.php
M src/LingoParser.php
A src/StashingDOMDocument.php
7 files changed, 126 insertions(+), 31 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Lingo
refs/changes/81/280581/1
diff --git a/extension.json b/extension.json
index 688f010..3d9ca13 100644
--- a/extension.json
+++ b/extension.json
@@ -67,6 +67,7 @@
"Lingo\\Backend": "/src/Backend.php",
"Lingo\\BasicBackend": "/src/BasicBackend.php",
"Lingo\\MessageLog": "/src/MessageLog.php",
+ "Lingo\\StashingDOMDocument": "/src/StashingDOMDocument.php",
"Lingo\\Tests\\Util\\XmlFileProvider":
"/tests/phpunit/Util/XmlFileProvider.php"
},
"callback": "Lingo\\Lingo::initExtension",
diff --git a/i18n/en.json b/i18n/en.json
index b4904f7..10d3902 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -7,5 +7,6 @@
"lingo-noterminologypage": "The terminology page \"$1\" does not
exist.",
"lingo-notatextpage": "The terminology page \"$1\" is not a text page.",
"lingo-terminologypagenotlocal": "Page \"$1\" is not a local page.",
- "lingo-noapprovedrevs": "Support for ApprovedRevs is enabled in Lingo.
But ApprovedRevs was not found."
+ "lingo-noapprovedrevs": "Support for ApprovedRevs is enabled in Lingo.
But ApprovedRevs was not found.",
+ "lingo-invalidlinktarget" : "Invalid link target for term \"$1\": $2"
}
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 3924b3a..e9f5079 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -10,5 +10,6 @@
"lingo-noterminologypage": "Used as warning message. Parameters:\n* $1
- terminology page title (value of <code>$wgexLingoPage</code>), or
{{msg-mw|lingo-terminologypagename}}\nSee also:\n*
{{msg-mw|lingo-terminologypagenotlocal}}",
"lingo-notatextpage": "Used as error message. Parameters:\n* $1 -
terminology page title (value of <code>$wgexLingoPage</code>), or
{{msg-mw|lingo-terminologypagename}}\nSee also:\n*
{{msg-mw|lingo-noterminologypage}}",
"lingo-terminologypagenotlocal": "Used as error message. Parameters:\n*
$1 - terminology page title (value of <code>$wgexLingoPage</code>), or
{{msg-mw|lingo-terminologypagename}}\nSee also:\n*
{{msg-mw|lingo-noterminologypage}}",
- "lingo-noapprovedrevs": "Used as warning message when the ApprovedRevs
extension is not installed."
+ "lingo-noapprovedrevs": "Used as warning message when the ApprovedRevs
extension is not installed.",
+ "lingo-invalidlinktarget" : "Used as error message when the link target
$2 is not a valid wiki page name."
}
diff --git a/src/Element.php b/src/Element.php
index ba22f5a..b17f639 100644
--- a/src/Element.php
+++ b/src/Element.php
@@ -28,11 +28,10 @@
*/
namespace Lingo;
-use DOMDocument;
+
use DOMElement;
use DOMNode;
use DOMText;
-use MWException;
use Title;
/**
@@ -49,7 +48,9 @@
const ELEMENT_STYLE = 4;
const ELEMENT_FIELDCOUNT = 5; // number of fields stored for each
element; (last field's index) + 1
- static private $mLinkTemplate = null;
+
+ const LINK_TEMPLATE_ID = 'LingoLink';
+
private $mFullDefinition = null;
private $mDefinitions = array();
private $mTerm = null;
@@ -77,10 +78,10 @@
}
/**
- * @param DOMDocument $doc
+ * @param StashingDOMDocument $doc
* @return DOMNode|DOMText
*/
- public function getFullDefinition( DOMDocument &$doc ) {
+ public function getFullDefinition( StashingDOMDocument &$doc ) {
global $wgexLingoDisplayOnce;
@@ -95,10 +96,9 @@
}
/**
- * @param DOMDocument $doc
- * @return DOMDocument
+ * @param StashingDOMDocument $doc
*/
- private function buildFullDefinition( DOMDocument &$doc ) {
+ private function buildFullDefinition( StashingDOMDocument &$doc ) {
// only create if not yet created
if ( $this->mFullDefinition === null ||
$this->mFullDefinition->ownerDocument !== $doc ) {
@@ -121,21 +121,29 @@
}
/**
- * @param DOMDocument $doc
- *
+ * @param StashingDOMDocument $doc
* @return DOMElement
- * @throws MWException
+ * @throws \MWException
*/
- protected function getFullDefinitionAsLink( DOMDocument &$doc ) {
+ protected function getFullDefinitionAsLink( StashingDOMDocument &$doc )
{
// create Title object for target page
$target = Title::newFromText( $this->mDefinitions[ 0 ][
self::ELEMENT_LINK ] );
+
+ if ( !$target instanceof Title ) {
+ $errorMessage = wfMessage( 'lingo-invalidlinktarget',
$this->mTerm, $this->mDefinitions[ 0 ][ self::ELEMENT_LINK ] )->text();
+ $errorDefinition = array( self::ELEMENT_DEFINITION =>
$errorMessage, self::ELEMENT_STYLE => 'invalid-link-target' );
+ $this->addDefinition( $errorDefinition );
+ return $this->getFullDefinitionAsTooltip( $doc );
+ }
// create link element
$link = $doc->createElement( 'a', $this->mDefinitions[ 0 ][
self::ELEMENT_TERM ] );
// set the link target
$link->setAttribute( 'href', $target->getLinkUrl() );
+
+
$link = $this->addClassAttributeToLink( $target, $link );
$link = $this->addTitleAttributeToLink( $target, $link );
@@ -145,6 +153,7 @@
/**
* @param $target
* @param $link
+ * @return mixed
*/
protected function &addClassAttributeToLink( $target, &$link ) {
@@ -152,18 +161,19 @@
// Cleanest would probably be to use Linker::link and parse it
// back into a DOMElement, but we are in a somewhat
time-critical
// part here.
- $classes = '';
+
+ // set style
+ $classes = string( $this->mDefinitions[ 0 ][
self::ELEMENT_STYLE ] );
if ( !$target->isKnown() ) {
- $classes .= 'new ';
+ $classes .= ' new';
}
if ( $target->isExternal() ) {
- $classes .= 'extiw ';
+ $classes .= ' extiw';
}
- // set style
- $classes .= $this->mDefinitions[ 0 ][ self::ELEMENT_STYLE ];
+ $classes = trim( $classes );
if ( $classes !== '' ) {
$link->setAttribute( 'class', $classes );
@@ -175,6 +185,7 @@
/**
* @param $target
* @param $link
+ * @return mixed
*/
protected function &addTitleAttributeToLink( $target, &$link ) {
@@ -191,12 +202,11 @@
}
/**
- * @param DOMDocument $doc
- *
+ * @param StashingDOMDocument $doc
* @return string
- * @throws MWException
+ * @throws \MWException
*/
- protected function getFullDefinitionAsTooltip( DOMDocument &$doc ) {
+ protected function getFullDefinitionAsTooltip( StashingDOMDocument
&$doc ) {
// Wrap term and definition in <span> tags
$span = $doc->createElement( 'span' );
@@ -238,22 +248,27 @@
}
/**
- * @param DOMDocument $doc
+ * @param StashingDOMDocument $doc
* @return DOMNode
*/
- private function getLinkTemplate( DOMDocument &$doc ) {
+ private function getLinkTemplate( StashingDOMDocument &$doc ) {
+
+ $mLinkTemplate = $doc->stashGet( self::LINK_TEMPLATE_ID );
+
// create template if it does not yet exist
- if ( !self::$mLinkTemplate || (
self::$mLinkTemplate->ownerDocument !== $doc ) ) {
+ if ( $mLinkTemplate === null ) {
global $wgScriptPath;
$linkimage = $doc->createElement( 'img' );
$linkimage->setAttribute( 'src', $wgScriptPath .
'/extensions/Lingo/styles/linkicon.png' );
- self::$mLinkTemplate = $doc->createElement( 'a' );
- self::$mLinkTemplate->appendChild( $linkimage );
+ $mLinkTemplate = $doc->createElement( 'a' );
+ $mLinkTemplate->appendChild( $linkimage );
+
+ $doc->stashSet( $mLinkTemplate, self::LINK_TEMPLATE_ID
);
}
- return self::$mLinkTemplate->cloneNode( true );
+ return $mLinkTemplate->cloneNode( true );
}
/**
diff --git a/src/Lingo.php b/src/Lingo.php
index e74db7c..9ff89ee 100644
--- a/src/Lingo.php
+++ b/src/Lingo.php
@@ -31,7 +31,7 @@
* Class Lingo
*
* @package Lingo
- * @ingroup Skins
+ * @ingroup Lingo
*/
class Lingo {
diff --git a/src/LingoParser.php b/src/LingoParser.php
index da4d039..5de6d42 100644
--- a/src/LingoParser.php
+++ b/src/LingoParser.php
@@ -230,7 +230,7 @@
// Parse HTML from page
\MediaWiki\suppressWarnings();
- $doc = new DOMDocument( '1.0', 'utf-8' );
+ $doc = new StashingDOMDocument( '1.0', 'utf-8' );
$doc->loadHTML( '<html><head><meta http-equiv="content-type"
content="charset=utf-8"/></head><body>' . $text . '</body></html>' );
\MediaWiki\restoreWarnings();
diff --git a/src/StashingDOMDocument.php b/src/StashingDOMDocument.php
new file mode 100644
index 0000000..74a2436
--- /dev/null
+++ b/src/StashingDOMDocument.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * File containing the StashingDOMDocument class
+ *
+ * @copyright (C) 2013 - 2016, Stephan Gambke
+ * @license GNU General Public License, version 3 (or any later version)
+ *
+ * The Lingo extension 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 3 of the License, or (at your option)
any
+ * later version.
+ *
+ * The Lingo extension 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, see <http://www.gnu.org/licenses/>.
+ *
+ * @file
+ * @ingroup Lingo
+ */
+
+namespace Lingo;
+
+/**
+ * Class StashingDOMDocument
+ *
+ * @package Lingo
+ * @ingroup Lingo
+ * @since 2.0.2
+ */
+class StashingDOMDocument extends \DOMDocument {
+
+ private $mStash = array();
+
+ /**
+ * @param \DOMElement $element
+ * @param null $key
+ * @return null
+ */
+ public function stashSet( \DOMElement $element, $key = null ) {
+
+ if ( $key === null ) {
+ $key = uniqid( '', true );
+ }
+
+ $this->mStash[ $key ] = $element;
+
+ return $key;
+ }
+
+ /**
+ * @param $key
+ * @return \DOMElement | null
+ */
+ public function stashGet( $key ) {
+ return @$this->mStash[ $key ];
+ }
+
+ /**
+ * @param $key
+ */
+ public function stashDelete( $key ) {
+ unset ( $this->mStash[ $key ] );
+ }
+
+ /**
+ * @param $key
+ * @return bool
+ */
+ public function isStashed ( $key ) {
+ return isset( $this->mStash[ $key ] );
+ }
+
+}
--
To view, visit https://gerrit.wikimedia.org/r/280581
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I028ef68e6e73f55a58f7c46ccb72b6b54645cd5b
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Lingo
Gerrit-Branch: master
Gerrit-Owner: Foxtrott <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits