jenkins-bot has submitted this change and it was merged. ( 
https://gerrit.wikimedia.org/r/365197 )

Change subject: Resurrect this extension
......................................................................


Resurrect this extension

This is a complete rewrite. As per task, the special page does nothing for now.

Bug: T170354
Change-Id: I846cc5265d1dcb8ed7214177e3a6121c96df0353
---
A .eslintrc.json
M .gitignore
A ArticleCreationWorkflow.alias.php
D ArticleCreationWorkflow.php
A COPYING
A Gruntfile.js
A composer.json
A extension.json
A i18n/en.json
A i18n/qqq.json
A includes/Hooks.php
A includes/SpecialCreatePage.php
A includes/Workflow.php
A jsduck.json
A package.json
A phpcs.xml
A tests/phan/config.php
A tests/phan/issues/.gitkeep
A tests/phan/stubs/.gitkeep
A tests/phpunit/WorkflowTest.php
20 files changed, 548 insertions(+), 7 deletions(-)

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



diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..488ab05
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,15 @@
+{
+       "extends": "wikimedia",
+       "env": {
+               "browser": true,
+               "jquery": true,
+               "qunit": true
+       },
+       "globals": {
+               "OO": false,
+               "mediaWiki": false
+       },
+       "rules": {
+               "dot-notation": [ "error", { "allowKeywords": true } ]
+       }
+}
diff --git a/.gitignore b/.gitignore
index 98b092a..98da5c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,7 @@
-.svn
+node_modules
+vendor
+*.log
 *~
 *.kate-swp
 .*.swp
+composer.lock
diff --git a/ArticleCreationWorkflow.alias.php 
b/ArticleCreationWorkflow.alias.php
new file mode 100644
index 0000000..1abf9b5
--- /dev/null
+++ b/ArticleCreationWorkflow.alias.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Aliases for special pages
+ *
+ * @file
+ * @ingroup Extensions
+ */
+// @codingStandardsIgnoreFile
+
+$specialPageAliases = array();
+
+/** English (English) */
+$specialPageAliases['en'] = array(
+       'CreatePage' => array( 'CreatePage' ),
+);
diff --git a/ArticleCreationWorkflow.php b/ArticleCreationWorkflow.php
deleted file mode 100644
index c79b991..0000000
--- a/ArticleCreationWorkflow.php
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-/**
- * MediaWiki ArticleCreation Extension
- * See https://www.mediawiki.org/wiki/Extension:ArticleCreationWorkflow
- * @Note This extension is archived. Do not use.
- */
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..7bec2e3
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 Wikimedia contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Gruntfile.js b/Gruntfile.js
new file mode 100644
index 0000000..e0a034e
--- /dev/null
+++ b/Gruntfile.js
@@ -0,0 +1,52 @@
+/* eslint-env node */
+module.exports = function ( grunt ) {
+       var conf = grunt.file.readJSON( 'extension.json' );
+
+       grunt.loadNpmTasks( 'grunt-banana-checker' );
+       grunt.loadNpmTasks( 'grunt-contrib-watch' );
+       grunt.loadNpmTasks( 'grunt-eslint' );
+       grunt.loadNpmTasks( 'grunt-jsonlint' );
+       grunt.loadNpmTasks( 'grunt-stylelint' );
+
+       grunt.initConfig( {
+               eslint: {
+                       src: [
+                               '**/*.js',
+                               '!node_modules/**',
+                               '!vendor/**',
+                               '!tests/externals/**',
+                               '!docs/**'
+                       ]
+               },
+               // Lint – Styling
+               stylelint: {
+                       options: {
+                               syntax: 'less'
+                       },
+                       all: [
+                               'modules/**/*.css',
+                               'modules/**/*.less'
+                       ]
+               },
+               banana: conf.MessagesDirs,
+               watch: {
+                       files: [
+                               '.{stylelintrc,eslintrc.json}',
+                               '<%= eslint.all %>',
+                               '<%= stylelint.all %>'
+                       ],
+                       tasks: 'test'
+               },
+               jsonlint: {
+                       all: [
+                               '**/*.json',
+                               '!node_modules/**',
+                               '!docs/**'
+                       ]
+               }
+       } );
+
+       grunt.registerTask( 'lint', [ 'eslint', 'stylelint', 'jsonlint', 
'banana' ] );
+       grunt.registerTask( 'test', 'lint' );
+       grunt.registerTask( 'default', 'test' );
+};
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..8763303
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,21 @@
+{
+       "name"       : "mediawiki/acw",
+       "type"       : "mediawiki-extension",
+       "description": "MediaWiki extension ArtcleCreationWorkflow",
+       "license"    : "MIT",
+       "minimum-stability": "dev",
+       "require"    : {
+       },
+       "require-dev": {
+               "jakub-onderka/php-parallel-lint": "0.9.2",
+               "jakub-onderka/php-console-highlighter": "0.3.2",
+               "mediawiki/mediawiki-codesniffer": "0.10.1"
+       },
+       "scripts": {
+               "fix": "phpcbf",
+               "test": [
+                       "parallel-lint . --exclude vendor",
+                       "phpcs -p -s"
+               ]
+       }
+}
diff --git a/extension.json b/extension.json
new file mode 100644
index 0000000..a91621e
--- /dev/null
+++ b/extension.json
@@ -0,0 +1,37 @@
+{
+       "manifest_version": 2,
+       "name": "ArticleCreationWorkflow",
+       "type": "other",
+       "author": [ "Max Semenik" ],
+       "url": 
"https://www.mediawiki.org/wiki/Extension:ArticleCreationWorkflow";,
+       "descriptionmsg": "acw-desc",
+       "license-name": "MIT",
+       "requires": {
+               "MediaWiki": ">= 1.30.0-alpha"
+       },
+       "SpecialPages": {
+               "CreatePage": "ArticleCreationWorkflow\\SpecialCreatePage"
+       },
+       "Hooks": {
+               "AlternateEdit": 
"ArticleCreationWorkflow\\Hooks::onAlternateEdit"
+       },
+       "AutoloadClasses": {
+               "ArticleCreationWorkflow\\Hooks": "includes/Hooks.php",
+               "ArticleCreationWorkflow\\SpecialCreatePage": 
"includes/SpecialCreatePage.php",
+               "ArticleCreationWorkflow\\Workflow": "includes/Workflow.php"
+       },
+       "MessagesDirs": {
+               "ArticleCreationWorkflow": [
+                       "i18n"
+               ]
+       },
+       "ExtensionMessagesFiles": {
+               "ArticleCreationWorkflowAliases": 
"ArticleCreationWorkflow.alias.php"
+       },
+       "config": {
+               "ArticleCreationWorkflows": {
+                       "description": "Describes conditions when new page 
creation should be intercepted. See doc/config.txt for details.",
+                       "value": []
+               }
+       }
+}
diff --git a/i18n/en.json b/i18n/en.json
new file mode 100644
index 0000000..19e030c
--- /dev/null
+++ b/i18n/en.json
@@ -0,0 +1,3 @@
+{
+       "acw-desc": "Customizes new page creation experience for new users"
+}
diff --git a/i18n/qqq.json b/i18n/qqq.json
new file mode 100644
index 0000000..dd5c782
--- /dev/null
+++ b/i18n/qqq.json
@@ -0,0 +1,3 @@
+{
+       "acw-desc": "{{desc}}"
+}
diff --git a/includes/Hooks.php b/includes/Hooks.php
new file mode 100644
index 0000000..61230ac
--- /dev/null
+++ b/includes/Hooks.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace ArticleCreationWorkflow;
+
+use EditPage;
+use MediaWiki\MediaWikiServices;
+use SpecialPage;
+
+/**
+ * Hook handlers
+ */
+class Hooks {
+       /**
+        * AlternateEdit hook handler
+        * Redirects users attempting to create pages to Special:CreatePage, 
based on configuration
+        *
+        * @see https://www.mediawiki.org/wiki/Manual:Hooks/AlternateEdit
+        *
+        * @param EditPage $editPage
+        * @return bool
+        */
+       public static function onAlternateEdit( EditPage $editPage ) {
+               $config = MediaWikiServices::getInstance()->getMainConfig();
+               $workflow = new Workflow( $config );
+
+               if ( $workflow->shouldInterceptEditPage( $editPage ) ) {
+                       $title = $editPage->getTitle();
+                       $redirTo = SpecialPage::getTitleFor( 'CreatePage', 
$title->getPrefixedText() );
+                       $output = $editPage->getContext()->getOutput();
+                       $output->redirect( $redirTo->getFullURL() );
+
+                       return false;
+               }
+
+               return true;
+       }
+}
diff --git a/includes/SpecialCreatePage.php b/includes/SpecialCreatePage.php
new file mode 100644
index 0000000..9dbdabb
--- /dev/null
+++ b/includes/SpecialCreatePage.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace ArticleCreationWorkflow;
+
+use Exception;
+use UnlistedSpecialPage;
+
+/**
+ * Special:CreatePage code
+ */
+class SpecialCreatePage extends UnlistedSpecialPage {
+       public function __construct() {
+               parent::__construct( 'CreatePage' );
+       }
+
+       /**
+        * @param string|null $subPage
+        */
+       public function execute( $subPage ) {
+               parent::execute( $subPage );
+
+               throw new Exception( 'Not implemented' );
+       }
+}
diff --git a/includes/Workflow.php b/includes/Workflow.php
new file mode 100644
index 0000000..64a5abc
--- /dev/null
+++ b/includes/Workflow.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace ArticleCreationWorkflow;
+
+use Config;
+use EditPage;
+
+/**
+ * Contains this extension's business logic
+ */
+class Workflow {
+       /** @var Config */
+       private $config;
+
+       /**
+        * @param Config $config Configuration to use
+        */
+       public function __construct( Config $config ) {
+               $this->config = $config;
+       }
+
+       /**
+        * Checks whether an attempt to edit a page should be intercepted and 
redirected to our workflow
+        *
+        * @param EditPage $editPage
+        * @return bool
+        */
+       public function shouldInterceptEditPage( EditPage $editPage ) {
+               $title = $editPage->getTitle();
+               $user = $editPage->getContext()->getUser();
+               $request = $editPage->getContext()->getRequest();
+
+               $conditions = $this->config->get( 'ArticleCreationWorkflows' );
+
+               // We are only interested in creation
+               if ( $title->exists() ) {
+                       return false;
+               }
+
+               foreach ( $conditions as $cond ) {
+                       // Filter on namespace
+                       if ( !in_array( $title->getNamespace(), 
$cond['namespaces'] ) ) {
+                               continue;
+                       }
+
+                       // Filter out users who don't have these rights
+                       if ( isset( $cond['redirectRight'] ) && 
!$user->isAllowed( $cond['redirectRight'] ) ) {
+                               continue;
+                       }
+
+                       // Filter out people who have these rights
+                       if ( isset( $cond['excludeRight'] ) && 
$user->isAllowed( $cond['excludeRight'] ) ) {
+                               continue;
+                       }
+
+                       return true;
+               }
+
+               return false;
+       }
+}
diff --git a/jsduck.json b/jsduck.json
new file mode 100644
index 0000000..82e333b
--- /dev/null
+++ b/jsduck.json
@@ -0,0 +1,10 @@
+{
+       "--title": "Echo - Documentation",
+       "--processes": "0",
+       "--warnings-exit-nonzero": true,
+       "--output": "docs",
+       "--": [
+               "modules",
+               "tests"
+       ]
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..44f5b07
--- /dev/null
+++ b/package.json
@@ -0,0 +1,19 @@
+{
+       "name": "ArticleCreationWorkflow",
+       "private": true,
+       "description": "Build tools for ACW",
+       "scripts": {
+               "test": "grunt test",
+               "doc": "jsduck"
+       },
+       "devDependencies": {
+               "eslint-config-wikimedia": "0.4.0",
+               "grunt": "1.0.1",
+               "grunt-banana-checker": "0.5.0",
+               "grunt-contrib-watch": "1.0.0",
+               "grunt-eslint": "19.0.0",
+               "grunt-jsonlint": "1.0.8",
+               "grunt-stylelint": "0.7.0",
+               "stylelint-config-wikimedia": "0.4.1"
+       }
+}
diff --git a/phpcs.xml b/phpcs.xml
new file mode 100644
index 0000000..60dda4e
--- /dev/null
+++ b/phpcs.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<ruleset name="MediaWiki">
+       <file>.</file>
+       <rule ref="./vendor/mediawiki/mediawiki-codesniffer/MediaWiki">
+               <exclude name="Generic.Files.LineLength.TooLong" />
+               <exclude name 
="MediaWiki.Commenting.FunctionComment.MissingParamComment" />
+       </rule>
+       <arg name="encoding" value="utf8" />
+       <arg name="extensions" value="php,php5,inc" />
+       <arg name="colors" />
+       <exclude-pattern>vendor</exclude-pattern>
+</ruleset>
diff --git a/tests/phan/config.php b/tests/phan/config.php
new file mode 100644
index 0000000..bee8e39
--- /dev/null
+++ b/tests/phan/config.php
@@ -0,0 +1,126 @@
+<?php
+// @codingStandardsIgnore
+
+$directoryList = [];
+$excludeAnalysisDirectoryList = [];
+
+$IP = getenv( 'MW_INSTALL_PATH' );
+if ( $IP === false ) {
+       $IP = realpath( __DIR__ . '/../../../..' );
+}
+
+$ourDirs = [ 'includes', 'tests/phan/stubs' ];
+$otherDirs = [
+       'includes', 'vendor', 'maintenance', 'languages',
+];
+// Use '.' if possible as the path to this extension to keep output filenames 
short
+if ( getcwd() === realpath( __DIR__ . '/../../' ) ) {
+       $ourIP = '.';
+} else {
+       $ourIP = "$IP/extensions/ArticleCreationWorkflow";
+}
+foreach ( $ourDirs as $dir ) {
+       $directoryList[] = "$ourIP/$dir";
+}
+foreach ( $otherDirs as $dir ) {
+       $fullpath = "$IP/$dir";
+       // Some directories, like `vendor`, are optional. The
+       // required deps may have been installed at the top level of mediawiki
+       // or some such
+       if ( is_dir( $fullpath ) ) {
+               $directoryList[] = $fullpath;
+               $excludeAnalysisDirectoryList[] = $fullpath;
+       }
+}
+
+/**
+ * This configuration will be read and overlaid on top of the
+ * default configuration. Command line arguments will be applied
+ * after this file is read.
+ *
+ * @see src/Phan/Config.php
+ * See Config for all configurable options.
+ */
+return [
+       // A list of directories that should be parsed for class and
+       // method information. After excluding the directories
+       // defined in exclude_analysis_directory_list, the remaining
+       // files will be statically analyzed for errors.
+
+       // Thus, both first-party and third-party code being used by
+       // your application should be included in this list.
+       'directory_list' => $directoryList,
+
+       // A directory list that defines files that will be excluded
+       // from static analysis, but whose class and method
+       // information should be included.
+
+       // Generally, you'll want to include the directories for
+       // third-party code (such as "vendor/") in this list.
+
+       // n.b.: If you'd like to parse but not analyze 3rd
+       // party code, directories containing that code
+       // should be added to the `directory_list` as
+       // to `excluce_analysis_directory_list`.
+       "exclude_analysis_directory_list" => $excludeAnalysisDirectoryList,
+
+       // Backwards Compatibility Checking. This is slow
+       // and expensive, but you should consider running
+       // it before upgrading your version of PHP to a
+       // new version that has backward compatibility
+       // breaks.
+       'backward_compatibility_checks' => false,
+
+       // Run a quick version of checks that takes less
+       // time at the cost of not running as thorough
+       // an analysis. You should consider setting this
+       // to true only when you wish you had more issues
+       // to fix in your code base.
+       'quick_mode' => false,
+
+       // If enabled, check all methods that override a
+       // parent method to make sure its signature is
+       // compatible with the parent's. This check
+       // can add quite a bit of time to the analysis.
+       'analyze_signature_compatibility' => true,
+
+       // The minimum severity level to report on. This can be
+       // set to Issue::SEVERITY_LOW, Issue::SEVERITY_NORMAL or
+       // Issue::SEVERITY_CRITICAL. Setting it to only
+       // critical issues is a good place to start on a big
+       // sloppy mature code base.
+       'minimum_severity' => 0,
+
+       // If true, missing properties will be created when
+       // they are first seen. If false, we'll report an
+       // error message if there is an attempt to write
+       // to a class property that wasn't explicitly
+       // defined.
+       'allow_missing_properties' => false,
+
+       // Allow null to be cast as any type and for any
+       // type to be cast to null. Setting this to false
+       // will cut down on false positives.
+       'null_casts_as_any_type' => false,
+
+       // If enabled, scalars (int, float, bool, string, null)
+       // are treated as if they can cast to each other.
+       'scalar_implicit_cast' => false,
+
+       // If true, seemingly undeclared variables in the global
+       // scope will be ignored. This is useful for projects
+       // with complicated cross-file globals that you have no
+       // hope of fixing.
+       'ignore_undeclared_variables_in_global_scope' => false,
+
+       // Add any issue types (such as 'PhanUndeclaredMethod')
+       // to this black-list to inhibit them from being reported.
+       'suppress_issue_types' => [
+       ],
+
+       // If empty, no filter against issues types will be applied.
+       // If this white-list is non-empty, only issues within the list
+       // will be emitted by Phan.
+       'whitelist_issue_types' => [
+       ],
+];
diff --git a/tests/phan/issues/.gitkeep b/tests/phan/issues/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/phan/issues/.gitkeep
diff --git a/tests/phan/stubs/.gitkeep b/tests/phan/stubs/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/phan/stubs/.gitkeep
diff --git a/tests/phpunit/WorkflowTest.php b/tests/phpunit/WorkflowTest.php
new file mode 100644
index 0000000..6d116aa
--- /dev/null
+++ b/tests/phpunit/WorkflowTest.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace ArticleCreationWorkflow\Tests;
+
+use Article;
+use ArticleCreationWorkflow\Workflow;
+use DerivativeContext;
+use EditPage;
+use FauxRequest;
+use HashConfig;
+use MediaWikiTestCase;
+use RequestContext;
+use Title;
+use User;
+
+/**
+ * @group ArticleCreationWorkflow
+ */
+class WorkflowTest extends MediaWikiTestCase {
+       /**
+        * @dataProvider provideShouldInterceptEditPage
+        *
+        * @param User $user
+        * @param Title $title
+        * @param array $settings
+        * @param string $query
+        * @param bool $expected
+        */
+       public function testShouldInterceptEditPage( User $user, Title $title,
+               $settings, $expected
+       ) {
+               $context = new DerivativeContext( RequestContext::getMain() );
+               $context->setTitle( $title );
+               $context->setUser( $user );
+
+               $article = new Article( $title );
+               $article->setContext( $context );
+               $editPage = new EditPage( $article );
+               $config = new HashConfig( [ 'ArticleCreationWorkflows' => 
$settings ] );
+
+               $workflow = new Workflow( $config );
+
+               self::assertEquals( $expected, 
$workflow->shouldInterceptEditPage( $editPage ) );
+       }
+
+       public function provideShouldInterceptEditPage() {
+               $anon = User::newFromId( 0 );
+               $newbie = $this->getMock( 'User' );
+               $newbie->method( 'isAllowed' )
+                       ->with( 'autoconfirmed' )
+                       ->willReturn( false );
+               $confirmed = $this->getMock( 'User' );
+               $confirmed->method( 'isAllowed' )
+                       ->with( 'autoconfirmed' )
+                       ->willReturn( true );
+
+               $mainspacePage = Title::newFromText( 'Some nonexistent page' );
+               $miscPage = Title::newFromText( 'Project:Nonexistent too' );
+               $existingPage = $this->getMock( 'Title' );
+               $existingPage->method( 'exists' )
+                       ->willReturn( true );
+               $existingPage->method( 'getContentModel' )
+                       ->willReturn( CONTENT_MODEL_WIKITEXT );
+
+               $config = [
+                       [
+                               'namespaces' => [ NS_MAIN ],
+                               'excludeRight' => 'autoconfirmed',
+                       ],
+               ];
+
+               return [
+                       // No config, do nothing
+                       [ $anon, $mainspacePage, [], false ],
+                       // Wrong NS, do nothing
+                       [ $anon, $miscPage, $config, false ],
+                       // Page exists, do nothing
+                       [ $anon, $existingPage, $config, false ],
+                       // Confirmed user, do nothing
+                       [ $confirmed, $mainspacePage, $config, false ],
+
+                       // Anon attempting to create a page, intercept
+                       [ $anon, $mainspacePage, $config, true ],
+                       // Newbie attempting to create a page, intercept
+                       [ $newbie, $mainspacePage, $config, true ],
+               ];
+       }
+}

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I846cc5265d1dcb8ed7214177e3a6121c96df0353
Gerrit-PatchSet: 9
Gerrit-Project: mediawiki/extensions/ArticleCreationWorkflow
Gerrit-Branch: master
Gerrit-Owner: MaxSem <[email protected]>
Gerrit-Reviewer: Kaldari <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: MaxSem <[email protected]>
Gerrit-Reviewer: MusikAnimal <[email protected]>
Gerrit-Reviewer: Niharika29 <[email protected]>
Gerrit-Reviewer: Samwilson <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to