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

Change subject: Special:EnableFlow archives pre-existing talk page
......................................................................


Special:EnableFlow archives pre-existing talk page

Enabling flow on an existing talk page is now accepted.
It tries to archive the talk page to a subpage.

The name of the archive is configurable using a new
form field. The default value is %s/Archive_%d and
it is localized.

It uses a template named "Wikitext talk page converted to Flow"
to add a reference to the archive page at the top of
the flow board.

It uses a template named "Archive for converted wikitext talk page"
to add a reference to the flow board at the top of
the archive page.

Bug: T72073
Change-Id: If3b23383e4289290cde1237b74a4bbbb6bdcb455
---
M autoload.php
M container.php
M i18n/en.json
M i18n/qqq.json
M includes/Import/Converter.php
M includes/Import/Importer.php
M includes/Import/Wikitext/ConversionStrategy.php
M includes/Import/Wikitext/ImportSource.php
A includes/Log/DefaultLogger.php
M includes/Specials/SpecialEnableFlow.php
M maintenance/convertLqt.php
M maintenance/convertLqtPageOnLocalWiki.php
M maintenance/convertNamespaceFromWikitext.php
13 files changed, 170 insertions(+), 57 deletions(-)

Approvals:
  Matthias Mullie: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/autoload.php b/autoload.php
index ff9e156..c66d2ac 100644
--- a/autoload.php
+++ b/autoload.php
@@ -216,6 +216,7 @@
        'Flow\\Import\\Wikitext\\ImportSource' => __DIR__ . 
'/includes/Import/Wikitext/ImportSource.php',
        'Flow\\LinksTableUpdater' => __DIR__ . 
'/includes/LinksTableUpdater.php',
        'Flow\\Log\\ActionFormatter' => __DIR__ . 
'/includes/Log/ActionFormatter.php',
+       'Flow\\Log\\DefaultLogger' => __DIR__ . 
'/includes/Log/DefaultLogger.php',
        'Flow\\Log\\LogQuery' => __DIR__ . '/includes/Log/Query.php',
        'Flow\\Log\\LqtImportFormatter' => __DIR__ . 
'/includes/Log/LqtImportFormatter.php',
        'Flow\\Log\\ModerationLogger' => __DIR__ . 
'/includes/Log/ModerationLogger.php',
diff --git a/container.php b/container.php
index cb286b4..fb590f4 100644
--- a/container.php
+++ b/container.php
@@ -1219,4 +1219,13 @@
        );
 };
 
+$c['parser'] = function() {
+       global $wgParser;
+       return $wgParser;
+};
+
+$c['default_logger'] = function() {
+       return new Flow\Log\DefaultLogger();
+};
+
 return $c;
diff --git a/i18n/en.json b/i18n/en.json
index 005d542..e9448d9 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -392,7 +392,10 @@
        "flow-special-enableflow-header": "Initial description of Flow board 
(wikitext)",
        "flow-special-enableflow-board-already-exists": "There is already a 
Flow board at [[$1]].",
        "flow-special-enableflow-invalid-title": "The provided page is not a 
valid page title",
-       "flow-special-enableflow-page-already-exists": "There is already a 
non-Flow page at [[$1]]. If you still want to locate a Flow board there, please 
move the existing page to an archive, delete the redirect, then use 
Special:EnableFlow again. Include the archive name in the description.",
+       "flow-special-enableflow-archive-title-format": "Where to archive 
existing content",
+       "flow-special-enableflow-archive-title-format-default-value": 
"%s/Archive_%d",
+       "flow-special-enableflow-board-creation-not-allowed": "You are not 
allowed to create a Flow board at [[:$1]].",
+       "flow-special-enableflow-page-is-liquidthreads": "There is a 
LiquidThreads page at [[:$1]].",
        "flow-special-enableflow-confirmation": "You have successfully created 
a Flow board at [[$1]].",
        "flow-spam-confirmedit-form": "Please confirm you are a human by 
solving the below captcha: $1",
        "flow-embedding-unsupported": "Discussions cannot be embedded yet.",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index e29ac96..7823fd6 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -394,10 +394,13 @@
        "flow-special-invalid-uuid": "Error message shown on the redirector 
special page if the specified type / UUID combination is invalid",
        "flow-special-enableflow-legend": "Legend for Special:EnableFlow form",
        "flow-special-enableflow-page": "Label for the page field of 
Special:EnableFlow",
+       "flow-special-enableflow-archive-title-format": "Label for the archive 
format field of Special:EnableFlow",
+       "flow-special-enableflow-archive-title-format-default-value": "Default 
value for the archive format field of Special:EnableFlow. This is a format 
string. %s and %d should be present. %s represents the title of the page where 
Flow is being enabled. %d represents a number that will be incremented if an 
archive page with the same name already exist.",
        "flow-special-enableflow-header": "Label for the header field of 
Special:EnableFlow",
        "flow-special-enableflow-board-already-exists": "Error given on 
Special:EnableFlow if board already exists at requested page name.  
Parameters:\n$1 - Page name where user requested to put Flow board",
        "flow-special-enableflow-invalid-title": "Error given on 
Special:EnableFlow if the provided page is not a valid page name.",
-       "flow-special-enableflow-page-already-exists": "Error given on 
Special:EnableFlow if a non-Flow page already exists at requested page name.  
Parameters:\n$1 - Page name where user requested to put Flow board",
+       "flow-special-enableflow-board-creation-not-allowed": "Error given on 
Special:EnableFlow if the current user is not allowed to create a Flow board.  
Parameters:\n$1 - Page name where user requested to put Flow board",
+       "flow-special-enableflow-page-is-liquidthreads": "Error given on 
Special:EnableFlow if the page to enable Flow on is a LiquidThreads page.  
Parameters:\n$1 - Page name where user requested to put Flow board",
        "flow-special-enableflow-confirmation": "Confirmation message on 
Special:EnableFlow saying that you have successfully created a board  
Parameters:\n$1 - Page name of new Flow board",
        "flow-spam-confirmedit-form": "Error message when ConfirmEdit flagged 
the submitted content (because an anonymous user submitted external links, 
possibly spam). A captcha will be displayed after this error message. 
Parameters:\n* $1 - the HTML for the captcha form.",
        "flow-embedding-unsupported": "Error message displayed if a user tries 
to transclude a Flow page.",
diff --git a/includes/Import/Converter.php b/includes/Import/Converter.php
index bd5e019..5e1e6cb 100644
--- a/includes/Import/Converter.php
+++ b/includes/Import/Converter.php
@@ -4,6 +4,7 @@
 
 use DatabaseBase;
 use Flow\Repository\TitleRepository;
+use Flow\Exception\FlowException;
 use MovePage;
 use MWExceptionHandler;
 use Psr\Log\LoggerInterface;
@@ -31,7 +32,7 @@
  */
 class Converter {
        /**
-        * @var DatabaseBase Slave database of the current wiki. Required
+        * @var DatabaseBase Master database of the current wiki. Required
         *  to lookup past page moves.
         */
        protected $dbw;
@@ -96,22 +97,15 @@
        }
 
        /**
+        * Converts multiple pages into Flow boards
+        *
         * @param Traversable<Title>|array $titles
         */
-       public function convert( $titles ) {
+       public function convertAll( $titles ) {
                /** @var Title $title */
                foreach ( $titles as $title ) {
                        try {
-                               $movedFrom = $this->getPageMovedFrom( $title );
-                               if ( ! $this->isAllowed( $title, $movedFrom ) ) 
{
-                                       continue;
-                               }
-
-                               if ( $this->strategy->isConversionFinished( 
$title, $movedFrom ) ) {
-                                       continue;
-                               }
-
-                               $this->doConversion( $title, $movedFrom );
+                               $this->convert( $title );
                        } catch ( \Exception $e ) {
                                MWExceptionHandler::logException( $e );
                                $this->logger->error( "Exception while 
importing: {$title}" );
@@ -120,6 +114,25 @@
                }
        }
 
+       /**
+        * Converts a page into a Flow board
+        *
+        * @param Title $title
+        */
+       public function convert( Title $title ) {
+               $movedFrom = $this->getPageMovedFrom( $title );
+               if ( ! $this->isAllowed( $title, $movedFrom ) ) {
+                       throw new FlowException( "Not allowed to convert: 
{$title}" );
+               }
+
+               // conversion is already done
+               if ( $this->strategy->isConversionFinished( $title, $movedFrom 
) ) {
+                       return;
+               }
+
+               $this->doConversion( $title, $movedFrom );
+       }
+
        protected function isAllowed( Title $title, Title $movedFrom = null ) {
                // Only make changes to wikitext pages
                if ( $title->getContentModel() !== CONTENT_MODEL_WIKITEXT ) {
diff --git a/includes/Import/Importer.php b/includes/Import/Importer.php
index 740eeb4..8b56617 100644
--- a/includes/Import/Importer.php
+++ b/includes/Import/Importer.php
@@ -18,6 +18,7 @@
 use Flow\Model\Workflow;
 use Flow\OccupationController;
 use Flow\WorkflowLoaderFactory;
+use Flow\Container;
 use IP;
 use MWCryptRand;
 use Psr\Log\LoggerInterface;
@@ -522,6 +523,7 @@
        public function import( PageImportState $state ) {
                $destinationTitle = $state->boardWorkflow->getArticleTitle();
                $state->logger->info( 'Importing to ' . 
$destinationTitle->getPrefixedText() );
+
                if ( $state->boardWorkflow->isNew() ) {
                        $this->occupationController->allowCreation(
                                $destinationTitle,
@@ -531,6 +533,7 @@
                                new Article( $destinationTitle ),
                                $state->boardWorkflow
                        );
+
                        $state->put( $state->boardWorkflow, array() );
                }
 
diff --git a/includes/Import/Wikitext/ConversionStrategy.php 
b/includes/Import/Wikitext/ConversionStrategy.php
index 546c9d8..e4339c6 100644
--- a/includes/Import/Wikitext/ConversionStrategy.php
+++ b/includes/Import/Wikitext/ConversionStrategy.php
@@ -38,12 +38,39 @@
        protected $parser;
 
        /**
+        * @var array $archiveTitleSuggestions
+        */
+       protected $archiveTitleSuggestions;
+
+       /**
+        * @var string $headerSuffix
+        */
+       protected $headerSuffix;
+
+       /**
         * @param Parser|StubObject $parser
         * @param ImportSourceStore $sourceStore
         */
-       public function __construct( $parser, ImportSourceStore $sourceStore ) {
+       public function __construct(
+               $parser,
+               ImportSourceStore $sourceStore,
+               $preferredArchiveTitle = null,
+               $headerSuffix = null
+       ) {
                $this->parser = $parser;
                $this->sourceStore = $sourceStore;
+               $this->headerSuffix = $headerSuffix;
+
+               if ( isset( $preferredArchiveTitle ) && !empty( 
$preferredArchiveTitle ) ) {
+                       $this->archiveTitleSuggestions = array( 
$preferredArchiveTitle );
+               } else {
+                       $this->archiveTitleSuggestions = array(
+                               '%s/Archive %d',
+                               '%s/Archive%d',
+                               '%s/archive %d',
+                               '%s/archive%d',
+                       );
+               }
        }
 
        /**
@@ -83,19 +110,14 @@
         * {@inheritDoc}
         */
        public function createImportSource( Title $title ) {
-               return new ImportSource( $title, $this->parser );
+               return new ImportSource( $title, $this->parser, 
$this->headerSuffix );
        }
 
        /**
         * {@inheritDoc}
         */
        public function decideArchiveTitle( Title $source ) {
-               return Converter::decideArchiveTitle( $source, array(
-                       '%s/Archive %d',
-                       '%s/Archive%d',
-                       '%s/archive %d',
-                       '%s/archive%d',
-               ) );
+               return Converter::decideArchiveTitle( $source, 
$this->archiveTitleSuggestions );
        }
 
        /**
diff --git a/includes/Import/Wikitext/ImportSource.php 
b/includes/Import/Wikitext/ImportSource.php
index 4b737cc..6a61388 100644
--- a/includes/Import/Wikitext/ImportSource.php
+++ b/includes/Import/Wikitext/ImportSource.php
@@ -25,14 +25,16 @@
        /**
         * @param Title $title
         * @param Parser|StubObject $parser
+        * @param string $headerSuffix
         * @throws ImportException When $title is an external title
         */
-       public function __construct( Title $title, $parser ) {
+       public function __construct( Title $title, $parser, $headerSuffix = 
null ) {
                if ( $title->isExternal() ) {
                        throw new ImportException( "Invalid non-local title: 
$title" );
                }
                $this->title = $title;
                $this->parser = $parser;
+               $this->headerSuffix = $headerSuffix;
        }
 
        /**
@@ -67,6 +69,10 @@
                ) );
                $content .= "\n\n{{{$template}|$arguments}}";
 
+               if ( $this->headerSuffix && !empty( $this->headerSuffix ) ) {
+                       $content .= "\n\n{$this->headerSuffix}";
+               }
+
                return new ImportHeader(
                        array( new ObjectRevision(
                                $content,
diff --git a/includes/Log/DefaultLogger.php b/includes/Log/DefaultLogger.php
new file mode 100644
index 0000000..17fb916
--- /dev/null
+++ b/includes/Log/DefaultLogger.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Flow\Log;
+
+use Psr\Log\AbstractLogger;
+use Psr\Log\LogLevel;
+
+class DefaultLogger extends AbstractLogger {
+
+       /**
+        * Sends everything to wfDebugLog for now.
+        *
+        * @param string $logLevel
+        * @param string $message
+        * @param array $context
+        */
+       public function log( $logLevel, $message, array $context = array() ) {
+               wfDebugLog( 'Flow ', $logLevel . ' ' . $message . ' ' . 
implode( ',', $context ) );
+       }
+}
diff --git a/includes/Specials/SpecialEnableFlow.php 
b/includes/Specials/SpecialEnableFlow.php
index d6f22fb..e89282d 100644
--- a/includes/Specials/SpecialEnableFlow.php
+++ b/includes/Specials/SpecialEnableFlow.php
@@ -6,6 +6,9 @@
 use Status;
 use Title;
 use Flow\Container;
+use Flow\Import\Converter;
+use Flow\Import\Wikitext\ConversionStrategy;
+use Flow\Import\NullImportSourceStore;
 
 /**
  * A special page that allows users with the flow-create-board right to create
@@ -38,6 +41,11 @@
                                'type' => 'text',
                                'label-message' => 
'flow-special-enableflow-page',
                        ),
+                       'archive-title-format' => array(
+                               'type' => 'text',
+                               'label-message' => 
'flow-special-enableflow-archive-title-format',
+                               'default' => $this->msg( 
'flow-special-enableflow-archive-title-format-default-value' )->text(),
+                       ),
                        'header' => array(
                                'type' => 'textarea',
                                'label-message' => 
'flow-special-enableflow-header'
@@ -54,7 +62,8 @@
        }
 
        /**
-        * Check that Flow board does not exist, then create it
+        * Creates a flow board.
+        * Archives any pre-existing wikitext talk page.
         *
         * @param array $data Form data
         * @return Status Status indicating result
@@ -73,44 +82,68 @@
                        return Status::newFatal( 
'flow-special-enableflow-board-already-exists', $page );
                }
 
-               if ( !$this->occupationController->allowCreation( $title, 
$this->getUser() ) ) {
-                       // This is the only plausible reason this method would 
return false here.
-                       // If there is another possible reason, we should have 
the method return a
-                       // Status.
-                       return Status::newFatal( 
'flow-special-enableflow-page-already-exists', $page );
+               if ( !$this->occupationController->allowCreation( $title, 
$this->getUser(), false ) ) {
+                       return Status::newFatal( 
'flow-special-enableflow-board-creation-not-allowed', $page );
                }
-
-               $loader = $this->loaderFactory->createWorkflowLoader( $title );
-               $blocks = $loader->getBlocks();
-
-               $action = 'edit-header';
-
-               $params = array(
-                       'header' => array(
-                               'content' => $data['header'],
-                               'format' => 'wikitext',
-                       ),
-               );
-
-               $blocksToCommit = $loader->handleSubmit(
-                       $this->getContext(),
-                       $action,
-                       $params
-               );
 
                $status = Status::newGood();
 
-               foreach( $blocks as $block ) {
-                       if ( $block->hasErrors() ) {
-                               $errors = $block->getErrors();
+               if ( $title->exists() ) {
 
-                               foreach( $errors as $errorKey ) {
-                                       $status->fatal( 
$block->getErrorMessage( $errorKey ) );
+                       if ( class_exists( 'LqtDispatch' ) && 
LqtDispatch::isLqtPage( $title ) ) {
+                               return Status::newFatal( 
'flow-special-enableflow-page-is-liquidthreads', $page );
+                       }
+
+                       $converter = new Converter(
+                               wfGetDB( DB_MASTER ),
+                               Container::get( 'importer' ),
+                               Container::get( 'default_logger' ),
+                               
$this->occupationController->getTalkpageManager(),
+                               new ConversionStrategy(
+                                       Container::get( 'parser' ),
+                                       new NullImportSourceStore(),
+                                       $data['archive-title-format'],
+                                       $data['header']
+                               )
+                       );
+
+                       try {
+                               $converter->convert( $title );
+                       } catch ( \Exception $e ) {
+                               \MWExceptionHandler::logException( $e );
+                               $status->fatal( 'flow-error-external', 
$e->getMessage() );
+                       }
+
+               } else {
+                       $loader = $this->loaderFactory->createWorkflowLoader( 
$title );
+                       $blocks = $loader->getBlocks();
+
+                       $action = 'edit-header';
+                       $params = array(
+                               'header' => array(
+                                       'content' => $data['header'],
+                                       'format' => 'wikitext',
+                               ),
+                       );
+
+                       $blocksToCommit = $loader->handleSubmit(
+                               $this->getContext(),
+                               $action,
+                               $params
+                       );
+
+                       foreach( $blocks as $block ) {
+                               if ( $block->hasErrors() ) {
+                                       $errors = $block->getErrors();
+
+                                       foreach( $errors as $errorKey ) {
+                                               $status->fatal( 
$block->getErrorMessage( $errorKey ) );
+                                       }
                                }
                        }
-               }
 
-               $loader->commit( $blocksToCommit );
+                       $loader->commit( $blocksToCommit );
+               }
 
                $this->page = $data['page'];
                return $status;
diff --git a/maintenance/convertLqt.php b/maintenance/convertLqt.php
index e2e69ab..9b57a2d 100644
--- a/maintenance/convertLqt.php
+++ b/maintenance/convertLqt.php
@@ -60,7 +60,7 @@
 
                $logger->info( "Starting full wiki LQT conversion" );
                $titles = new PagesWithPropertyIterator( $dbw, 
'use-liquid-threads', $startId, $stopId );
-               $converter->convert( $titles );
+               $converter->convertAll( $titles );
        }
 }
 
diff --git a/maintenance/convertLqtPageOnLocalWiki.php 
b/maintenance/convertLqtPageOnLocalWiki.php
index 8f25bee..a1e6070 100644
--- a/maintenance/convertLqtPageOnLocalWiki.php
+++ b/maintenance/convertLqtPageOnLocalWiki.php
@@ -72,7 +72,7 @@
                $logger->info( "Starting LQT conversion of page $srcPageName" );
 
                $srcTitle = \Title::newFromText( $srcPageName );
-               $converter->convert( array(
+               $converter->convertAll( array(
                        $srcTitle,
                ) );
        }
diff --git a/maintenance/convertNamespaceFromWikitext.php 
b/maintenance/convertNamespaceFromWikitext.php
index 65198dd..0cbc425 100644
--- a/maintenance/convertNamespaceFromWikitext.php
+++ b/maintenance/convertNamespaceFromWikitext.php
@@ -67,7 +67,7 @@
                        } );
                }
 
-               $converter->convert( $it );
+               $converter->convertAll( $it );
        }
 }
 

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

Gerrit-MessageType: merged
Gerrit-Change-Id: If3b23383e4289290cde1237b74a4bbbb6bdcb455
Gerrit-PatchSet: 15
Gerrit-Project: mediawiki/extensions/Flow
Gerrit-Branch: master
Gerrit-Owner: Sbisson <sbis...@wikimedia.org>
Gerrit-Reviewer: EBernhardson <ebernhard...@wikimedia.org>
Gerrit-Reviewer: Mattflaschen <mflasc...@wikimedia.org>
Gerrit-Reviewer: Matthias Mullie <mmul...@wikimedia.org>
Gerrit-Reviewer: Sbisson <sbis...@wikimedia.org>
Gerrit-Reviewer: Siebrand <siebr...@kitano.nl>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to