Dan-nl has uploaded a new change for review.
https://gerrit.wikimedia.org/r/90527
Change subject: item specific categories throws an exception
......................................................................
item specific categories throws an exception
when in step 2 of the upload process, if an item specific category is added
that uses a
metadata field that has not been used in the metadata mapping, the application
will throw
an exception because the metadata field is not in
Mapping->target_dom_elements_mapped.
the solution implemented was to create an array that contains all first level
elements of
the metadata record instead of only the targeted dom elements based on the
metadata mapping.
a Metadata and MetadataPhpAdapter class were created that provide current use,
storage and
retrieval of the new metadata array, and a place for future use, e.g., using
ContentHandler
to store and retrieve metadata snippets
an issue with wikitext category generation was also corrected. the application
was hard
coding the namespace name as Category: and not stripping out [] that might be
in the metadata.
created \GWToolset\getNamespaceName() and
\GWToolset\stripIllegalCategoryChars() to handle
these issues.
a few clean-up and cosmetic issues spotted in the affected files while working
on these
issues were also addressed.
* GWToolset.i18n.php
- got rid of bold around the gwtoolset-developer-issue key
* includes/Config.php
- added $autoloader_classes
- removed outdated $autoloader_classes
- updated the version
* includes/Adapters/Php/MedtadataPhpAdapter.php
- added file
* includes/Forms/MetadataDetectForm.php
- changed the way the namespace name is found
* includes/Handlers/Forms/MetadataDetectHandler.php
- added line breaks to code that is > 100 characters
- removed unused use namespace FSFile
* includes/Handlers/Forms/MetadataMappingHandler.php
- added in use of the new Metadata class
- re-factored processMatchingElement() so that it incorporates the new
Metadata class
and uses an $options array instead of individual parameters
* includes/UploadHandler.php
- added in use of the new Metadata class
- re-factored wikitext category generation so that it uses
\GWToolset\getNamespaceName()
and \GWToolset\stripIllegalCategoryChars()
- removed getMappedField() and and used Metadata->getConcatenatedField()
instead for
getting item specific category values
- made a few @param types consistent with the rest of the application
- removed @return {void}s
- re-factored saveMediafileViaJob() so that it incorporates the new Metadata
class and
uses an $options array instead of individual parameters
* includes/Handlers/Xml/XmlMappingHandler.php
- added getDOMElementAsArray() and addDOMElementToArray() to create the array
version
of the metadata to be used in the Metadata class
* includes/Jobs/UploadMediafileJob.php
- added in use of the new Metadata class
- adjusted validateParams() to the new $options array provided by
saveMediaFileViaJob()
* includes/Models/Mapping.php
- added in use of \GWToolset\getNamespaceName()
* includes/Models/Medtadata.php
- added file
* includes/functions/functions.php
- added getNamespaceName()
- added stripIllegalCategoryChars()
- adjusted spacing in a comment
- made a few @param types consistent with the rest of the application
- handleError() altered the comment and changed ErrorException to MWException
* re: #183/assembla - item specific categories throws an exception
Change-Id: I5b23b8af2d2c572af97ae179761b37091bab6a85
---
M GWToolset.i18n.php
A includes/Adapters/Php/MetadataPhpAdapter.php
M includes/Config.php
M includes/Forms/MetadataDetectForm.php
M includes/Forms/MetadataMappingForm.php
M includes/Handlers/UploadHandler.php
M includes/Handlers/Xml/XmlMappingHandler.php
M includes/Jobs/UploadMediafileJob.php
M includes/Models/Mapping.php
A includes/Models/Metadata.php
M includes/functions/functions.php
11 files changed, 425 insertions(+), 158 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/GWToolset
refs/changes/27/90527/1
diff --git a/GWToolset.i18n.php b/GWToolset.i18n.php
index 72fdcfe..2af0daa 100644
--- a/GWToolset.i18n.php
+++ b/GWToolset.i18n.php
@@ -34,8 +34,8 @@
'gwtoolset-could-not-open-xml' => 'Could not open the XML File for
reading.',
'gwtoolset-developer-issue' => "Please contact a developer; they will
need to address this issue before you can continue.
-'''$1'''",
- 'gwtoolset-dom-record-issue' => '<code>record-element-name</code>, or
<code>record-count</code> not provided.',
+$1",
+ 'gwtoolset-dom-record-issue' => '<code>record-element-name</code>, or
<code>record-count</code> or <code>record-current</code> not provided.',
'gwtoolset-ignorewarnings' => '<code>ignorewarnings</code> not set.',
'gwtoolset-no-accepted-types' => 'No accepted types provided',
'gwtoolset-no-callback' => 'No callback passed to this method.',
@@ -53,6 +53,7 @@
'gwtoolset-no-title' => 'No title provided.',
'gwtoolset-no-upload-handler' => 'No upload handler was created.',
'gwtoolset-no-upload-media' =>
"<code>user_options['upload-media']</code> not set.",
+ 'gwtoolset-no-url-to-evaluate' => 'No URL was provided for evaluation.',
'gwtoolset-no-url-to-media' => '<code>url-to-the-media-file</code> not
set.',
'gwtoolset-no-user' => 'no user object provided.',
'gwtoolset-no-xml-element' => 'No XMLReader or DOMElement provided.',
@@ -280,7 +281,7 @@
'gwtoolset-desc' =>
'{{desc|name=GWToolset|url=https://www.mediawiki.org/wiki/Extension:GWToolset}}',
'gwtoolset-developer-issue' => "A user-friendly message that lets the
user know that something went wrong that a developer will need to fix. The
single parameter takes a message that explains a bit more to the developer what
the issue may be.",
'gwtoolset-disk-write-failure' => 'User error message that appears when
the uploaded file failed to write to disk.',
- 'gwtoolset-dom-record-issue' => 'Hint to the developer that appears
when record-element-name, or record-count not provided.',
+ 'gwtoolset-dom-record-issue' => 'Hint to the developer that appears
when record-element-name, or record-count or record-current not provided.',
'gwtoolset-ensure-well-formed-xml' => 'Additional instructions that
will help the user make sure the XML File is well-formed.',
'gwtoolset-example-record' => 'Label for the metadata example record.',
'gwtoolset-file-interpretation-error' => 'Heading that appears when
there was a problem interpreting the metadata file.',
@@ -347,6 +348,7 @@
'gwtoolset-no-title' => 'Hint to the developer that appears when no
title is provided.',
'gwtoolset-no-upload-handler' => 'Hint to the developer that appears
when no upload handler was created.',
'gwtoolset-no-upload-media' => "Hint to the developer that appears when
user_options['upload-media'] is not set.",
+ 'gwtoolset-no-url-to-evaluate' => 'Message that appears when no URL was
provided for evaluation.',
'gwtoolset-no-url-to-media' => 'Hint to the developer that appears when
url-to-the-media-file is not set.',
'gwtoolset-no-user' => 'Hint to the developer that appears when no user
object is provided.',
'gwtoolset-no-xml-element' => 'Hint to the developer that appears when
no XMLReader or DOMElement is provided.',
diff --git a/includes/Adapters/Php/MetadataPhpAdapter.php
b/includes/Adapters/Php/MetadataPhpAdapter.php
new file mode 100644
index 0000000..857a4df
--- /dev/null
+++ b/includes/Adapters/Php/MetadataPhpAdapter.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * GWToolset
+ *
+ * @file
+ * @ingroup Extensions
+ * @license GNU General Public License 3.0 http://www.gnu.org/licenses/gpl.html
+ */
+
+namespace GWToolset\Adapters\Php;
+use GWToolset\Adapters\DataAdapterInterface;
+
+class MetadataPhpAdapter implements DataAdapterInterface {
+
+ /**
+ * @param {array} $options
+ */
+ public function create( array $options = array() ) {
+ }
+
+ /**
+ * @param {array} $options
+ */
+ public function delete( array $options = array() ) {
+ }
+
+ /**
+ * @param {array} $options
+ */
+ public function retrieve( array $options = array() ) {
+ }
+
+ /**
+ * @param {array} $options
+ */
+ public function update( array $options = array() ) {
+ }
+}
diff --git a/includes/Config.php b/includes/Config.php
index f33fa61..548b2f7 100644
--- a/includes/Config.php
+++ b/includes/Config.php
@@ -16,7 +16,7 @@
public static $url =
'https://www.mediawiki.org/wiki/Extension:GWToolset';
public static $descriptionmsg = 'gwtoolset-desc';
public static $type = 'media';
- public static $version = '0.1.0';
+ public static $version = '0.1.1';
/**
* @var {array}
@@ -56,6 +56,7 @@
'GWToolset\Adapters\Php\MappingPhpAdapter' =>
'/includes/Adapters/Php/MappingPhpAdapter.php',
'GWToolset\Adapters\Php\MediawikiTemplatePhpAdapter' =>
'/includes/Adapters/Php/MediawikiTemplatePhpAdapter.php',
+ 'GWToolset\Adapters\Php\MetadataPhpAdapter' =>
'/includes/Adapters/Php/MetadataPhpAdapter.php',
'GWToolset\Forms\MetadataDetectForm' =>
'/includes/Forms/MetadataDetectForm.php',
'GWToolset\Forms\MetadataMappingForm' =>
'/includes/Forms/MetadataMappingForm.php',
@@ -86,8 +87,7 @@
'GWToolset\Models\Mapping' => '/includes/Models/Mapping.php',
'GWToolset\Models\MediawikiTemplate' =>
'/includes/Models/MediawikiTemplate.php',
- 'GWToolset\Models\Menu' => '/includes/Models/Menu.php',
- 'GWToolset\Models\ModelAbstract' =>
'/includes/Models/ModelAbstract.php',
+ 'GWToolset\Models\Metadata' => '/includes/Models/Metadata.php',
'GWToolset\Models\ModelInterface' =>
'/includes/Models/ModelInterface.php',
'GWToolset\SpecialGWToolset' =>
'/includes/Specials/SpecialGWToolset.php',
@@ -246,6 +246,7 @@
'gwtoolset-cancel'
),
'dependencies' => array(
+ 'jquery.json',
'jquery.spinner',
'jquery.ui.widget',
'jquery.ui.button',
@@ -279,7 +280,7 @@
/**
* @see SpecialPage __constructor
- * @var {boolean}
+ * @var {bool}
* whether the page is listed in Special:Specialpages
*/
public static $special_page_listed = true;
@@ -307,14 +308,14 @@
public static $title_separator = '-';
/**
- * @var {boolean}
+ * @var {bool}
* tells the upload form to place the $accepted_mime_types in a comma
* delimited list in the input file’s accept attribute
*/
public static $use_file_accept_attribute = true;
/**
- * @var {boolean}
+ * @var {bool}
*/
public static $use_UploadStash = true;
diff --git a/includes/Forms/MetadataDetectForm.php
b/includes/Forms/MetadataDetectForm.php
index 1cdd77c..6bde13d 100644
--- a/includes/Forms/MetadataDetectForm.php
+++ b/includes/Forms/MetadataDetectForm.php
@@ -28,8 +28,7 @@
* an html form
*/
public static function getForm( SpecialPage $SpecialPage ) {
- $namespace = $SpecialPage->getLanguage()->getNamespaces();
- $namespace = $namespace[Config::$metadata_namespace] . ':';
+ $namespace = \GWToolset\getNamespaceName(
Config::$metadata_namespace );
$MediawikiTemplate = new MediawikiTemplate( new
MediawikiTemplatePhpAdapter() );
return
diff --git a/includes/Forms/MetadataMappingForm.php
b/includes/Forms/MetadataMappingForm.php
index 220fad9..65a3ba8 100644
--- a/includes/Forms/MetadataMappingForm.php
+++ b/includes/Forms/MetadataMappingForm.php
@@ -320,7 +320,7 @@
Html::rawElement(
'table',
- array(),
+ array( 'id' => 'global-categories-table' ),
Html::rawElement(
'tbody',
array(),
@@ -370,7 +370,7 @@
Html::rawElement(
'table',
- array(),
+ array( 'id' => 'item-specific-categories-table'
),
Html::rawElement(
'thead',
array(),
diff --git a/includes/Handlers/UploadHandler.php
b/includes/Handlers/UploadHandler.php
index 306c481..fba9cb6 100644
--- a/includes/Handlers/UploadHandler.php
+++ b/includes/Handlers/UploadHandler.php
@@ -17,6 +17,7 @@
GWToolset\Jobs\UploadFromUrlJob,
GWToolset\Models\Mapping,
GWToolset\Models\MediawikiTemplate,
+ GWToolset\Models\Metadata,
JobQueueGroup,
Linker,
LocalRepo,
@@ -48,6 +49,11 @@
* @var {MediawikiTemplate}
*/
protected $_MediawikiTemplate;
+
+ /**
+ * @var {Metadata}
+ */
+ protected $_Metadata;
/**
* @var {SpecialPage}
@@ -88,7 +94,6 @@
/**
* @param {array} $options
- * @return {void}
*/
public function __construct( array $options = array() ) {
$this->reset();
@@ -103,6 +108,10 @@
if ( isset( $options['MediawikiTemplate'] ) ) {
$this->_MediawikiTemplate =
$options['MediawikiTemplate'];
+ }
+
+ if ( isset( $options['Metadata'] ) ) {
+ $this->_Metadata = $options['Metadata'];
}
if ( isset( $options['SpecialPage'] ) ) {
@@ -153,7 +162,11 @@
$categories = explode( Config::$category_separator,
$this->user_options['categories'] );
foreach ( $categories as $category ) {
- $result .= '[[Category:' . Filter::evaluate(
$category ) . ']]';
+ $result .=
+ '[[' .
+
\GWToolset\getNamespaceName( NS_CATEGORY ) .
+
\GWToolset\stripIllegalCategoryChars( Filter::evaluate( $category ) ) .
+ ']]';
}
}
@@ -187,13 +200,19 @@
}
if ( !empty(
$this->user_options['category-metadata'][$i] ) ) {
- $metadata = Filter::evaluate(
- $this->getMappedField(
$this->user_options['category-metadata'][$i] )
- );
+ $metadata =
+
$this->_Metadata->getConcatenatedField(
+
$this->user_options['category-metadata'][$i]
+ );
}
if ( !empty( $metadata ) ) {
- $result .= '[[Category:' . $phrase .
$metadata . ']]';
+ $result .=
+ '[[' .
+
\GWToolset\getNamespaceName( NS_CATEGORY ) .
+
\GWToolset\stripIllegalCategoryChars( $phrase ) .
+
\GWToolset\stripIllegalCategoryChars( $metadata ) .
+ ']]';
}
}
}
@@ -208,7 +227,6 @@
*
* @param {array} $accepted_types
* @throws {MWException}
- * @return {void}
*/
protected function augmentAllowedExtensions( array $accepted_types =
array() ) {
global $wgFileExtensions;
@@ -269,6 +287,13 @@
protected function evaluateMediafileUrl( $url ) {
$result = array( 'content-type' => null, 'extension' => null,
'url' => null );
$pathinfo = array();
+
+ if ( empty( $url ) ) {
+ throw new MWException(
+ __METHOD__ . ' ' .
+ wfMessage( 'gwtoolset-no-url-to-evaluate'
)->escaped()
+ );
+ }
$Http = MWHttpRequest::factory(
$url,
@@ -359,32 +384,6 @@
}
/**
- * @param {string} $field
- *
- * @return {string}
- * the string is not filtered
- */
- protected function getMappedField( $field ) {
- $result = null;
-
- foreach ( $this->_Mapping->target_dom_elements_mapped[$field]
as $targeted_field ) {
- $parameter_as_id =
$this->_MediawikiTemplate->getParameterAsId( $targeted_field );
-
- if ( array_key_exists(
- $targeted_field,
$this->_MediawikiTemplate->mediawiki_template_array )
- ) {
- $result .=
$this->_MediawikiTemplate->mediawiki_template_array[$targeted_field] . ' ';
- } elseif ( array_key_exists(
- $parameter_as_id,
$this->_MediawikiTemplate->mediawiki_template_array )
- ) {
- $result .=
$this->_MediawikiTemplate->mediawiki_template_array[$parameter_as_id] . ' ';
- }
- }
-
- return $result;
- }
-
- /**
* creates the wiki text for the media file page.
* concatenates several pieces of information in order to create the
wiki
* text for the mediafile wiki text
@@ -401,13 +400,13 @@
}
/**
- * @param {Array} $options
+ * @param {string} $title
* @throws {MWException}
* @return {Title}
*/
- protected function getTitle( array &$options ) {
+ protected function getTitle( $title ) {
$result = \GWToolset\getTitle(
- \GWToolset\stripIllegalTitleChars( $options['title'] ),
+ \GWToolset\stripIllegalTitleChars( $title ),
Config::$mediafile_namespace,
array( 'must-be-known' => false )
);
@@ -415,7 +414,7 @@
if ( !( $result instanceof Title ) ) {
throw new MWException(
wfMessage( 'gwtoolset-title-bad' )
- ->params( $options['title'] )->parse()
+ ->params( $title )->parse()
);
}
@@ -486,9 +485,6 @@
return $result;
}
- /**
- * @return {void}
- */
public function reset() {
$this->_File = null;
$this->_Mapping = null;
@@ -505,7 +501,6 @@
* restores the wiki’s allowed extensions array
*
* @param {array} $accepted_types
- * @return {void}
*/
protected function restoreAllowedExtensions( array $accepted_types =
array() ) {
global $wgFileExtensions;
@@ -594,15 +589,16 @@
}
/**
- * controls the workflow for saving media files
+ * @todo does ContentHandler filter $options['text']?
+ * @todo does WikiPage filter $options['comment']?
*
* @param {array} $user_options
- * an array of user options that was submitted in the html form
- *
+ * @throws {MWException}
* @return {null|Title}
*/
- public function saveMediaFile( array &$user_options ) {
- $result = null;
+ public function saveMediafileAsContent( array &$user_options ) {
+ $Title = null;
+ $Status = null;
$options = array();
$this->validateUserOptions( $user_options );
@@ -625,27 +621,9 @@
$options['text'] = $this->getText();
- if ( $this->user_options['save-as-batch-job'] ) {
- $Status = $this->saveMediafileViaJob( $options );
- } else {
- $result = $this->saveMediafileAsContent( $options );
- }
-
- return $result;
- }
-
- /**
- * @todo does ContentHandler filter $options['text']?
- * @todo does WikiPage filter $options['comment']?
- * @param {array} $options
- * @throws {MWException}
- * @return {Title}
- */
- public function saveMediafileAsContent( array &$options ) {
- $Status = null;
WikiChecks::increaseHTTPTimeout();
$this->validatePageOptions( $options );
- $Title = $this->getTitle( $options );
+ $Title = $this->getTitle( $options['title'] );
if ( !$Title->isKnown() ) {
$Status = $this->uploadMediaFileViaUploadFromUrl(
$options, $Title );
@@ -670,10 +648,19 @@
}
/**
+ * save a metadata record as a new/updated wiki page
+ *
+ * @param {array} $user_options
+ * an array of user options that was submitted in the html form
+ *
* @param {array} $options
+ * {array} $options['metadata-mapped-to-mediawiki-template']
+ * {array} $options['metadata-as-array']
+ * {string} $options['metadata-raw']
+ *
* @return {bool}
*/
- protected function saveMediafileViaJob( array &$options ) {
+ public function saveMediafileViaJob( array &$user_options, array
$options ) {
$result = false;
$job = null;
$sessionKey = null;
@@ -682,20 +669,17 @@
return;
}
- $this->validatePageOptions( $options );
- $Title = $this->getTitle( $options );
+ $this->validateUserOptions( $user_options );
$job = new UploadMediafileJob(
- $Title,
+ Title::newFromText(
+ 'User:' . $this->_User->getName() . '/' . Config::$name
. ' Mediafile Batch Job'
+ ),
array(
- 'comment' => $options['comment'],
- 'ignorewarnings' => $options['ignorewarnings'],
- 'text' => $options['text'],
- 'title' => $options['title'],
- 'url-to-the-media-file' =>
$options['url-to-the-media-file'],
- 'username' => $this->_User->getName(),
- 'user_options' => $this->user_options,
- 'watch' => $options['watch']
+ 'options' => $options,
+ 'post' => $_POST,
+ 'user-name' => $this->_User->getName(),
+ 'user-options' => $user_options
)
);
@@ -781,7 +765,6 @@
*
* @param {array} $options
* @throws {MWException}
- * @return {void}
*/
protected function validatePageOptions( array &$options ) {
if ( !isset( $options['ignorewarnings'] ) ) {
@@ -819,7 +802,6 @@
/**
* @param {array} $options
* @throws {MWException}
- * @return {void}
*/
protected function validateUserOptions( array &$user_options ) {
if ( !isset( $user_options['comment'] ) ) {
diff --git a/includes/Handlers/Xml/XmlMappingHandler.php
b/includes/Handlers/Xml/XmlMappingHandler.php
index 0e21c4c..2df9283 100644
--- a/includes/Handlers/Xml/XmlMappingHandler.php
+++ b/includes/Handlers/Xml/XmlMappingHandler.php
@@ -66,6 +66,53 @@
}
/**
+ * helper method for getDOMElementAsArray()
+ *
+ * @param {array} $array
+ * @param {DOMElement} $DOMElement
+ */
+ protected function addDOMElementToArray( array &$array, DOMElement
$DOMElement ) {
+ $is_url = strpos( $DOMElement->nodeValue, '://' ) !== false;
+ $array[] = $this->getFilteredNodeValue( $DOMElement, $is_url );
+
+ if ( $DOMElement->hasAttributes() ) {
+ foreach ( $DOMElement->attributes as $attribute ) {
+ $array['@attributes'][$attribute->name] =
$attribute->value;
+ }
+ }
+ }
+
+ /**
+ * creates an array based on the dom element provided
+ * - only goes 1 level down
+ * - assigns the element name as the array index
+ * - adds values as an array to the element name index
+ *
+ * we’re using this method instead of a SimpleXMLElement object because
we have found that some
+ * metadata sources use XML namespaces without declaring them within
the XML document, which
+ * requires additional logic to sort out the namespaced elements that
may not be reliable
+ *
+ * @param {DOMElement} $DOMElement
+ * @return {array}
+ */
+ protected function getDOMElementAsArray( DOMElement $DOMElement ) {
+ $result = array();
+
+ foreach ( $DOMElement->childNodes as $childNode ) {
+ if ( $childNode->nodeType === XML_ELEMENT_NODE ) {
+ if ( !isset( $result[$childNode->tagName] ) ) {
+ $result[$childNode->tagName] = array();
+ $this->addDOMElementToArray(
$result[$childNode->tagName], $childNode );
+ } else {
+ $this->addDOMElementToArray(
$result[$childNode->tagName], $childNode );
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ /**
* takes in a metadata dom element that represents a targeted
* record within the metadata that will be saved/updated in the
* wiki as a wiki page and maps it to the mediawiki template
@@ -81,6 +128,7 @@
* getting the NS is not always straightforward
*
* @todo possibly filter keys and values
+ * @todo possibly refactor so that it works with getDOMElementAsArray
*
* @param {DOMELement} $DOMElement
*
@@ -206,7 +254,7 @@
*
* @return {array}
* - $result['Title'] {Title}
- * - $result['stop-reading'] {boolean}
+ * - $result['stop-reading'] {bool}
*/
protected function processDOMElements( $XMLElement, array
&$user_options ) {
$result = array( 'Title' => null, 'stop-reading' => false );
@@ -225,6 +273,7 @@
if ( !isset( $user_options['record-element-name'] )
|| !isset( $user_options['record-count'] )
+ || !isset( $user_options['record-current'] )
) {
throw new MWException(
wfMessage( 'gwtoolset-developer-issue' )
@@ -248,24 +297,30 @@
}
if ( !empty( $record ) ) {
- $user_options['record-count'] += 1;
+ $user_options['record-current'] += 1;
- // don’t process the element if the
record count is not >=
- // the record nr we should start
processing on
- if ( $user_options['record-count'] <
$user_options['record-begin'] ) {
+ // don’t process the element if the
current record nr is <
+ // the record nr we should begin
processing on
+ if ( $user_options['record-current'] <
$user_options['record-begin'] ) {
break;
}
- // stop processing if the record count
is > the record nr we should
- // start processing on plus the job
throttle
- if ( $user_options['record-count'] >
$user_options['record-begin'] + Config::$job_throttle ) {
+ // stop processing if the current
record nr is >=
+ // the record nr we should begin
processing on plus the job throttle
+ if ( $user_options['record-current']
+ >=
$user_options['record-begin'] + Config::$job_throttle
+ ) {
$result['stop-reading'] = true;
break;
}
$result['Title'] =
$this->_MappingHandler->processMatchingElement(
- $user_options,
$this->getDOMElementMapped( $record ),
- $outer_xml
+ $user_options,
+ array(
+ 'metadata-as-array' =>
$this->getDOMElementAsArray( $record ),
+
'metadata-mapped-to-mediawiki-template' => $this->getDOMElementMapped( $record
),
+ 'metadata-raw' =>
$outer_xml
+ )
);
}
diff --git a/includes/Jobs/UploadMediafileJob.php
b/includes/Jobs/UploadMediafileJob.php
index 7044554..6ea182c 100644
--- a/includes/Jobs/UploadMediafileJob.php
+++ b/includes/Jobs/UploadMediafileJob.php
@@ -8,27 +8,18 @@
*/
namespace GWToolset\Jobs;
-use GWToolset\Handlers\UploadHandler,
+use GWToolset\Adapters\Php\MappingPhpAdapter,
+ GWToolset\Adapters\Php\MediawikiTemplatePhpAdapter,
+ GWToolset\Adapters\Php\MetadataPhpAdapter,
+ GWToolset\Models\Mapping,
+ GWToolset\Models\MediawikiTemplate,
+ GWToolset\Models\Metadata,
+ GWToolset\Handlers\UploadHandler,
MWException,
Job,
User;
class UploadMediafileJob extends Job {
-
- /**
- * {UploadHandler}
- */
- protected $_UploadHandler;
-
- /**
- * @var {User}
- */
- protected $_User;
-
- /**
- * @var {string}
- */
- public $filename_metadata;
/**
* @param {Title} $title
@@ -41,38 +32,50 @@
}
/**
+ * a control method for re-establishing application state so that the
metadata can be processed.
+ * this is similar to MetadataMappingHandler::processMetadata(),
however it avoids the necessity
+ * to process the metadata file
+ *
+ * @todo re-factor so that this is able to use
MetadataMappingHandler::processMetadata(). will
+ * need to add some logic to it so that if a batch job is being process
it doesn't display a form
+ * or process the metadata again
+ *
* @return {bool|Title}
*/
protected function processMetadata() {
$result = false;
+ $_POST = $this->params['post'];
- $this->_UploadHandler = new UploadHandler(
+ $MediawikiTemplate = new MediawikiTemplate( new
MediawikiTemplatePhpAdapter() );
+ $MediawikiTemplate->getMediaWikiTemplate(
$this->params['user-options'] );
+
+ $Mapping = new Mapping( new MappingPhpAdapter() );
+ $Mapping->mapping_array =
$MediawikiTemplate->getMappingFromArray( $_POST );
+ $Mapping->setTargetElements();
+ $Mapping->reverseMap();
+
+ $Metadata = new Metadata( new MetadataPhpAdapter() );
+
+ $User = User::newFromName( $this->params['user-name'] );
+
+ $UploadHandler = new UploadHandler(
array(
- 'User' => $this->_User
+ 'Mapping' => $Mapping,
+ 'MediawikiTemplate' => $MediawikiTemplate,
+ 'Metadata' => $Metadata,
+ 'User' => $User,
)
);
- $this->_UploadHandler->user_options =
$this->params['user_options'];
- $result = $this->_UploadHandler->saveMediafileAsContent(
$this->params );
+ $MediawikiTemplate->metadata_raw =
$this->params['options']['metadata-raw'];
+ $MediawikiTemplate->populateFromArray(
+
$this->params['options']['metadata-mapped-to-mediawiki-template']
+ );
- return $result;
- }
+ $Metadata->metadata_raw =
$this->params['options']['metadata-raw'];
+ $Metadata->metadata_as_array =
$this->params['options']['metadata-as-array'];
- /**
- * @return {bool}
- */
- protected function validateParams() {
- $result = true;
-
- if ( empty( $this->params['username'] ) ) {
- error_log( __METHOD__ . ' : no
$this->params[\'username\'] provided' . PHP_EOL );
- $result = false;
- }
-
- if ( empty( $this->params['user_options'] ) ) {
- error_log( __METHOD__ . ' : no
$this->params[\'user_options\'] provided' . PHP_EOL );
- $result = false;
- }
+ $result = $UploadHandler->saveMediafileAsContent(
$this->params['user-options'] );
return $result;
}
@@ -89,16 +92,53 @@
return $result;
}
- $this->_User = User::newFromName( $this->params['username'] );
-
try {
$result = $this->processMetadata();
} catch ( MWException $e ) {
- error_log( $e->getMessage() );
+ $this->setLastError(
+ __METHOD__ . ': ' .
+ $e->getMessage() .
+ print_r( $this->params['user-options'], true )
+ );
}
- if ( !$result ) {
- error_log( "Could not save [ {$this->params['title']} ]
to the wiki." );
+ return $result;
+ }
+
+ /**
+ * @return {bool}
+ */
+ protected function validateParams() {
+ $result = true;
+
+ if ( empty( $this->params['options'] ) ) {
+ $this->setLastError( __METHOD__ . ': no
$this->params[\'options\'] provided' );
+ $result = false;
+ }
+
+ if ( empty(
$this->params['options']['metadata-mapped-to-mediawiki-template'] ) ) {
+ $this->setLastError(
+ __METHOD__ .
+ ': no
$this->params[\'options\'][\'metadata-mapped-to-mediawiki-template\'] provided'
+ );
+ $result = false;
+ }
+
+ if ( empty( $this->params['options']['metadata-raw'] ) ) {
+ $this->setLastError(
+ __METHOD__ . ': no
$this->params[\'options\'][\'metadata-raw\'] provided'
+ );
+ $result = false;
+ }
+
+ if ( empty( $this->params['user-name'] ) ) {
+ $this->setLastError( __METHOD__ . ': no
$this->params[\'user-name\'] provided' );
+ $result = false;
+ }
+
+ if ( empty( $this->params['user-options'] ) ) {
+ $this->setLastError( __METHOD__ . ': no
$this->params[\'user-options\'] provided' );
+ $result = false;
}
return $result;
diff --git a/includes/Models/Mapping.php b/includes/Models/Mapping.php
index 3618f3b..5ba42e3 100644
--- a/includes/Models/Mapping.php
+++ b/includes/Models/Mapping.php
@@ -108,18 +108,13 @@
* relies on a hardcoded path to the metadata mapping url
*
* @param {array} $options
- *
* @throws {MWException}
- *
* @return {string}
* the string is not filtered
*/
protected function getMappingName( array $options ) {
$result = null;
-
- $Languages = new Language();
- $namespace = $Languages->getNamespaces();
- $namespace = $namespace[Config::$metadata_namespace] . ':';
+ $namespace = \GWToolset\getNamespaceName(
Config::$metadata_namespace );
if ( !empty( $options['Metadata-Mapping-Title'] ) ) {
$result = str_replace(
diff --git a/includes/Models/Metadata.php b/includes/Models/Metadata.php
new file mode 100644
index 0000000..0607c47
--- /dev/null
+++ b/includes/Models/Metadata.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * GWToolset
+ *
+ * @file
+ * @ingroup Extensions
+ * @license GNU General Public License 3.0 http://www.gnu.org/licenses/gpl.html
+ */
+
+namespace GWToolset\Models;
+use GWToolset\Adapters\DataAdapterInterface,
+ GWToolset\Config,
+ Php\Filter;
+
+class Metadata implements ModelInterface {
+ /**
+ * @var {array}
+ */
+ public $metadata_as_array;
+
+ /**
+ * @var {string}
+ * a raw representation of the original metadata
+ */
+ public $metadata_raw;
+
+ /**
+ * @var {DataAdapterInterface}
+ */
+ protected $_DataAdapater;
+
+ /**
+ * @param {DataAdapterInterface} $DataAdapter
+ */
+ public function __construct( DataAdapterInterface $DataAdapter ) {
+ $this->reset();
+ $this->_DataAdapater = $DataAdapter;
+ }
+
+ /**
+ * @param {array} $options
+ */
+ public function create( array $options = array() ) {
+ }
+
+ /**
+ * @param {array} $options
+ */
+ public function delete( array &$options = array() ) {
+ }
+
+ /**
+ * locates an element within the metadata and concatenates its values
when there is more than
+ * one of the same element within the metadata
+ *
+ * @todo should we cache the concatenated fields or pre-populate all of
them?
+ *
+ * @param {string}
+ *
+ * @return {null|string}
+ * the string is filtered
+ */
+ public function getConcatenatedField( $field = null ) {
+ $result = null;
+
+ if ( empty( $field ) || !is_string( $field ) ) {
+ return $result;
+ }
+
+ if ( array_key_exists( $field, $this->metadata_as_array ) ) {
+ foreach ( $this->metadata_as_array[$field] as $key =>
$value ) {
+ if ( $key === '@attributes' ) {
+ continue;
+ }
+
+ if ( strpos( $value, '://' ) !== false ) {
+ $result .=
+ Filter::evaluate(
+ array(
+ 'source' =>
$value,
+
'filter-sanitize' => FILTER_SANITIZE_URL
+ )
+ ) .
+ Config::$metadata_separator .
+ ' ';
+ } else {
+ $result .= Filter::evaluate( $value ) .
Config::$metadata_separator . ' ';
+ }
+ }
+ }
+
+ $result = rtrim( $result, Config::$metadata_separator );
+
+ return $result;
+ }
+
+ public function reset() {
+ $this->metadata_as_array = array();
+ $this->metadata_raw = null;
+ $this->_DataAdapater = null;
+ }
+
+ /**
+ * @param {array} $options
+ */
+ public function retrieve( array &$options = array() ) {
+ }
+
+ /**
+ * @param {array} $options
+ */
+ public function update( array &$options = array() ) {
+ }
+}
diff --git a/includes/functions/functions.php b/includes/functions/functions.php
index c778330..faf6b26 100644
--- a/includes/functions/functions.php
+++ b/includes/functions/functions.php
@@ -69,13 +69,37 @@
}
/**
+ * based on a namespace number, returns the namespace name
+ *
+ * @param {int} $namespace
+ * @return {null|string}
+ * the result is not filtered
+ */
+function getNamespaceName( $namespace = 0 ) {
+ $result = null;
+
+ if ( !is_int( $namespace ) ) {
+ return $result;
+ }
+
+ $Languages = new Language();
+ $namespaces = $Languages->getNamespaces();
+
+ if ( isset( $namespaces[$namespace] ) ) {
+ $result = $namespaces[$namespace] . ':';
+ }
+
+ return $result;
+}
+
+/**
* attempts to retrieve a wiki title based on a given page title, an
* optional namespace requirement and whether or not the title must be known
*
- * @param {String} $page_title
+ * @param {string} $page_title
* @param {Int} $namespace
- * @param {Array} $options
- * {Boolean} $options['must-be-known']
+ * @param {array} $options
+ * {boolean} $options['must-be-known']
* Whether or not the Title must be known; defaults to true
*
* @throws {MWException}
@@ -138,6 +162,23 @@
}
/**
+ * @param {string} $category
+ * @return {null|string}
+ * the result has not been filtered
+ */
+function stripIllegalCategoryChars( $category = null ) {
+ $result = null;
+
+ if ( empty( $category ) || !is_string( $category ) ) {
+ return $result;
+ }
+
+ $result = str_replace( array( '[', ']' ), '', $category );
+
+ return $result;
+}
+
+/**
* replaces illegal characters in a title with a replacement character,
defaults to ‘-’.
* illegal characters are based on Commons:File_naming and other bad title
articles.
* Title::secureAndSplit() allows some of these characters.
@@ -150,10 +191,10 @@
* @param {string} $title
*
* @param {array} $options
- * {Boolean} $options['allow-subpage']
+ * {boolean} $options['allow-subpage']
* allows for the ‘/’ subpage character
*
- * {String} $options['replacement']
+ * {string} $options['replacement']
* the character used to replace illegal characters; defaults to ‘-’
*
* @return {string} the string is not filtered
@@ -184,8 +225,8 @@
/**
* wfSuppressWarnings() lowers the error_reporting threshold because the
- * script that follows it is “allowed” to produce warnings, thus, only
- * handle errors this way when error_reporting is set to >= E_ALL
+ * script that follows it is “allowed” to produce warnings, thus, only
+ * throw an exception when error_reporting is set to >= E_ALL
*
* @param {int} $errno
* @param {string} $errstr
@@ -203,7 +244,7 @@
if ( $errno > E_WARNING ) {
error_log( $errstr . ' in ' . $errfile . ' on line nr '
. $errline );
- throw new ErrorException( $errormsg, 0, $errno,
$errfile, $errline );
+ throw new MWException( $errormsg );
} else {
echo $errormsg;
}
--
To view, visit https://gerrit.wikimedia.org/r/90527
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I5b23b8af2d2c572af97ae179761b37091bab6a85
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/GWToolset
Gerrit-Branch: master
Gerrit-Owner: Dan-nl <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits