Addshore has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/363020 )
Change subject: Allow recovery from invalid chars in title exception
......................................................................
Allow recovery from invalid chars in title exception
Change-Id: Ib99aa3e105370dfc9fb5564d4cf35b254e6b5684
---
M extension.json
M i18n/en.json
M i18n/qqq.json
A src/Exceptions/RecoverableTitleImportException.php
D src/Exceptions/TitleConflictException.php
M src/Exceptions/TitleException.php
A src/Html/RecoverableTitleExceptionPage.php
D src/Html/TitleConflictPage.php
M src/Services/ImportPlanValidator.php
M src/SpecialImportFile.php
M tests/phpunit/Services/ImportPlanValidatorTest.php
11 files changed, 160 insertions(+), 127 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/FileImporter
refs/changes/20/363020/1
diff --git a/extension.json b/extension.json
index 8b0b701..898b298 100644
--- a/extension.json
+++ b/extension.json
@@ -37,9 +37,9 @@
"FileImporter\\Exceptions\\ImportException":
"src/Exceptions/ImportException.php",
"FileImporter\\Exceptions\\InvalidArgumentException":
"src/Exceptions/InvalidArgumentException.php",
"FileImporter\\Exceptions\\LocalizedImportException":
"src/Exceptions/LocalizedImportException.php",
+ "FileImporter\\Exceptions\\RecoverableTitleImportException":
"src/Exceptions/RecoverableTitleImportException.php",
"FileImporter\\Exceptions\\SourceUrlException":
"src/Exceptions/SourceUrlException.php",
"FileImporter\\Exceptions\\TitleException":
"src/Exceptions/TitleException.php",
- "FileImporter\\Exceptions\\TitleConflictException":
"src/Exceptions/TitleConflictException.php",
"FileImporter\\Interfaces\\DetailRetriever":
"src/Interfaces/DetailRetriever.php",
"FileImporter\\Interfaces\\ImportTitleChecker":
"src/Interfaces/ImportTitleChecker.php",
"FileImporter\\Interfaces\\SourceUrlChecker":
"src/Interfaces/SourceUrlChecker.php",
@@ -59,7 +59,7 @@
"FileImporter\\Html\\ImportPreviewPage":
"src/Html/ImportPreviewPage.php",
"FileImporter\\Html\\ImportSuccessPage":
"src/Html/ImportSuccessPage.php",
"FileImporter\\Html\\InputFormPage":
"src/Html/InputFormPage.php",
- "FileImporter\\Html\\TitleConflictPage":
"src/Html/TitleConflictPage.php",
+ "FileImporter\\Html\\RecoverableTitleExceptionPage":
"src/Html/RecoverableTitleExceptionPage.php",
"FileImporter\\Html\\TextRevisionSnippet":
"src/Html/TextRevisionSnippet.php",
"FileImporter\\Remote\\MediaWiki\\ApiDetailRetriever":
"src/Remote/MediaWiki/ApiDetailRetriever.php",
"FileImporter\\Remote\\MediaWiki\\HttpApiLookup":
"src/Remote/MediaWiki/HttpApiLookup.php",
diff --git a/i18n/en.json b/i18n/en.json
index 4eccc05..aaf1655 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -21,6 +21,7 @@
"fileimporter-badimporthash": "Import hash does not match. Please
restart the import.",
"fileimporter-localtitleexists" : "The title you are currently trying
to import to already exists on this wiki.",
"fileimporter-sourcetitleexists" : "The title you are currently trying
to import to already exists on the source wiki.",
+ "fileimporter-illegalfilenamechars" : "The title you are currently
trying to import to contains illegal filename characters.",
"fileimporter-duplicatefilesdetected" : "The file you are currently
trying to import already exists on this wiki.",
"fileimporter-duplicatefilesdetected-prefix" : "Duplicates",
"fileimporter-exampleprefix": "Example",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index ec5c210..0f3c649 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -23,6 +23,7 @@
"fileimporter-badimporthash": "Error message shown on the special page
when the import hash for the request does not match the expected hash.",
"fileimporter-localtitleexists": "Error message shown on the special
page when the title to be imported to already exists on the local wiki.",
"fileimporter-sourcetitleexists": "Error message shown on the special
page when the title to be imported to already exists on the source wiki.",
+ "fileimporter-illegalfilenamechars" : "Error message shown on the
special page when the title to be imported to contains illegal characters as
defined by MediaWiki.",
"fileimporter-duplicatefilesdetected": "Error message shown on the
special page when the file to be imported has been detected as already existing
on the local wiki.",
"fileimporter-duplicatefilesdetected-prefix": "Prefix for the duplicate
file that has been found.\n{{Identical|Duplicate}}",
"fileimporter-exampleprefix": "Prefix for the example URL contained
within the URL text box on the special page.\n{{Identical|Example}}",
diff --git a/src/Exceptions/RecoverableTitleImportException.php
b/src/Exceptions/RecoverableTitleImportException.php
new file mode 100644
index 0000000..599424a
--- /dev/null
+++ b/src/Exceptions/RecoverableTitleImportException.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace FileImporter\Exceptions;
+
+use FileImporter\Data\ImportPlan;
+use MessageSpecifier;
+
+/**
+ * Exception thrown when an import has an issue with the planned title that
can be
+ * resolved by the user.
+ */
+class RecoverableTitleImportException extends LocalizedImportException {
+
+ /**
+ * @var ImportPlan
+ */
+ private $importPlan;
+
+ /**
+ * @param string|array|MessageSpecifier $messageSpec See
Message::newFromSpecifier
+ * @param ImportPlan $importPlan ImportPlan to recover the import of.
+ */
+ public function __construct( $messageSpec, ImportPlan $importPlan ) {
+ $this->importPlan = $importPlan;
+ parent::__construct( $messageSpec );
+ }
+
+ public function getImportPlan() {
+ return $this->importPlan;
+ }
+
+}
diff --git a/src/Exceptions/TitleConflictException.php
b/src/Exceptions/TitleConflictException.php
deleted file mode 100644
index 1fc7bd4..0000000
--- a/src/Exceptions/TitleConflictException.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-namespace FileImporter\Exceptions;
-
-use FileImporter\Data\ImportPlan;
-
-class TitleConflictException extends ImportException {
-
- const LOCAL_TITLE = 1;
- const REMOTE_TITLE = 2;
-
- private $importPlan;
- private $conflictType;
-
- /**
- * TitleConflictException constructor.
- *
- * @param ImportPlan $importPlan
- * @param int $conflictType Either LOCAL_TITLE or REMOTE_TITLE
- */
- public function __construct( ImportPlan $importPlan, $conflictType ) {
- $this->importPlan = $importPlan;
- $this->conflictType = $conflictType;
- parent::__construct( 'Title conflict detected' );
- }
-
- public function getImportPlan() {
- return $this->importPlan;
- }
-
- /**
- * @return int
- */
- public function getType() {
- return $this->conflictType;
- }
-
-}
diff --git a/src/Exceptions/TitleException.php
b/src/Exceptions/TitleException.php
index 2cdd538..a3240d8 100644
--- a/src/Exceptions/TitleException.php
+++ b/src/Exceptions/TitleException.php
@@ -2,6 +2,36 @@
namespace FileImporter\Exceptions;
+use Throwable;
+
class TitleException extends ImportException {
+ /**
+ * The user could recover this title exception by changing the title.
+ */
+ const IS_RECOVERABLE = 1;
+
+ /**
+ * The user can not recover this title exception by changing the title.
+ */
+ const IS_NOT_RECOVERABLE = 0;
+
+ /**
+ * TitleException constructor.
+ *
+ * @param string $message
+ * @param int $code Either IS_RECOVERABLE or IS_NOT_RECOVERABLE
+ * @param Throwable|null $previous
+ */
+ public function __construct( $message = "", $code =
self::IS_NOT_RECOVERABLE, Throwable $previous = null ) {
+ parent::__construct( $message, $code, $previous );
+ }
+
+ /**
+ * @return bool Can the user recover this TitleException?
+ */
+ public function isRecoverable() {
+ return $this->code === self::IS_RECOVERABLE;
+ }
+
}
diff --git a/src/Html/RecoverableTitleExceptionPage.php
b/src/Html/RecoverableTitleExceptionPage.php
new file mode 100644
index 0000000..5714c80
--- /dev/null
+++ b/src/Html/RecoverableTitleExceptionPage.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace FileImporter\Html;
+
+use FileImporter\Exceptions\RecoverableTitleImportException;
+use Html;
+use SpecialPage;
+
+/**
+ * Html showing an error and the ChangeTitleForm
+ */
+class RecoverableTitleExceptionPage {
+
+ /**
+ * @var SpecialPage
+ */
+ private $specialPage;
+
+ /**
+ * @var RecoverableTitleImportException
+ */
+ private $exception;
+
+ /**
+ * @param SpecialPage $specialPage
+ * @param RecoverableTitleImportException $exception
+ */
+ public function __construct(
+ SpecialPage $specialPage,
+ RecoverableTitleImportException $exception
+ ) {
+ $this->specialPage = $specialPage;
+ $this->exception = $exception;
+ }
+
+ private function getMessageInPageLanguage() {
+ return $this->exception
+ ->getMessageObject()
+ ->inLanguage( $this->specialPage->getLanguage() )
+ ->plain();
+ }
+
+ public function getHtml() {
+ return Html::rawElement(
+ 'div',
+ [ 'class' => 'warningbox' ],
+ Html::element( 'p', [], (
$this->getMessageInPageLanguage() ) )
+ ) .
+ ( new ChangeTitleForm(
+ $this->specialPage,
+ $this->exception->getImportPlan()
+ ) )->getHtml();
+ }
+
+}
diff --git a/src/Html/TitleConflictPage.php b/src/Html/TitleConflictPage.php
deleted file mode 100644
index 2351ccb..0000000
--- a/src/Html/TitleConflictPage.php
+++ /dev/null
@@ -1,57 +0,0 @@
-<?php
-
-namespace FileImporter\Html;
-
-use FileImporter\Data\ImportPlan;
-use Html;
-use Message;
-use SpecialPage;
-
-/**
- * Html showing a title conflict error and ChangeTitleForm
- */
-class TitleConflictPage {
-
- /**
- * @var SpecialPage
- */
- private $specialPage;
-
- /**
- * @var string
- */
- private $warningMessage;
-
- /**
- * @var ImportPlan
- */
- private $importPlan;
-
- /**
- * @param SpecialPage $specialPage
- * @param ImportPlan $importPlan
- * @param string $warningMessage
- */
- public function __construct(
- SpecialPage $specialPage,
- ImportPlan $importPlan,
- $warningMessage
- ) {
- $this->specialPage = $specialPage;
- $this->importPlan = $importPlan;
- $this->warningMessage = $warningMessage;
- }
-
- public function getHtml() {
- return Html::rawElement(
- 'div',
- [ 'class' => 'warningbox' ],
- Html::element( 'p', [], ( new Message(
$this->warningMessage ) )->plain() )
- ) .
- ( new ChangeTitleForm(
- $this->specialPage,
- $this->importPlan
- ) )->getHtml();
- }
-
-}
diff --git a/src/Services/ImportPlanValidator.php
b/src/Services/ImportPlanValidator.php
index 1a0c113..98009d5 100644
--- a/src/Services/ImportPlanValidator.php
+++ b/src/Services/ImportPlanValidator.php
@@ -4,7 +4,7 @@
use FileImporter\Data\ImportPlan;
use FileImporter\Exceptions\DuplicateFilesException;
-use FileImporter\Exceptions\TitleConflictException;
+use FileImporter\Exceptions\RecoverableTitleImportException;
use FileImporter\Exceptions\TitleException;
use FileImporter\Interfaces\ImportTitleChecker;
@@ -37,15 +37,16 @@
*
* @param ImportPlan $importPlan The plan to be validated
*
- * @throws DuplicateFilesException When a file with the same hash is
detected
- * @throws TitleConflictException When either a local or remote title
conflict was detected
+ * @throws TitleException When there is a problem with the planned
title (can't be fixed easily).
+ * @throws DuplicateFilesException When a file with the same hash is
detected locally..
+ * @throws RecoverableTitleImportException When there is a problem with
the title that can be fixed.
*/
public function validate( ImportPlan $importPlan ) {
// Checks the extension doesn't provide easy ways to fix
- $this->runFileTitleCheck( $importPlan );
$this->runFileExtensionCheck( $importPlan );
$this->runDuplicateFilesCheck( $importPlan );
// Checks that can be fixed in the extension
+ $this->runFileTitleCheck( $importPlan );
$this->runLocalTitleConflictCheck( $importPlan );
$this->runRemoteTitleConflictCheck( $importPlan );
}
@@ -53,7 +54,10 @@
private function runFileTitleCheck( ImportPlan $importPlan ) {
$plannedTitleText = $importPlan->getTitle()->getText();
if ( $plannedTitleText != wfStripIllegalFilenameChars(
$plannedTitleText ) ) {
- throw new TitleException( 'The target filename is
invalid' );
+ throw new RecoverableTitleImportException(
+ 'fileimporter-illegalfilenamechars',
+ $importPlan
+ );
}
}
@@ -89,7 +93,10 @@
private function runLocalTitleConflictCheck( ImportPlan $importPlan ) {
if ( $importPlan->getTitle()->exists() ) {
- throw new TitleConflictException( $importPlan,
TitleConflictException::LOCAL_TITLE );
+ throw new RecoverableTitleImportException(
+ 'fileimporter-localtitleexists',
+ $importPlan
+ );
}
}
@@ -104,7 +111,10 @@
$title->getText() !==
$details->getSourceLinkTarget()->getText() &&
!$this->importTitleChecker->importAllowed(
$request->getUrl(), $title->getText() )
) {
- throw new TitleConflictException( $importPlan,
TitleConflictException::REMOTE_TITLE );
+ throw new RecoverableTitleImportException(
+ 'fileimporter-sourcetitleexists',
+ $importPlan
+ );
}
}
diff --git a/src/SpecialImportFile.php b/src/SpecialImportFile.php
index 3ea287e..7fffc29 100644
--- a/src/SpecialImportFile.php
+++ b/src/SpecialImportFile.php
@@ -9,13 +9,14 @@
use FileImporter\Data\SourceUrl;
use FileImporter\Exceptions\DuplicateFilesException;
use FileImporter\Exceptions\ImportException;
-use FileImporter\Exceptions\TitleConflictException;
+use FileImporter\Exceptions\RecoverableTitleImportException;
+use FileImporter\Exceptions\TitleException;
use FileImporter\Html\ChangeTitleForm;
use FileImporter\Html\DuplicateFilesPage;
use FileImporter\Html\ImportPreviewPage;
use FileImporter\Html\ImportSuccessPage;
use FileImporter\Html\InputFormPage;
-use FileImporter\Html\TitleConflictPage;
+use FileImporter\Html\RecoverableTitleExceptionPage;
use FileImporter\Services\DuplicateFileRevisionChecker;
use FileImporter\Services\Importer;
use FileImporter\Services\ImportPlanValidator;
@@ -148,21 +149,10 @@
return;
}
- if ( $exception instanceof TitleConflictException ) {
- switch ( $exception->getType() ) {
- case TitleConflictException::LOCAL_TITLE:
- $titleConflictMessage =
'fileimporter-localtitleexists';
- break;
- case TitleConflictException::REMOTE_TITLE:
- $titleConflictMessage =
'fileimporter-sourcetitleexists';
- break;
- default:
- throw $exception;
- }
- $this->getOutput()->addHTML( ( new TitleConflictPage(
+ if ( $exception instanceof RecoverableTitleImportException ) {
+ $this->getOutput()->addHTML( ( new
RecoverableTitleExceptionPage(
$this,
- $exception->getImportPlan(),
- $titleConflictMessage
+ $exception
) )->getHtml() );
return;
}
@@ -172,7 +162,7 @@
}
/**
- * @throws
DuplicateFilesException|TitleConflictException|ImportException
+ * @throws ImportException
* @return ImportPlan
*/
private function getImportPlan() {
diff --git a/tests/phpunit/Services/ImportPlanValidatorTest.php
b/tests/phpunit/Services/ImportPlanValidatorTest.php
index 5891194..3ded3ca 100644
--- a/tests/phpunit/Services/ImportPlanValidatorTest.php
+++ b/tests/phpunit/Services/ImportPlanValidatorTest.php
@@ -10,7 +10,7 @@
use FileImporter\Data\ImportRequest;
use FileImporter\Data\SourceUrl;
use FileImporter\Exceptions\DuplicateFilesException;
-use FileImporter\Exceptions\TitleConflictException;
+use FileImporter\Exceptions\RecoverableTitleImportException;
use FileImporter\Exceptions\TitleException;
use FileImporter\Interfaces\ImportTitleChecker;
use FileImporter\Services\DuplicateFileRevisionChecker;
@@ -144,7 +144,10 @@
$this->getMockImportTitleChecker( 0, true )
],
'Invalid, title exists on target site' => [
- new TitleConflictException( $emptyPlan, 'Title
conflict detected' ),
+ new RecoverableTitleImportException(
+ 'fileimporter-localtitleexists',
+ $emptyPlan
+ ),
$this->getMockImportPlan(
$this->getMockTitle( 'FinalName.JPG',
true ),
$this->getMockTitle( 'SourceName.JPG',
false )
@@ -153,7 +156,10 @@
$this->getMockImportTitleChecker( 0, true )
],
'Invalid, title exists on source site' => [
- new TitleConflictException( $emptyPlan, 'Title
conflict detected' ),
+ new RecoverableTitleImportException(
+ 'fileimporter-sourcetitleexists',
+ $emptyPlan
+ ),
$this->getMockImportPlan(
$this->getMockTitle( 'FinalName.JPG',
false ),
$this->getMockTitle( 'SourceName.JPG',
false )
@@ -171,7 +177,7 @@
$this->getMockImportTitleChecker( 1, true )
],
'Invalid, No Extension on planned name' => [
- new TitleException( 'The target filename is
invalid' ),
+ new TitleException( 'Planned file name does not
have an extension' ),
$this->getMockImportPlan(
$this->getMockTitle(
'FinalName.JPG/Foo', false ),
$this->getMockTitle( 'SourceName.jpg',
false )
@@ -189,12 +195,15 @@
$this->getMockImportTitleChecker( 0, true )
],
'Invalid, Bad title (includes another namespace)' => [
- new TitleException( 'The target filename is
invalid' ),
+ new RecoverableTitleImportException(
+ 'fileimporter-illegalfilenamechars',
+ $emptyPlan
+ ),
$this->getMockImportPlan(
$this->getMockTitle(
'Talk:FinalName.JPG', false ),
$this->getMockTitle( 'SourceName.JPG',
false )
),
- $this->getMockDuplicateFileRevisionChecker( 0,
0 ),
+ $this->getMockDuplicateFileRevisionChecker( 1,
0 ),
$this->getMockImportTitleChecker( 0, true )
],
];
--
To view, visit https://gerrit.wikimedia.org/r/363020
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib99aa3e105370dfc9fb5564d4cf35b254e6b5684
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/FileImporter
Gerrit-Branch: master
Gerrit-Owner: Addshore <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits