(bug 47070) check content model namespace on import.
authordaniel <daniel.kinzler@wikimedia.de>
Tue, 10 Dec 2013 13:36:52 +0000 (14:36 +0100)
committerDaniel Kinzler <daniel.kinzler@wikimedia.de>
Tue, 17 Dec 2013 16:58:57 +0000 (16:58 +0000)
When importing, we need to check that the kind of content we are about to
import is actually allowed in the specified location on the local wiki.

This change does two things:

* Introduce the ContentModelCanBeUsedOn hook which provides control over
which kind of content can be used where.

* Introduce a check against ContentHandler::canBeUsedOn in the importer,
along with an appropriate error message.

Change-Id: Ia2ff0b0474f4727c9ebbba3c0a2a111495055f61

docs/hooks.txt
includes/Import.php
includes/content/ContentHandler.php
languages/messages/MessagesEn.php
languages/messages/MessagesQqq.php
maintenance/language/messages.inc

index e3387b5..dbeaa6e 100644 (file)
@@ -830,6 +830,15 @@ content model name, but no entry for that model exists in $wgContentHandlers.
 $modeName: the requested content model name
 &$handler: set this to a ContentHandler object, if desired.
 
+'ContentModelCanBeUsedOn': Called to determine whether that content model can
+be used on a given page. This is especially useful to prevent some content models
+to be used in some special location.
+$contentModel: ID of the content model in question
+$title: the Title in question.
+&$ok: Output parameter, whether it is OK to use $contentModel on $title.
+Handler functions that modify $ok should generally return false to prevent further
+hooks from further modifying $ok.
+
 'ConvertContent': Called by AbstractContent::convert when a conversion to another
 content model is requested.
 $content: The Content object to be converted.
index 8b7af02..2770e47 100644 (file)
@@ -252,6 +252,16 @@ class WikiImporter {
         * @return bool
         */
        public function importRevision( $revision ) {
+               if ( !$revision->getContent()->getContentHandler()->canBeUsedOn( $revision->getTitle() ) ) {
+                       $this->notice( 'import-error-bad-location',
+                               $revision->getTitle()->getPrefixedText(),
+                               $revision->getID(),
+                               $revision->getModel(),
+                               $revision->getFormat() );
+
+                       return false;
+               }
+
                try {
                        $dbw = wfGetDB( DB_MASTER );
                        return $dbw->deadlockLoop( array( $revision, 'importOldRevision' ) );
@@ -262,6 +272,8 @@ class WikiImporter {
                                $revision->getModel(),
                                $revision->getFormat() );
                }
+
+               return false;
        }
 
        /**
index 1abe1fa..200d453 100644 (file)
@@ -677,12 +677,19 @@ abstract class ContentHandler {
         * typically based on the namespace or some other aspect of the title, such as a special suffix
         * (e.g. ".svg" for SVG content).
         *
+        * @note: this calls the ContentHandlerCanBeUsedOn hook which may be used to override which
+        * content model can be used where.
+        *
         * @param Title $title the page's title.
         *
         * @return bool true if content of this kind can be used on the given page, false otherwise.
         */
        public function canBeUsedOn( Title $title ) {
-               return true;
+               $ok = true;
+
+               wfRunHooks( 'ContentModelCanBeUsedOn', array( $this->getModelID(), $title, &$ok ) );
+
+               return $ok;
        }
 
        /**
index 4ec3ee8..88e68a0 100644 (file)
@@ -3594,7 +3594,7 @@ The file was only partially uploaded.',
 A temporary folder is missing.',
 'import-parse-failure'       => 'XML import parse failure',
 'import-noarticle'           => 'No page to import!',
-'import-nonewrevisions'      => 'All revisions were previously imported.',
+'import-nonewrevisions'      => 'No revisions imported (all were either already present, or skipped due to errors).',
 'xml-error-string'           => '$1 at line $2, col $3 (byte $4): $5',
 'import-upload'              => 'Upload XML data',
 'import-token-mismatch'      => 'Loss of session data.
@@ -3606,6 +3606,7 @@ Please try again.',
 'import-error-special'       => 'Page "$1" is not imported because it belongs to a special namespace that does not allow pages.',
 'import-error-invalid'       => 'Page "$1" is not imported because its name is invalid.',
 'import-error-unserialize'   => 'Revision $2 of page "$1" could not be unserialized. The revision was reported to use content model $3 serialized as $4.',
+'import-error-bad-location'  => 'Revision $2 using content model $3 can not be stored on "$1" on this wiki, since that model is not supported on that page.',
 'import-options-wrong'       => 'Wrong {{PLURAL:$2|option|options}}: <nowiki>$1</nowiki>',
 'import-rootpage-invalid'    => 'Given root page is an invalid title.',
 'import-rootpage-nosubpage'  => 'Namespace "$1" of the root page does not allow subpages.',
index 483fd25..b333682 100644 (file)
@@ -7279,7 +7279,8 @@ See also:
 See also:
 * {{msg-mw|Import-noarticle}}
 * {{msg-mw|Importbadinterwiki}}',
-'import-nonewrevisions' => 'Used in [[Special:Import]].',
+'import-nonewrevisions' => 'Used in [[Special:Import]] to indicate that no revisions were imported.
+This may be due to the revisions already being present, or to errors when importing them.',
 'xml-error-string' => 'Parameters:
 * $1 - Some kind of message, perhaps name of the error?
 * $2 - line number
@@ -7327,6 +7328,17 @@ Parameters:
 
 This may happen if the content got corrupted or the serialization format is mis-reported.
 
+Parameters:
+* $1 - the name of the page the offending revision belongs to
+* $2 - the ID of the offending revision, as reported in the dump that is being imported
+* $3 - the content model reported for the offending revision in the dump that is being imported
+* $4 - the serialization format reported for the offending revision in the dump that is being imported
+{{Related|Import-error}}',
+'import-error-bad location' => 'Import error message displayed when trying to import a page to a title that is not allowed for this kind of content on this wiki.
+
+This may happen for content models bound to specific namespaces or title patterns, if the configuration of the allowed namespaces
+or titles differs from the configuration on the source wiki.
+
 Parameters:
 * $1 - the name of the page the offending revision belongs to
 * $2 - the ID of the offending revision, as reported in the dump that is being imported
index 40bc31d..76de144 100644 (file)
@@ -2521,6 +2521,7 @@ $wgMessageStructure = array(
                'import-error-special',
                'import-error-invalid',
                'import-error-unserialize',
+               'import-error-bad-location',
                'import-options-wrong',
                'import-rootpage-invalid',
                'import-rootpage-nosubpage',