WikidataBuilder has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/329040 )

Change subject: New Wikidata Build - 2016-12-24T10:00:01+0000
......................................................................

New Wikidata Build - 2016-12-24T10:00:01+0000

Change-Id: Id09acca49bb449004bbabfd71ee221b57492bce0
---
M composer.lock
M extensions/ArticlePlaceholder/i18n/pl.json
M extensions/Wikibase/client/i18n/ce.json
M extensions/Wikibase/client/i18n/kk-cyrl.json
M extensions/Wikibase/repo/i18n/ar.json
M extensions/Wikibase/repo/i18n/ce.json
M extensions/Wikibase/repo/i18n/de.json
M extensions/Wikibase/repo/i18n/en.json
M extensions/Wikibase/repo/i18n/nb.json
M extensions/Wikibase/repo/i18n/pl.json
M extensions/Wikibase/repo/i18n/qqq.json
A extensions/Wikibase/repo/includes/Specials/HTMLForm/HTMLTrimmedTextField.php
M extensions/Wikibase/repo/includes/Specials/SpecialModifyEntity.php
M extensions/Wikibase/repo/includes/Specials/SpecialNewEntity.php
M extensions/Wikibase/repo/includes/Specials/SpecialNewItem.php
M extensions/Wikibase/repo/includes/Specials/SpecialNewProperty.php
M 
extensions/Wikibase/repo/tests/phpunit/includes/Specials/HtmlAssertionHelpers.php
M 
extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialMergeItemsTest.php
M 
extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialNewItemTest.php
M 
extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialNewPropertyTest.php
M 
extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialRedirectEntityTest.php
M vendor/composer/autoload_classmap.php
M vendor/composer/installed.json
23 files changed, 736 insertions(+), 579 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Wikidata 
refs/changes/40/329040/1

diff --git a/composer.lock b/composer.lock
index e59cc99..706c1a4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -797,12 +797,12 @@
             "source": {
                 "type": "git",
                 "url": 
"https://github.com/wikimedia/mediawiki-extensions-ArticlePlaceholder.git";,
-                "reference": "98a2db861a58102cdbc52707ff90e9f68899d02b"
+                "reference": "75a2540c6f19488a630a4f871c01912dd26f1c21"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-ArticlePlaceholder/zipball/98a2db861a58102cdbc52707ff90e9f68899d02b";,
-                "reference": "98a2db861a58102cdbc52707ff90e9f68899d02b",
+                "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-ArticlePlaceholder/zipball/75a2540c6f19488a630a4f871c01912dd26f1c21";,
+                "reference": "75a2540c6f19488a630a4f871c01912dd26f1c21",
                 "shasum": ""
             },
             "require-dev": {
@@ -827,7 +827,7 @@
             ],
             "description": "Provides a special page with Wikibase information 
about a certain topic, with invitation to create an article for the topic",
             "homepage": 
"https://www.mediawiki.org/wiki/Extension:ArticlePlaceholder";,
-            "time": "2016-12-21 15:36:21"
+            "time": "2016-12-23 21:28:55"
         },
         {
             "name": "propertysuggester/property-suggester",
@@ -1585,12 +1585,12 @@
             "source": {
                 "type": "git",
                 "url": 
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git";,
-                "reference": "34c8556f728ae901bd33b9ad31fd669233290e51"
+                "reference": "1a771255cc07b3047e11c591091d642ea83f1abd"
             },
             "dist": {
                 "type": "zip",
-                "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/34c8556f728ae901bd33b9ad31fd669233290e51";,
-                "reference": "34c8556f728ae901bd33b9ad31fd669233290e51",
+                "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/1a771255cc07b3047e11c591091d642ea83f1abd";,
+                "reference": "1a771255cc07b3047e11c591091d642ea83f1abd",
                 "shasum": ""
             },
             "require": {
@@ -1663,7 +1663,7 @@
                 "wikibaserepo",
                 "wikidata"
             ],
-            "time": "2016-12-23 09:08:26"
+            "time": "2016-12-23 21:34:43"
         },
         {
             "name": "wikibase/wikimedia-badges",
diff --git a/extensions/ArticlePlaceholder/i18n/pl.json 
b/extensions/ArticlePlaceholder/i18n/pl.json
index 2ad2803..752f6d3 100644
--- a/extensions/ArticlePlaceholder/i18n/pl.json
+++ b/extensions/ArticlePlaceholder/i18n/pl.json
@@ -7,9 +7,11 @@
        "createtopicpage": "Utwórz stronę",
        "articleplaceholder-abouttopic-create-article-label": "Tytuł artykułu",
        "articleplaceholder-abouttopic-create-article-button": "Utwórz artykuł",
+       "articleplaceholder-abouttopic-create-emtpy-article-button": "Utwórz 
nowy artykuł",
        "articleplaceholder-abouttopic-translate-article-label": "Język 
źródłowy:",
        "articleplaceholder-abouttopic-translate-article-button": "Przetłumacz 
artykuł",
        "articleplaceholder-abouttopic-create-article-submit-button": "Wyślij",
+       "articleplaceholder-abouttopic-article-exists-error": "Artykuł o tej 
nazwie już istnieje",
        "articleplaceholder-abouttopic-lua-identifier": "Źródła zewnętrzne",
        "articleplaceholder-createpage-title": "Tworzenie $1",
        "articleplaceholder-createpage-alreadyexists": "Strona o tytule $1 już 
istnieje. Proszę wybrać inny tytuł.",
diff --git a/extensions/Wikibase/client/i18n/ce.json 
b/extensions/Wikibase/client/i18n/ce.json
index 24c8ba9..bf92662 100644
--- a/extensions/Wikibase/client/i18n/ce.json
+++ b/extensions/Wikibase/client/i18n/ce.json
@@ -38,7 +38,6 @@
        "wikibase-linkitem-not-loggedin-title": "Ахьа авторизаци ян еза",
        "wikibase-linkitem-not-loggedin": "И функци лела я йиш хилийта ахьа 
хьай цӀерца болх ба беза хӀокху вики чох а, [$1 Викихаамаш чохь а].",
        "wikibase-linkitem-success-link": "АгӀонаш кхиамца [$1 Викихаамаш чохь] 
вовшахтесна.",
-       "wikibase-limitreport-entities-accessed": "Чуяьхна Викибазан хӀумнийн 
дукхалла",
        "wikibase-property-notfound": "Билгало «$1» ца карайо",
        "wikibase-rc-hide-wikidata": "$1 Викихаамаш",
        "wikibase-rc-hide-wikidata-hide": "Къайлабаха",
@@ -62,6 +61,8 @@
        "wikibase-pageswithbadges-submit": "Гайта агӀонаш",
        "wikibase-pageinfo-entity-id": "Викихаамаш чур элиментан ID",
        "wikibase-pageinfo-entity-id-none": "ХӀумма цаоьшу",
+       "wikibase-pageinfo-entity-usage-L": "Билгало: $1",
+       "wikibase-pageinfo-entity-usage-T": "Корта",
        "wikibase-property-render-error": "билгало «$1»: $2 гучуйоккхуш гӀалат 
ду",
        "wikibase-otherprojects": "Кхин проекташ",
        "wikibase-otherprojects-beta-message": "Кхечу проектийн агӀонгара 
панель",
diff --git a/extensions/Wikibase/client/i18n/kk-cyrl.json 
b/extensions/Wikibase/client/i18n/kk-cyrl.json
index 65853ed..24fa23d 100644
--- a/extensions/Wikibase/client/i18n/kk-cyrl.json
+++ b/extensions/Wikibase/client/i18n/kk-cyrl.json
@@ -1,7 +1,8 @@
 {
        "@metadata": {
                "authors": [
-                       "Arystanbek"
+                       "Arystanbek",
+                       "Нұрлан Рахымжанов"
                ]
        },
        "tooltip-t-wikibase": "Сілтеме дерек қойма данасымен байланысқан",
@@ -33,7 +34,7 @@
        "wikibase-linkitem-confirmitem-button": "Құптау",
        "wikibase-linkitem-not-loggedin-title": "Сіз кіруіңіз керек",
        "wikibase-linkitem-not-loggedin": "Сіз бұл уикиге кіруіңіз керек және  
[$1 орталық дерек қоймасында] бұл мүмкіндікті қолдану",
-       "wikibase-linkitem-success-link": "Беттер сәтті сілтенді. Сіз [$1 
орталық дерек қоймасыңыздан] жаңадан басталған элементердегі қамтылған 
сілтемелерді таба аласыз.",
+       "wikibase-linkitem-success-link": "Беттер сәтті сілтенді. Сіз [$1 
орталық дерек қоймасынан] жаңадан басталған элементегі қамтылған сілтемелерді 
таба аласыз.",
        "wikibase-property-notfound": "$1 сипаты табылмады.",
        "wikibase-rc-hide-wikidata": "{{WBREPONAME}}ті $1",
        "wikibase-rc-hide-wikidata-hide": "жасыру",
diff --git a/extensions/Wikibase/repo/i18n/ar.json 
b/extensions/Wikibase/repo/i18n/ar.json
index 22f345d..e876a90 100644
--- a/extensions/Wikibase/repo/i18n/ar.json
+++ b/extensions/Wikibase/repo/i18n/ar.json
@@ -235,6 +235,7 @@
        "wikibase-mergeitems-toid": "المعرِّف الذي يجري الدمج إليه",
        "wikibase-mergeitems-submit": "دمج العناصر",
        "wikibase-mergeitems-success": "تم دمج $1 إلى $3وتم تحويل.",
+       "wikibase-itemmerge-redirect": "هذه العناصر ربما تم دمجها فعلا.",
        "wikibase-itemmerge-missing-parameter": "دخل ناقص.",
        "wikibase-itemmerge-not-item": "الكائن المحدد ليس عنصراً.",
        "wikibase-itemmerge-failed-save": "لم يمكن حفظ العنصر.",
diff --git a/extensions/Wikibase/repo/i18n/ce.json 
b/extensions/Wikibase/repo/i18n/ce.json
index ad9d3a2..d52f546 100644
--- a/extensions/Wikibase/repo/i18n/ce.json
+++ b/extensions/Wikibase/repo/i18n/ce.json
@@ -24,7 +24,7 @@
        
"wikibase-entitytermsview-entitytermsforlanguagelistview-configure-link-label": 
"Нисъян",
        "wikibase-entitytermsforlanguagelistview-aliases": "Кхин евзаш ю",
        "wikibase-entitytermsforlanguagelistview-description": "Цуьнах лаьцна",
-       "wikibase-entitytermsforlanguagelistview-label": "Билгалдар",
+       "wikibase-entitytermsforlanguagelistview-label": "Билгало",
        "wikibase-entitytermsforlanguagelistview-language": "Мотт",
        "wikibase-entitytermsforlanguagelistview-more": "Массо меттанаш",
        "wikibase-entitytermsforlanguagelistview-less": "КӀезиг меттанаш",
@@ -96,7 +96,7 @@
        "wikibase-gotolinkedpage-submit": "Дехьа гӀо",
        "special-itemdisambiguation": "Массех маьӀна долу элемент",
        "wikibase-itemdisambiguation-lookup-language": "Метта код:",
-       "wikibase-itemdisambiguation-lookup-label": "ЦӀе:",
+       "wikibase-itemdisambiguation-lookup-label": "Билгало:",
        "wikibase-itemdisambiguation-submit": "Лахар",
        "wikibase-newproperty-datatype": "Хаамийн тайп:",
        "wikibase-newproperty-invalid-datatype": "Билгалйина цамагина хаамийн 
тайп.",
@@ -108,13 +108,13 @@
        "wikibase-newitem-page": "ЦхьалгӀа агӀо тесна сайт",
        "wikibase-newitem-no-external-page": "Кара ца-йо оцу сайтан чохь иштта 
цӀе йолу агӀо.",
        "wikibase-newentity-language": "Мотт:",
-       "wikibase-newentity-label": "ЦӀе (билгало):",
+       "wikibase-newentity-label": "Билгало:",
        "wikibase-newentity-description": "Цуьнах лаьцна:",
        "wikibase-newentity-aliases": "Псевдонимаш, дӀасакъаьстина верт. 
сизал:",
        "wikibase-newentity-submit": "Кхолла",
        "special-setlabel": "Язъе цӀе",
        "wikibase-setlabel-introfull": "Ахьа язийна хӀокхун [[$1]] цӀе «$2».",
-       "wikibase-setlabel-label": "ЦӀе (билгало):",
+       "wikibase-setlabel-label": "Билгало:",
        "wikibase-setlabel-submit": "Язъе цӀе",
        "wikibase-setdescription-label": "Цуьнах лаьцна:",
        "wikibase-setdescription-submit": "ДӀаязде цуьнах лаьцна",
diff --git a/extensions/Wikibase/repo/i18n/de.json 
b/extensions/Wikibase/repo/i18n/de.json
index 68cf4a3..179ff44 100644
--- a/extensions/Wikibase/repo/i18n/de.json
+++ b/extensions/Wikibase/repo/i18n/de.json
@@ -179,6 +179,7 @@
        "wikibase-newproperty-fieldset": "Ein neues Attribut erstellen",
        "wikibase-newproperty-datatype": "Datentyp:",
        "wikibase-newproperty-invalid-datatype": "Es wurde ein ungültiger 
Datentyp angegeben.",
+       "wikibase-newproperty-insufficient-data": "Du musst mindestens entweder 
eine Bezeichnung, Beschreibung oder Aliasse angeben.",
        "wikibase-description-helppage": "Help:Beschreibung",
        "wikibase-label-helppage": "Help:Bezeichnung",
        "special-newitem": "Ein neues Datenobjekt erstellen",
@@ -189,6 +190,7 @@
        "wikibase-newitem-no-external-page": "Eine Seite „$2“ konnte nicht auf 
„$1“ gefunden werden.",
        "wikibase-newitem-not-recognized-siteid": "Die angegebene 
Websitekennung ist nicht bekannt.",
        "wikibase-newitem-not-recognized-language": "Der angegebene Sprachcode 
wurde nicht erkannt.",
+       "wikibase-newitem-insufficient-data": "Du musst mindestens entweder 
eine Bezeichnung, Beschreibung oder Aliasse angeben.",
        "wikibase-newentity-language": "Sprache:",
        "wikibase-newentity-label": "Bezeichnung:",
        "wikibase-newentity-description": "Beschreibung:",
diff --git a/extensions/Wikibase/repo/i18n/en.json 
b/extensions/Wikibase/repo/i18n/en.json
index db80463..2887a99 100644
--- a/extensions/Wikibase/repo/i18n/en.json
+++ b/extensions/Wikibase/repo/i18n/en.json
@@ -171,6 +171,7 @@
        "wikibase-newproperty-fieldset": "Create a new property",
        "wikibase-newproperty-datatype": "Data type:",
        "wikibase-newproperty-invalid-datatype": "Invalid data type specified.",
+       "wikibase-newproperty-insufficient-data": "You need to fill at least 
either label, description or aliases.",
        "wikibase-description-helppage": "Help:Description",
        "wikibase-label-helppage": "Help:Label",
        "special-newitem": "Create a new item",
@@ -181,6 +182,7 @@
        "wikibase-newitem-no-external-page": "A page \"$2\" could not be found 
on \"$1\".",
        "wikibase-newitem-not-recognized-siteid": "The provided site identifier 
was not recognized.",
        "wikibase-newitem-not-recognized-language": "The supplied language code 
was not recognized.",
+       "wikibase-newitem-insufficient-data": "You need to fill at least either 
label, description or aliases.",
        "wikibase-newentity-language": "Language:",
        "wikibase-newentity-label": "Label:",
        "wikibase-newentity-description": "Description:",
diff --git a/extensions/Wikibase/repo/i18n/nb.json 
b/extensions/Wikibase/repo/i18n/nb.json
index 03baa99..33bf126 100644
--- a/extensions/Wikibase/repo/i18n/nb.json
+++ b/extensions/Wikibase/repo/i18n/nb.json
@@ -169,7 +169,7 @@
        "wikibase-newitem-no-external-page": "Siden «$2» ble ikke funnet på 
«$1».",
        "wikibase-newitem-not-recognized-siteid": "Den oppgitte 
nettstedidentifikatoren ble ikke gjenkjent.",
        "wikibase-newitem-not-recognized-language": "Den angitte språkkoden ble 
ikke gjenkjent.",
-       "wikibase-newentity-language": "Språk:",
+       "wikibase-newentity-language": "Leksemets språk",
        "wikibase-newentity-label": "Etikett:",
        "wikibase-newentity-description": "Beskrivelse:",
        "wikibase-newentity-aliases": "Alias adskilt av vertikalstrek:",
diff --git a/extensions/Wikibase/repo/i18n/pl.json 
b/extensions/Wikibase/repo/i18n/pl.json
index ddb23f6..8eb3cf9 100644
--- a/extensions/Wikibase/repo/i18n/pl.json
+++ b/extensions/Wikibase/repo/i18n/pl.json
@@ -350,6 +350,8 @@
        "apihelp-query+wbsearch-param-limit": "Maksymalna liczba wyników",
        "apihelp-query+wbsubscribers-param-limit": "Maksymalna liczba wyników",
        "apihelp-wbsetaliases-param-bot": "Oznacz tę zmianę jako wykonaną przez 
bota. Ten znacznik adresu URL będzie brany pod uwagę tylko, jeśli użytkownik 
należy do grupy „bot”.",
+       "apihelp-wbsetaliases-param-add": "Lista aliasów do dodania (można 
używać z <var>remove</var>)",
+       "apihelp-wbsetaliases-param-remove": "Lista aliasów do usunięcia (można 
używać z <var>add</var>)",
        "apihelp-wbsetaliases-param-language": "Język, w którym ustawić aliasy",
        "apihelp-wbsetclaim-param-bot": "Oznacz tę zmianę jako wykonaną przez 
bota. Ten znacznik adresu URL będzie brany pod uwagę tylko, jeśli użytkownik 
należy do grupy „bot”.",
        "apihelp-wbsetclaimvalue-description": "Ustawia wartość stwierdzenia 
Wikibase.",
diff --git a/extensions/Wikibase/repo/i18n/qqq.json 
b/extensions/Wikibase/repo/i18n/qqq.json
index 607458d..fae4cb0 100644
--- a/extensions/Wikibase/repo/i18n/qqq.json
+++ b/extensions/Wikibase/repo/i18n/qqq.json
@@ -202,6 +202,7 @@
        "wikibase-newproperty-fieldset": "Title for the fieldset on the 
CreateProperty special page.",
        "wikibase-newproperty-datatype": "Label for the data-type-dropdown 
holding the data type of the new property.\n{{Identical|Data type}}",
        "wikibase-newproperty-invalid-datatype": "Error message shown when the 
page gets an invalid datatype",
+       "wikibase-newproperty-insufficient-data": "Error message shown when a 
user tries to create a property and didn't fill in enough data",
        "wikibase-description-helppage": "{{doc-important|Do not change the 
<code>Help:</code> part.}}\nThe name of the local help page about using and 
editing labels.",
        "wikibase-label-helppage": "{{doc-important|Do not change the 
<code>Help:</code> part.}}\nThe name of the local help page about using and 
editing descriptions.",
        "special-newitem": "{{doc-special|NewItem}}\nThe special page is for 
creating new items.\n{{Identical|Create new item}}",
@@ -212,6 +213,7 @@
        "wikibase-newitem-no-external-page": "Error message shown when a user 
tries to add a page that does not exist on the site chosen.\n\nParameters:\n* 
$1 - global site ID, known to be valid\n* $2 - requested page name that could 
not be found on the site\n{{Related|Wikibase-no-external-page}}",
        "wikibase-newitem-not-recognized-siteid": "Error message shown when a 
user tries to add a link to a site with an unknown identifier.\n\nSee also:\n* 
{{msg-mw|Wikibase-api-not-recognized-siteid}}",
        "wikibase-newitem-not-recognized-language": "Error message shown when a 
user tries to create an item with an unknown language code.\n\nSee also:\n* 
{{msg-mw|Wikibase-api-not-recognized-language}}",
+       "wikibase-newitem-insufficient-data": "Error message shown when a user 
tries to create an item and didn't fill in enough data",
        "wikibase-newentity-language": "Name for 
\"language\"\n{{Identical|Language}}",
        "wikibase-newentity-label": "Label for the \"label\" textfield holding 
the label of the new item.\n{{Identical|Label}}",
        "wikibase-newentity-description": "Label for the \"description\" 
textfield holding the description of the new item.\n{{Identical|Description}}",
diff --git 
a/extensions/Wikibase/repo/includes/Specials/HTMLForm/HTMLTrimmedTextField.php 
b/extensions/Wikibase/repo/includes/Specials/HTMLForm/HTMLTrimmedTextField.php
new file mode 100644
index 0000000..46dd6c1
--- /dev/null
+++ 
b/extensions/Wikibase/repo/includes/Specials/HTMLForm/HTMLTrimmedTextField.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Wikibase\Repo\Specials\HTMLForm;
+
+use HTMLTextField;
+use Wikibase\StringNormalizer;
+
+class HTMLTrimmedTextField extends HTMLTextField {
+
+       /**
+        * @var StringNormalizer
+        */
+       private $stringNormalizer;
+
+       public function __construct( array $params ) {
+               parent::__construct( $params );
+
+               $this->stringNormalizer = new StringNormalizer();
+       }
+
+       public function filter( $value, $alldata ) {
+               $filteredValue = $this->stringNormalizer->trimToNFC( $value );
+
+               return parent::filter( $filteredValue, $alldata );
+       }
+
+}
diff --git a/extensions/Wikibase/repo/includes/Specials/SpecialModifyEntity.php 
b/extensions/Wikibase/repo/includes/Specials/SpecialModifyEntity.php
index 8326c42..1f894be 100644
--- a/extensions/Wikibase/repo/includes/Specials/SpecialModifyEntity.php
+++ b/extensions/Wikibase/repo/includes/Specials/SpecialModifyEntity.php
@@ -246,13 +246,14 @@
                $this->getOutput()->addModuleStyles( array( 'wikibase.special' 
) );
 
                if ( $this->getUser()->isAnon() ) {
-                       $this->showErrorHTML(
+                       $this->getOutput()->addHTML( Html::rawElement(
+                               'p',
+                               [ 'class' => 'warning' ],
                                $this->msg(
                                        'wikibase-anonymouseditwarning',
                                        $this->msg( 'wikibase-entity-item' 
)->text()
-                               )->parse(),
-                               'warning'
-                       );
+                               )->parse()
+                       ) );
                }
 
                // Form header
diff --git a/extensions/Wikibase/repo/includes/Specials/SpecialNewEntity.php 
b/extensions/Wikibase/repo/includes/Specials/SpecialNewEntity.php
index 0a01637..d0b2dcd 100644
--- a/extensions/Wikibase/repo/includes/Specials/SpecialNewEntity.php
+++ b/extensions/Wikibase/repo/includes/Specials/SpecialNewEntity.php
@@ -4,11 +4,10 @@
 
 use Html;
 use HTMLForm;
-use InvalidArgumentException;
+use OutputPage;
 use Status;
 use Wikibase\CopyrightMessageBuilder;
 use Wikibase\DataModel\Entity\EntityDocument;
-use Wikibase\DataModel\Term\FingerprintProvider;
 use Wikibase\Lib\LanguageNameLookup;
 use Wikibase\Repo\WikibaseRepo;
 use Wikibase\Summary;
@@ -25,6 +24,7 @@
  * @author John Erling Blad < jeb...@gmail.com >
  * @author Bene* < benestar.wikime...@gmail.com >
  * @author Adrian Heine <adrian.he...@wikimedia.de>
+ * @author Aleksey Bekh-Ivanov < aleksey.bekh-iva...@wikimedia.de >
  */
 abstract class SpecialNewEntity extends SpecialWikibaseRepoPage {
 
@@ -36,39 +36,14 @@
        protected $parts = null;
 
        /**
-        * @var string|null
-        */
-       private $label;
-
-       /**
-        * @var string|null
-        */
-       private $description;
-
-       /**
         * @var string[]
         */
-       private $aliases = [];
-
-       /**
-        * @var string
-        */
-       private $contentLanguageCode;
-
-       /**
-        * @var string[]
-        */
-       private $languageCodes;
+       protected $languageCodes;
 
        /**
         * @var SpecialPageCopyrightView
         */
        private $copyrightView;
-
-       /**
-        * @var LanguageDirectionalityLookup
-        */
-       private $languageDirectionalityLookup;
 
        /**
         * @var LanguageNameLookup
@@ -92,7 +67,6 @@
                        $settings->getSetting( 'dataRightsText' )
                );
                $this->languageCodes = 
$wikibaseRepo->getTermsLanguages()->getLanguages();
-               $this->languageDirectionalityLookup = 
$wikibaseRepo->getLanguageDirectionalityLookup();
                $this->languageNameLookup = 
$wikibaseRepo->getLanguageNameLookup();
        }
 
@@ -115,142 +89,25 @@
                $this->checkReadOnly();
 
                $this->parts = ( $subPage === '' ? [] : explode( '/', $subPage 
) );
-               $this->prepareArguments();
+
+               $form = $this->createForm();
+
+               $form->prepareForm();
+
+               /** @var Status|false $submitStatus `false` if form was not 
submitted */
+               $submitStatus = $form->tryAuthorizedSubmit();
+
+               if ( $submitStatus && $submitStatus->isGood() ) {
+                       $this->redirectToEntityPage( $submitStatus->getValue() 
);
+
+                       return;
+               }
 
                $out = $this->getOutput();
 
-               $uiLanguageCode = $this->getLanguage()->getCode();
+               $this->displayBeforeForm( $out );
 
-               if ( $this->getRequest()->wasPosted()
-                       && $this->getUser()->matchEditToken( 
$this->getRequest()->getVal( 'wpEditToken' ) )
-               ) {
-                       if ( $this->hasSufficientArguments() ) {
-                               $entity = $this->createEntity();
-
-                               $status = $this->modifyEntity( $entity );
-
-                               if ( $status->isGood() ) {
-                                       $summary = new Summary( 'wbeditentity', 
'create' );
-                                       $summary->setLanguage( $uiLanguageCode 
);
-                                       $summary->addAutoSummaryArgs( 
$this->label, $this->description );
-
-                                       $status = $this->saveEntity(
-                                               $entity,
-                                               $summary,
-                                               $this->getRequest()->getVal( 
'wpEditToken' ),
-                                               EDIT_NEW
-                                       );
-
-                                       $out = $this->getOutput();
-
-                                       if ( !$status->isOK() ) {
-                                               $out->addHTML( '<div 
class="error">' );
-                                               $out->addWikiText( 
$status->getWikiText() );
-                                               $out->addHTML( '</div>' );
-                                       } elseif ( $entity !== null ) {
-                                               $title = $this->getEntityTitle( 
$entity->getId() );
-                                               $entityUrl = 
$title->getFullURL();
-                                               $this->getOutput()->redirect( 
$entityUrl );
-                                       }
-                               } else {
-                                       $out->addHTML( '<div class="error">' );
-                                       $out->addHTML( $status->getHTML() );
-                                       $out->addHTML( '</div>' );
-                               }
-                       }
-               }
-
-               $this->getOutput()->addModuleStyles( [ 'wikibase.special' ] );
-
-               foreach ( $this->getWarnings() as $warning ) {
-                       $out->addHTML( Html::element( 'div', [ 'class' => 
'warning' ], $warning ) );
-               }
-
-               $this->createForm( $this->getLegend(), 
$this->additionalFormElements() );
-       }
-
-       /**
-        * Tries to extract argument values from web request or of the page's 
sub-page parts
-        *
-        * Trimming argument values from web request.
-        *
-        * @since 0.1
-        */
-       protected function prepareArguments() {
-               $label = $this->getRequest()->getVal(
-                       'label',
-                       isset( $this->parts[0] ) ? $this->parts[0] : ''
-               );
-               $this->label = $this->stringNormalizer->trimToNFC( $label );
-
-               $description = $this->getRequest()->getVal(
-                       'description',
-                       isset( $this->parts[1] ) ? $this->parts[1] : ''
-               );
-               $this->description = $this->stringNormalizer->trimToNFC( 
$description );
-
-               $aliases = $this->getRequest()->getVal( 'aliases' );
-               $explodedAliases = $aliases === null ? [] : explode( '|', 
$aliases );
-               foreach ( $explodedAliases as $alias ) {
-                       $alias = $this->stringNormalizer->trimToNFC( $alias );
-
-                       if ( $alias !== '' ) {
-                               $this->aliases[] = $alias;
-                       }
-               }
-
-               $this->contentLanguageCode = $this->getRequest()->getVal( 
'lang', $this->getLanguage()->getCode() );
-       }
-
-       /**
-        * Checks whether required arguments are set sufficiently
-        *
-        * @since 0.1
-        *
-        * @return bool
-        */
-       protected function hasSufficientArguments() {
-               return $this->label !== ''
-                       || $this->description !== ''
-                       || $this->aliases !== [];
-       }
-
-       /**
-        * @since 0.1
-        *
-        * @return EntityDocument Created entity of correct subtype
-        */
-       abstract protected function createEntity();
-
-       /**
-        * Attempt to modify entity
-        *
-        * @since 0.1
-        *
-        * @param EntityDocument $entity
-        *
-        * @throws InvalidArgumentException
-        * @return Status
-        */
-       protected function modifyEntity( EntityDocument $entity ) {
-               if ( !( $entity instanceof FingerprintProvider ) ) {
-                       throw new InvalidArgumentException( '$entity must be a 
FingerprintProvider' );
-               }
-
-               $fingerprint = $entity->getFingerprint();
-               $status = Status::newGood();
-
-               $languageCode = $this->contentLanguageCode;
-               if ( !in_array( $languageCode, $this->languageCodes ) ) {
-                       $status->error( 
'wikibase-newitem-not-recognized-language' );
-                       return $status;
-               }
-
-               $fingerprint->setLabel( $languageCode, $this->label );
-               $fingerprint->setDescription( $languageCode, $this->description 
);
-               $fingerprint->setAliasGroup( $languageCode, $this->aliases );
-
-               return $status;
+               $form->displayForm( $submitStatus ?: Status::newGood() );
        }
 
        /**
@@ -258,7 +115,7 @@
         *
         * @return string[]
         */
-       private function getLanguageOptions() {
+       protected function getLanguageOptions() {
                $languageOptions = [];
                foreach ( $this->languageCodes as $code ) {
                        $languageName = $this->languageNameLookup->getName( 
$code );
@@ -270,88 +127,7 @@
        /**
         * @return array[]
         */
-       protected function additionalFormElements() {
-               $this->getOutput()->addModules( 
'wikibase.special.languageLabelDescriptionAliases' );
-
-               $langCode = $this->contentLanguageCode;
-               $langDir = 
$this->languageDirectionalityLookup->getDirectionality( 
$this->contentLanguageCode );
-               return [
-                       'lang' => [
-                               'name' => 'lang',
-                               'options' => $this->getLanguageOptions(),
-                               'default' => $langCode,
-                               'type' => 'combobox',
-                               'id' => 'wb-newentity-language',
-                               'label-message' => 'wikibase-newentity-language'
-                       ],
-                       'label' => [
-                               'name' => 'label',
-                               'default' => $this->label ?: '',
-                               'type' => 'text',
-                               'id' => 'wb-newentity-label',
-                               'lang' => $langCode,
-                               'dir' => $langDir,
-                               'placeholder' => $this->msg(
-                                       'wikibase-label-edit-placeholder'
-                               )->text(),
-                               'label-message' => 'wikibase-newentity-label'
-                       ],
-                       'description' => [
-                               'name' => 'description',
-                               'default' => $this->description ?: '',
-                               'type' => 'text',
-                               'id' => 'wb-newentity-description',
-                               'lang' => $langCode,
-                               'dir' => $langDir,
-                               'placeholder' => $this->msg(
-                                       'wikibase-description-edit-placeholder'
-                               )->text(),
-                               'label-message' => 
'wikibase-newentity-description'
-                       ],
-                       'aliases' => [
-                               'name' => 'aliases',
-                               'default' => $this->aliases ? implode( '|', 
$this->aliases ) : '',
-                               'type' => 'text',
-                               'id' => 'wb-newentity-aliases',
-                               'lang' => $langCode,
-                               'dir' => $langDir,
-                               'placeholder' => $this->msg(
-                                       'wikibase-aliases-edit-placeholder'
-                               )->text(),
-                               'label-message' => 'wikibase-newentity-aliases'
-                       ]
-               ];
-       }
-
-       /**
-        * Building the HTML form for creating a new item.
-        *
-        * @param string|null $legend initial value for the label input box
-        * @param array[] $additionalFormElements initial value for the 
description input box
-        */
-       private function createForm( $legend = null, array 
$additionalFormElements ) {
-               $this->addCopyrightText();
-
-               $this->getOutput()->addModules( 'wikibase.special.newEntity' );
-
-               HTMLForm::factory( 'ooui', $additionalFormElements, 
$this->getContext() )
-                       ->setId( 'mw-newentity-form1' )
-                       ->setSubmitID( 'wb-newentity-submit' )
-                       ->setSubmitName( 'submit' )
-                       ->setSubmitTextMsg( 'wikibase-newentity-submit' )
-                       ->setWrapperLegendMsg( $legend )
-                       ->setSubmitCallback( function () {// no-op
-                       } )->show();
-       }
-
-       /**
-        * @todo could factor this out into a special page form builder and 
renderer
-        */
-       private function addCopyrightText() {
-               $html = $this->copyrightView->getHtml( $this->getLanguage(), 
'wikibase-newentity-submit' );
-
-               $this->getOutput()->addHTML( $html );
-       }
+       abstract protected function getFormFields();
 
        /**
         * @since 0.1
@@ -369,4 +145,91 @@
         */
        abstract protected function getWarnings();
 
+       /**
+        * @return HTMLForm
+        */
+       private function createForm() {
+               return HTMLForm::factory( 'ooui', $this->getFormFields(), 
$this->getContext() )
+                       ->setId( 'mw-newentity-form1' )
+                       ->setSubmitID( 'wb-newentity-submit' )
+                       ->setSubmitName( 'submit' )
+                       ->setSubmitTextMsg( 'wikibase-newentity-submit' )
+                       ->setWrapperLegendMsg( $this->getLegend() )
+                       ->setSubmitCallback(
+                               function ( $data, HTMLForm $form ) {
+                                       $validationStatus = 
$this->validateFormData( $data );
+                                       if ( !$validationStatus->isGood() ) {
+                                               return $validationStatus;
+                                       }
+
+                                       $entity = 
$this->createEntityFromFormData( $data );
+
+                                       $summary = $this->createSummary( 
$entity );
+
+                                       $saveStatus = $this->saveEntity(
+                                               $entity,
+                                               $summary,
+                                               $form->getRequest()->getVal( 
'wpEditToken' ),
+                                               EDIT_NEW
+                                       );
+
+                                       if ( !$saveStatus->isGood() ) {
+                                               return $saveStatus;
+                                       }
+
+                                       return Status::newGood( $entity );
+                               }
+                       );
+       }
+
+       /**
+        * @param array $formData
+        *
+        * @return EntityDocument
+        */
+       abstract protected function createEntityFromFormData( array $formData );
+
+       /**
+        * @param array $formData
+        *
+        * @return Status
+        */
+       abstract protected function validateFormData( array $formData );
+
+       /**
+        * @param EntityDocument $entity
+        *
+        * @return Summary
+        */
+       abstract protected function createSummary( $entity );
+
+       /**
+        * @return string
+        */
+       private function getCopyrightText() {
+               return $this->copyrightView->getHtml( $this->getLanguage(), 
'wikibase-newentity-submit' );
+       }
+
+       /**
+        * @param OutputPage $output
+        */
+       protected function displayBeforeForm( OutputPage $output ) {
+               $output->addModules( 'wikibase.special.newEntity' );
+
+               $output->addHTML( $this->getCopyrightText() );
+
+               foreach ( $this->getWarnings() as $warning ) {
+                       $output->addHTML( Html::element( 'div', [ 'class' => 
'warning' ], $warning ) );
+               }
+       }
+
+       /**
+        * @param EntityDocument $entity
+        */
+       private function redirectToEntityPage( EntityDocument $entity ) {
+               $title = $this->getEntityTitle( $entity->getId() );
+               $entityUrl = $title->getFullURL();
+               $this->getOutput()->redirect( $entityUrl );
+       }
+
 }
diff --git a/extensions/Wikibase/repo/includes/Specials/SpecialNewItem.php 
b/extensions/Wikibase/repo/includes/Specials/SpecialNewItem.php
index 800fbd9..f108256 100644
--- a/extensions/Wikibase/repo/includes/Specials/SpecialNewItem.php
+++ b/extensions/Wikibase/repo/includes/Specials/SpecialNewItem.php
@@ -2,10 +2,14 @@
 
 namespace Wikibase\Repo\Specials;
 
-use InvalidArgumentException;
+use OutputPage;
+use SiteLookup;
 use Status;
-use Wikibase\DataModel\Entity\EntityDocument;
+use WebRequest;
 use Wikibase\DataModel\Entity\Item;
+use Wikibase\DataModel\Term\Term;
+use Wikibase\Repo\Specials\HTMLForm\HTMLTrimmedTextField;
+use Wikibase\Summary;
 
 /**
  * Page for creating new Wikibase items.
@@ -17,21 +21,22 @@
  */
 class SpecialNewItem extends SpecialNewEntity {
 
-       /**
-        * @var string|null
-        */
-       private $siteId;
-
-       /**
-        * @var string|null
-        */
-       private $pageName;
+       const FIELD_LANG = 'lang';
+       const FIELD_LABEL = 'label';
+       const FIELD_DESCRIPTION = 'description';
+       const FIELD_ALIASES = 'aliases';
+       const FIELD_SITE = 'site';
+       const FIELD_PAGE = 'page';
 
        /**
         * @since 0.1
+        * @param SiteLookup|null $siteStore
         */
-       public function __construct() {
+       public function __construct( SiteLookup $siteStore = null ) {
                parent::__construct( 'NewItem' );
+               if ( $siteStore ) {
+                       $this->siteLookup = $siteStore;
+               }
        }
 
        public function doesWrites() {
@@ -39,96 +44,137 @@
        }
 
        /**
-        * @see SpecialNewEntity::prepareArguments
-        */
-       protected function prepareArguments() {
-               parent::prepareArguments();
-
-               $this->siteId = $this->getRequest()->getVal( 'site' );
-               $this->pageName = $this->getRequest()->getVal( 'page' );
-       }
-
-       /**
         * @return bool
         */
-       private function isSiteLinkProvided() {
-               return $this->siteId !== null && $this->pageName !== null;
+       private function isSiteLinkProvided( WebRequest $request ) {
+               return $request->getVal( self::FIELD_SITE ) !== null
+                          && $request->getVal( self::FIELD_PAGE ) !== null;
        }
 
        /**
-        * @see SpecialNewEntity::createEntity
-        *
+        * @param array $formData
         * @return Item
         */
-       protected function createEntity() {
-               return new Item();
-       }
+       protected function createEntityFromFormData( array $formData ) {
+               $languageCode = $formData[ self::FIELD_LANG ];
 
-       /**
-        * @see SpecialNewEntity::modifyEntity
-        *
-        * @param EntityDocument $item
-        *
-        * @throws InvalidArgumentException
-        * @return Status
-        */
-       protected function modifyEntity( EntityDocument $item ) {
-               $status = parent::modifyEntity( $item );
+               $item = new Item();
+               $fingerprint = $item->getFingerprint();
+               $fingerprint->setLabel( $languageCode, $formData[ 
self::FIELD_LABEL ] );
+               $fingerprint->setDescription( $languageCode, $formData[ 
self::FIELD_DESCRIPTION ] );
 
-               if ( $this->isSiteLinkProvided() ) {
-                       if ( !( $item instanceof Item ) ) {
-                               throw new InvalidArgumentException( 'Unexpected 
entity type' );
-                       }
+               $aliases = explode( '|', (string)$formData[ self::FIELD_ALIASES 
] );
+               $aliases = array_map( [ $this->stringNormalizer, 'trimToNFC' ], 
$aliases );
+               $fingerprint->setAliasGroup( $languageCode, $aliases );
 
-                       $site = $this->siteLookup->getSite( $this->siteId );
+               if ( isset( $formData[ self::FIELD_SITE ] ) ) {
+                       $site = $this->siteLookup->getSite( $formData[ 
self::FIELD_SITE ] );
+                       $normalizedPageName = $site->normalizePageName( 
$formData[ self::FIELD_PAGE ] );
 
-                       if ( $site === null ) {
-                               $status->error( 
'wikibase-newitem-not-recognized-siteid' );
-                               return $status;
-                       }
-
-                       $normalizedPageName = $site->normalizePageName( 
$this->pageName );
-
-                       if ( $normalizedPageName === false ) {
-                               $status->error( 
'wikibase-newitem-no-external-page', $this->siteId, $this->pageName );
-                               return $status;
-                       }
-
-                       $item->getSiteLinkList()->addNewSiteLink( 
$this->siteId, $normalizedPageName );
+                       $item->getSiteLinkList()->addNewSiteLink( 
$site->getGlobalId(), $normalizedPageName );
                }
 
-               return $status;
+               return $item;
        }
 
        /**
-        * @see SpecialNewEntity::additionalFormElements
-        *
         * @return array[]
         */
-       protected function additionalFormElements() {
-               $formDescriptor = parent::additionalFormElements();
+       protected function getFormFields() {
+               $langCode = $this->getLanguage()->getCode();
 
-               if ( $this->isSiteLinkProvided() ) {
-                       $formDescriptor['site'] = [
-                               'name' => 'site',
-                               'default' => $this->siteId,
+               $formFields = [
+                       self::FIELD_LANG => [
+                               'name' => self::FIELD_LANG,
+                               'options' => $this->getLanguageOptions(),
+                               'default' => $langCode,
+                               'type' => 'combobox',
+                               'id' => 'wb-newentity-language',
+                               'filter-callback' => [ $this->stringNormalizer, 
'trimToNFC' ],
+                               'validation-callback' => function ( $language ) 
{
+                                       if ( !in_array( $language, 
$this->languageCodes ) ) {
+                                               return [ $this->msg( 
'wikibase-newitem-not-recognized-language' )->text() ];
+                                       }
+
+                                       return true;
+                               },
+                               'label-message' => 
'wikibase-newentity-language',
+                       ],
+                       self::FIELD_LABEL => [
+                               'name' => self::FIELD_LABEL,
+                               'default' => isset( $this->parts[0] ) ? 
$this->parts[0] : '',
+                               'class' => HTMLTrimmedTextField::class,
+                               'id' => 'wb-newentity-label',
+                               'placeholder-message' => 
'wikibase-label-edit-placeholder',
+                               'label-message' => 'wikibase-newentity-label',
+                       ],
+                       self::FIELD_DESCRIPTION => [
+                               'name' => self::FIELD_DESCRIPTION,
+                               'default' => isset( $this->parts[1] ) ? 
$this->parts[1] : '',
+                               'class' => HTMLTrimmedTextField::class,
+                               'id' => 'wb-newentity-description',
+                               'placeholder-message' => 
'wikibase-description-edit-placeholder',
+                               'label-message' => 
'wikibase-newentity-description',
+                       ],
+                       self::FIELD_ALIASES => [
+                               'name' => self::FIELD_ALIASES,
+                               'class' => HTMLTrimmedTextField::class,
+                               'id' => 'wb-newentity-aliases',
+                               'placeholder-message' => 
'wikibase-aliases-edit-placeholder',
+                               'label-message' => 'wikibase-newentity-aliases',
+                       ],
+               ];
+
+               if ( $this->isSiteLinkProvided( $this->getRequest() ) ) {
+                       $formFields[ self::FIELD_SITE ] = [
+                               'name' => self::FIELD_SITE,
+                               'default' => $this->getRequest()->getVal( 
self::FIELD_SITE ),
                                'type' => 'text',
                                'id' => 'wb-newitem-site',
                                'readonly' => 'readonly',
+                               'validation-callback' => function ( $siteId, 
$formData ) {
+                                       $site = $this->siteLookup->getSite( 
$siteId );
+
+                                       if ( $site === null ) {
+                                               return [ $this->msg( 
'wikibase-newitem-not-recognized-siteid' )->text() ];
+                                       }
+
+                                       return true;
+                               },
                                'label-message' => 'wikibase-newitem-site'
                        ];
 
-                       $formDescriptor['page'] = [
-                               'name' => 'page',
-                               'default' => $this->pageName,
+                       $formFields[ self::FIELD_PAGE ] = [
+                               'name' => self::FIELD_PAGE,
+                               'default' => $this->getRequest()->getVal( 
self::FIELD_PAGE ),
                                'type' => 'text',
                                'id' => 'wb-newitem-page',
                                'readonly' => 'readonly',
+                               'validation-callback' => function ( $pageName, 
$formData ) {
+                                       $siteId = $formData['site'];
+                                       $site = $this->siteLookup->getSite( 
$siteId );
+                                       if ( $site === null ) {
+                                               return true;
+                                       }
+
+                                       $normalizedPageName = 
$site->normalizePageName( $pageName );
+                                       if ( $normalizedPageName === false ) {
+                                               return [
+                                                       $this->msg(
+                                                               
'wikibase-newitem-no-external-page',
+                                                               $siteId,
+                                                               $pageName
+                                                       )->text(),
+                                               ];
+                                       }
+
+                                       return true;
+                               },
                                'label-message' => 'wikibase-newitem-page'
                        ];
                }
 
-               return $formDescriptor;
+               return $formFields;
        }
 
        /**
@@ -155,4 +201,47 @@
                return [];
        }
 
+       /**
+        * @param array $formData
+        *
+        * @return Status
+        */
+       protected function validateFormData( array $formData ) {
+               if ( $formData[ self::FIELD_LABEL ] == ''
+                        && $formData[ self::FIELD_DESCRIPTION ] == ''
+                        && $formData[ self::FIELD_ALIASES ] == ''
+               ) {
+                       return Status::newFatal( 
'wikibase-newitem-insufficient-data' );
+               }
+
+               return Status::newGood();
+       }
+
+       /**
+        * @param Item $item
+        *
+        * @return Summary
+        */
+       protected function createSummary( $item ) {
+               $uiLanguageCode = $this->getLanguage()->getCode();
+
+               $summary = new Summary( 'wbeditentity', 'create' );
+               $summary->setLanguage( $uiLanguageCode );
+               /** @var Term|null $labelTerm */
+               $labelTerm = 
$item->getFingerprint()->getLabels()->getIterator()->current();
+               /** @var Term|null $descriptionTerm */
+               $descriptionTerm = 
$item->getFingerprint()->getDescriptions()->getIterator()->current();
+               $summary->addAutoSummaryArgs(
+                       $labelTerm ? $labelTerm->getText() : '',
+                       $descriptionTerm ? $descriptionTerm->getText() : ''
+               );
+
+               return $summary;
+       }
+
+       protected function displayBeforeForm( OutputPage $output ) {
+               parent::displayBeforeForm( $output );
+               $output->addModules( 
'wikibase.special.languageLabelDescriptionAliases' );
+       }
+
 }
diff --git a/extensions/Wikibase/repo/includes/Specials/SpecialNewProperty.php 
b/extensions/Wikibase/repo/includes/Specials/SpecialNewProperty.php
index cd5f675..c068196 100644
--- a/extensions/Wikibase/repo/includes/Specials/SpecialNewProperty.php
+++ b/extensions/Wikibase/repo/includes/Specials/SpecialNewProperty.php
@@ -2,12 +2,14 @@
 
 namespace Wikibase\Repo\Specials;
 
-use InvalidArgumentException;
+use OutputPage;
 use Status;
-use Wikibase\DataModel\Entity\EntityDocument;
 use Wikibase\DataModel\Entity\Property;
+use Wikibase\DataModel\Term\Term;
 use Wikibase\DataTypeSelector;
+use Wikibase\Repo\Specials\HTMLForm\HTMLTrimmedTextField;
 use Wikibase\Repo\WikibaseRepo;
+use Wikibase\Summary;
 
 /**
  * Page for creating new Wikibase properties.
@@ -18,11 +20,11 @@
  * @author John Erling Blad < jeb...@gmail.com >
  */
 class SpecialNewProperty extends SpecialNewEntity {
-
-       /**
-        * @var string|null
-        */
-       private $dataType = null;
+       const FIELD_LANG = 'lang';
+       const FIELD_DATATYPE = 'datatype';
+       const FIELD_LABEL = 'label';
+       const FIELD_DESCRIPTION = 'description';
+       const FIELD_ALIASES = 'aliases';
 
        /**
         * @since 0.2
@@ -35,89 +37,104 @@
                return true;
        }
 
-       /**
-        * @see SpecialNewEntity::prepareArguments
-        */
-       protected function prepareArguments() {
-               parent::prepareArguments();
+       protected function createEntityFromFormData( array $formData ) {
+               $languageCode = $formData[ self::FIELD_LANG ];
 
-               $this->dataType = $this->getRequest()->getVal(
-                       'datatype',
-                       isset( $this->parts[2] ) ? $this->parts[2] : ''
-               );
-       }
+               $property = Property::newFromType( $formData[ 
self::FIELD_DATATYPE ] );
 
-       /**
-        * @see SpecialNewEntity::hasSufficientArguments()
-        */
-       protected function hasSufficientArguments() {
-               // TODO: Needs refinement
-               return parent::hasSufficientArguments() && ( $this->dataType 
!== '' );
-       }
+               $fingerprint = $property->getFingerprint();
+               $fingerprint->setLabel( $languageCode, $formData[ 
self::FIELD_LABEL ] );
+               $fingerprint->setDescription( $languageCode, $formData[ 
self::FIELD_DESCRIPTION ] );
 
-       /**
-        * @see SpecialNewEntity::createEntity
-        */
-       protected function createEntity() {
-               return Property::newFromType( 'string' );
-       }
+               $aliases = explode( '|', (string)$formData[ self::FIELD_ALIASES 
] );
+               $aliases = array_map( [ $this->stringNormalizer, 'trimToNFC' ], 
$aliases );
+               $fingerprint->setAliasGroup( $languageCode, $aliases );
 
-       /**
-        * @see SpecialNewEntity::modifyEntity
-        *
-        * @param EntityDocument $property
-        *
-        * @throws InvalidArgumentException
-        * @return Status
-        */
-       protected function modifyEntity( EntityDocument $property ) {
-               $status = parent::modifyEntity( $property );
-
-               if ( $this->dataType !== '' ) {
-                       if ( !( $property instanceof Property ) ) {
-                               throw new InvalidArgumentException( 'Unexpected 
entity type' );
-                       }
-
-                       if ( $this->dataTypeExists() ) {
-                               $property->setDataTypeId( $this->dataType );
-                       } else {
-                               $status->fatal( 
'wikibase-newproperty-invalid-datatype' );
-                       }
-               }
-
-               return $status;
+               return $property;
        }
 
        /**
         * @return bool
         */
-       private function dataTypeExists() {
+       private function dataTypeExists( $dataType ) {
                $dataTypeFactory = 
WikibaseRepo::getDefaultInstance()->getDataTypeFactory();
-               $ids = $dataTypeFactory->getTypeIds();
-               return in_array( $this->dataType, $ids );
+
+               return in_array( $dataType, $dataTypeFactory->getTypeIds() );
        }
 
        /**
-        * @see SpecialNewEntity::additionalFormElements()
+        * @see SpecialNewEntity::getFormFields()
         *
         * @return array[]
         */
-       protected function additionalFormElements() {
-               $formDescriptor = parent::additionalFormElements();
+       protected function getFormFields() {
+               $langCode = $this->getLanguage()->getCode();
+
+               $formFields = [
+                       self::FIELD_LANG => [
+                               'name' => self::FIELD_LANG,
+                               'options' => $this->getLanguageOptions(),
+                               'default' => $langCode,
+                               'type' => 'combobox',
+                               'id' => 'wb-newentity-language',
+                               'filter-callback' => [ $this->stringNormalizer, 
'trimToNFC' ],
+                               'validation-callback' => function ( $language ) 
{
+                                       if ( !in_array( $language, 
$this->languageCodes ) ) {
+                                               return [ $this->msg( 
'wikibase-newitem-not-recognized-language' )->text() ];
+                                       }
+
+                                       return true;
+                               },
+                               'label-message' => 'wikibase-newentity-language'
+                       ],
+                       self::FIELD_LABEL => [
+                               'name' => self::FIELD_LABEL,
+                               'default' => isset( $this->parts[0] ) ? 
$this->parts[0] : '',
+                               'class' => HTMLTrimmedTextField::class,
+                               'id' => 'wb-newentity-label',
+                               'placeholder-message' => 
'wikibase-label-edit-placeholder',
+                               'label-message' => 'wikibase-newentity-label'
+                       ],
+                       self::FIELD_DESCRIPTION => [
+                               'name' => self::FIELD_DESCRIPTION,
+                               'default' => isset( $this->parts[1] ) ? 
$this->parts[1] : '',
+                               'class' => HTMLTrimmedTextField::class,
+                               'id' => 'wb-newentity-description',
+                               'placeholder-message' => 
'wikibase-description-edit-placeholder',
+                               'label-message' => 
'wikibase-newentity-description'
+                       ],
+                       self::FIELD_ALIASES => [
+                               'name' => self::FIELD_ALIASES,
+                               'class' => HTMLTrimmedTextField::class,
+                               'id' => 'wb-newentity-aliases',
+                               'placeholder-message' => 
'wikibase-aliases-edit-placeholder',
+                               'label-message' => 'wikibase-newentity-aliases'
+                       ]
+               ];
 
                $dataTypeFactory = 
WikibaseRepo::getDefaultInstance()->getDataTypeFactory();
-               $selector = new DataTypeSelector( $dataTypeFactory->getTypes(), 
$this->getLanguage()->getCode() );
+               $selector = new DataTypeSelector(
+                       $dataTypeFactory->getTypes(),
+                       $this->getLanguage()->getCode()
+               );
 
-               $formDescriptor['datatype'] = [
-                       'name' => 'datatype',
+               $formFields[ self::FIELD_DATATYPE ] = [
+                       'name' => self::FIELD_DATATYPE,
                        'type' => 'select',
-                       'default' => $this->dataType,
+                       'default' => isset( $this->parts[2] ) ? $this->parts[2] 
: 'string',
                        'options' => array_flip( $selector->getOptionsArray() ),
                        'id' => 'wb-newproperty-datatype',
+                       'validation-callback' => function ( $dataType, 
$formData, $form ) {
+                               if ( !$this->dataTypeExists( $dataType ) ) {
+                                       return [ $this->msg( 
'wikibase-newproperty-invalid-datatype' )->text() ];
+                               }
+
+                               return true;
+                       },
                        'label-message' => 'wikibase-newproperty-datatype'
                ];
 
-               return $formDescriptor;
+               return $formFields;
        }
 
        /**
@@ -145,4 +162,47 @@
                return [];
        }
 
+       /**
+        * @param array $formData
+        *
+        * @return Status
+        */
+       protected function validateFormData( array $formData ) {
+               if ( $formData[ self::FIELD_LABEL ] == ''
+                        && $formData[ self::FIELD_DESCRIPTION ] == ''
+                        && $formData[ self::FIELD_ALIASES ] == ''
+               ) {
+                       return Status::newFatal( 
'wikibase-newproperty-insufficient-data' );
+               }
+
+               return Status::newGood();
+       }
+
+       /**
+        * @param Property $property
+        *
+        * @return Summary
+        */
+       protected function createSummary( $property ) {
+               $uiLanguageCode = $this->getLanguage()->getCode();
+
+               $summary = new Summary( 'wbeditentity', 'create' );
+               $summary->setLanguage( $uiLanguageCode );
+               /** @var Term|null $labelTerm */
+               $labelTerm = 
$property->getFingerprint()->getLabels()->getIterator()->current();
+               /** @var Term|null $descriptionTerm */
+               $descriptionTerm = 
$property->getFingerprint()->getDescriptions()->getIterator()->current();
+               $summary->addAutoSummaryArgs(
+                       $labelTerm ? $labelTerm->getText() : '',
+                       $descriptionTerm ? $descriptionTerm->getText() : ''
+               );
+
+               return $summary;
+       }
+
+       protected function displayBeforeForm( OutputPage $output ) {
+               parent::displayBeforeForm( $output );
+               $output->addModules( 
'wikibase.special.languageLabelDescriptionAliases' );
+       }
+
 }
diff --git 
a/extensions/Wikibase/repo/tests/phpunit/includes/Specials/HtmlAssertionHelpers.php
 
b/extensions/Wikibase/repo/tests/phpunit/includes/Specials/HtmlAssertionHelpers.php
index c1fc110..1c621a4 100644
--- 
a/extensions/Wikibase/repo/tests/phpunit/includes/Specials/HtmlAssertionHelpers.php
+++ 
b/extensions/Wikibase/repo/tests/phpunit/includes/Specials/HtmlAssertionHelpers.php
@@ -41,7 +41,7 @@
                $this->assertTag(
                        $matcher,
                        $html,
-                       "Failed to find input element with name '{$name}' and 
value '{$value}'"
+                       "Failed to find input element with name '{$name}' and 
value '{$value}' in :\n{$html}"
                );
        }
 
@@ -123,6 +123,27 @@
        }
 
        protected function assertHtmlContainsErrorMessage( $html, $messageText 
) {
+               $assertions = [
+                       [ $this, 'assertHtmlContainsFormErrorMessage' ],
+                       [ $this, 'assertHtmlContainsOOUiErrorMessage' ],
+               ];
+
+               foreach ( $assertions as $assertion ) {
+                       try {
+                               $assertion( $html, $messageText );
+
+                               return;
+                       } catch ( \PHPUnit_Framework_ExpectationFailedException 
$exception ) {
+                               continue;
+                       }
+               }
+
+               $this->fail(
+                       "Failed to find error message with text 
'{$messageText}' in html:\n\n {$html}"
+               );
+       }
+
+       protected function assertHtmlContainsFormErrorMessage( $html, 
$messageText ) {
                $matcher = [
                        'tag' => 'div',
                        'class' => 'error',
@@ -131,7 +152,20 @@
                $this->assertTag(
                        $matcher,
                        $html,
-                       "Failed to find error message with text 
'{$messageText}' in html:\n\n {$html}"
+                       "Failed to find form error message with text 
'{$messageText}' in html:\n\n {$html}"
+               );
+       }
+
+       protected function assertHtmlContainsOOUiErrorMessage( $html, 
$messageText ) {
+               $matcher = [
+                       'tag' => 'li',
+                       'class' => 'oo-ui-fieldLayout-messages-error',
+                       'content' => 'regexp: /' . preg_quote( $messageText, 
'/' ) . '/ui',
+               ];
+               $this->assertTag(
+                       $matcher,
+                       $html,
+                       "Failed to find OO-UI error message with text 
'{$messageText}' in html:\n\n {$html}"
                );
        }
 
diff --git 
a/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialMergeItemsTest.php
 
b/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialMergeItemsTest.php
index 9f7162a..7d2904b 100644
--- 
a/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialMergeItemsTest.php
+++ 
b/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialMergeItemsTest.php
@@ -283,18 +283,19 @@
                return $permissionChecker;
        }
 
+       /**
+        * @param string $error
+        * @param string $html
+        */
        private function assertError( $error, $html ) {
-               // Match error strings as generated by the ExceptionLocalizer 
mock!
-               if ( !preg_match( '!<p class="error">\(@(.*?)@\)</p>!', $html, 
$m ) ) {
-                       $this->fail( 'Expected error ' . $error . '. No error 
found in page!' );
-               }
-
-               $this->assertEquals( $error, $m[1], 'Expected error ' . $error 
);
+               $this->assertContains( '<p class="error">(@' . $error . 
'@)</p>', $html );
        }
 
+       /**
+        * @param string $html
+        */
        private function assertNoError( $html ) {
-               $pattern = '!<p class="error"!';
-               $this->assertNotRegExp( $pattern, $html, 'Expected no error!' );
+               $this->assertNotContains( 'class="error"', $html );
        }
 
        public function mergeRequestProvider() {
diff --git 
a/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialNewItemTest.php
 
b/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialNewItemTest.php
index f56b03e..cb09d51 100644
--- 
a/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialNewItemTest.php
+++ 
b/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialNewItemTest.php
@@ -3,6 +3,9 @@
 namespace Wikibase\Repo\Tests\Specials;
 
 use FauxRequest;
+use HashSiteStore;
+use Site;
+use SiteStore;
 use Wikibase\DataModel\Entity\EntityDocument;
 use Wikibase\DataModel\Entity\Item;
 use Wikibase\DataModel\Entity\ItemId;
@@ -28,31 +31,50 @@
  */
 class SpecialNewItemTest extends SpecialNewEntityTest {
 
+       /**
+        * @var SiteStore
+        */
+       private $siteStore;
+
+       protected function setUp() {
+               parent::setUp();
+
+               $this->siteStore = new HashSiteStore();
+       }
+
        protected function newSpecialPage() {
-               return new SpecialNewItem();
+               return new SpecialNewItem( $this->siteStore );
        }
 
        public function testAllNecessaryFormFieldsArePresent_WhenRendered() {
 
                list( $html ) = $this->executeSpecialPage();
 
-               $this->assertHtmlContainsInputWithName( $html, 'lang' );
-               $this->assertHtmlContainsInputWithName( $html, 'label' );
-               $this->assertHtmlContainsInputWithName( $html, 'description' );
-               $this->assertHtmlContainsInputWithName( $html, 'aliases' );
+               $this->assertHtmlContainsInputWithName( $html, 
SpecialNewItem::FIELD_LANG );
+               $this->assertHtmlContainsInputWithName( $html, 
SpecialNewItem::FIELD_LABEL );
+               $this->assertHtmlContainsInputWithName( $html, 
SpecialNewItem::FIELD_DESCRIPTION );
+               $this->assertHtmlContainsInputWithName( $html, 
SpecialNewItem::FIELD_ALIASES );
                $this->assertHtmlContainsSubmitControl( $html );
        }
 
        public function 
testSiteAndPageInputFieldsWithPredefinedValuesPresent_WhenRenderedWithGetParametersPassed()
 {
                $getParameters = [
-                       'site' => 'some-site',
-                       'page' => 'some-page'
+                       SpecialNewItem::FIELD_SITE => 'some-site',
+                       SpecialNewItem::FIELD_PAGE => 'some-page'
                ];
 
                list( $html ) = $this->executeSpecialPage( '', new FauxRequest( 
$getParameters ) );
 
-               $this->assertHtmlContainsInputWithNameAndValue( $html, 'site', 
'some-site' );
-               $this->assertHtmlContainsInputWithNameAndValue( $html, 'page', 
'some-page' );
+               $this->assertHtmlContainsInputWithNameAndValue(
+                       $html,
+                       SpecialNewItem::FIELD_SITE,
+                       'some-site'
+               );
+               $this->assertHtmlContainsInputWithNameAndValue(
+                       $html,
+                       SpecialNewItem::FIELD_PAGE,
+                       'some-page'
+               );
        }
 
        public function 
testLabelAndDescriptionValuesAreSetAccordingToSubpagePath_WhenRendered() {
@@ -62,58 +84,74 @@
 
                list( $html, ) = $this->executeSpecialPage( $subPage );
 
-               $this->assertHtmlContainsInputWithNameAndValue( $html, 'label', 
$subPagePart1 );
-               $this->assertHtmlContainsInputWithNameAndValue( $html, 
'description', $subPagePart2 );
+               $this->assertHtmlContainsInputWithNameAndValue( $html, 
SpecialNewItem::FIELD_LABEL, $subPagePart1 );
+               $this->assertHtmlContainsInputWithNameAndValue( $html, 
SpecialNewItem::FIELD_DESCRIPTION, $subPagePart2 );
        }
 
        public function provideValidEntityCreationRequests() {
                return [
                        'only label is set' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => 'label',
-                                       'description' => '',
-                                       'aliases' => '',
+                                       SpecialNewItem::FIELD_LANG => 'en',
+                                       SpecialNewItem::FIELD_LABEL => 'label',
+                                       SpecialNewItem::FIELD_DESCRIPTION => '',
+                                       SpecialNewItem::FIELD_ALIASES => '',
                                ],
                        ],
                        'another language' => [
                                [
-                                       'lang' => 'fr',
-                                       'label' => 'label',
-                                       'description' => '',
-                                       'aliases' => '',
+                                       SpecialNewItem::FIELD_LANG => 'fr',
+                                       SpecialNewItem::FIELD_LABEL => 'label',
+                                       SpecialNewItem::FIELD_DESCRIPTION => '',
+                                       SpecialNewItem::FIELD_ALIASES => '',
                                ],
                        ],
                        'only description is set' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => '',
-                                       'description' => 'desc',
-                                       'aliases' => '',
+                                       SpecialNewItem::FIELD_LANG => 'en',
+                                       SpecialNewItem::FIELD_LABEL => '',
+                                       SpecialNewItem::FIELD_DESCRIPTION => 
'desc',
+                                       SpecialNewItem::FIELD_ALIASES => '',
                                ],
                        ],
                        'single alias' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => '',
-                                       'description' => '',
-                                       'aliases' => 'alias',
+                                       SpecialNewItem::FIELD_LANG => 'en',
+                                       SpecialNewItem::FIELD_LABEL => '',
+                                       SpecialNewItem::FIELD_DESCRIPTION => '',
+                                       SpecialNewItem::FIELD_ALIASES => 
'alias',
                                ],
                        ],
                        'multiple aliases' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => '',
-                                       'description' => '',
-                                       'aliases' => 'alias1|alias2|alias3',
+                                       SpecialNewItem::FIELD_LANG => 'en',
+                                       SpecialNewItem::FIELD_LABEL => '',
+                                       SpecialNewItem::FIELD_DESCRIPTION => '',
+                                       SpecialNewItem::FIELD_ALIASES => 
'alias1|alias2|alias3',
+                               ],
+                       ],
+                       'nontrimmed label' => [
+                               [
+                                       SpecialNewItem::FIELD_LANG => 'en',
+                                       SpecialNewItem::FIELD_LABEL => '  some 
text with spaces on the sides    ',
+                                       SpecialNewItem::FIELD_DESCRIPTION => '',
+                                       SpecialNewItem::FIELD_ALIASES => '',
+                               ],
+                       ],
+                       'nontrimmed description' => [
+                               [
+                                       SpecialNewItem::FIELD_LANG => 'en',
+                                       SpecialNewItem::FIELD_LABEL => '',
+                                       SpecialNewItem::FIELD_DESCRIPTION => ' 
description with spaces on the sides ',
+                                       SpecialNewItem::FIELD_ALIASES => '',
                                ],
                        ],
                        'all input is present' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => 'label',
-                                       'description' => 'desc',
-                                       'aliases' => 'a1|a2',
+                                       SpecialNewItem::FIELD_LANG => 'en',
+                                       SpecialNewItem::FIELD_LABEL => 'label',
+                                       SpecialNewItem::FIELD_DESCRIPTION => 
'desc',
+                                       SpecialNewItem::FIELD_ALIASES => 
'a1|a2',
                                ],
                        ],
                ];
@@ -123,45 +161,33 @@
                return [
                        'unknown language' => [
                                [
-                                       'lang' => 'some-weird-language',
-                                       'label' => 'label',
-                                       'description' => '',
-                                       'aliases' => '',
+                                       SpecialNewItem::FIELD_LANG => 
'some-weird-language',
+                                       SpecialNewItem::FIELD_LABEL => 'label',
+                                       SpecialNewItem::FIELD_DESCRIPTION => '',
+                                       SpecialNewItem::FIELD_ALIASES => '',
                                ],
                                'language code was not recognized',
                        ],
                        'unknown site identifier' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => 'label',
-                                       'description' => '',
-                                       'aliases' => '',
-                                       'site' => 'unknown',
-                                       'page' => 'some page'
+                                       SpecialNewItem::FIELD_LANG => 'en',
+                                       SpecialNewItem::FIELD_LABEL => 'label',
+                                       SpecialNewItem::FIELD_DESCRIPTION => '',
+                                       SpecialNewItem::FIELD_ALIASES => '',
+                                       SpecialNewItem::FIELD_SITE => 'unknown',
+                                       SpecialNewItem::FIELD_PAGE => 'some 
page'
                                ],
                                'site identifier was not recognized',
                        ],
-                       //Property - uniq: label(in language)
-
-                       //                      'bad user token' => [  // TODO 
Probably should be implemented
-                       //                              [
-                       //                                      'lang' => 'en',
-                       //                                      'label' => 
'label',
-                       //                                      'description' 
=> '',
-                       //                                      'aliases' => '',
-                       //                                      'wpEditToken' 
=> 'some bad token'
-                       //                              ],
-                       //                              'try again',
-                       //                      ],
-                       //                      'all fields are empty' => [  // 
TODO Probably should be implemented
-                       //                              [
-                       //                                      'lang' => 'en',
-                       //                                      'label' => '',
-                       //                                      'description' 
=> '',
-                       //                                      'aliases' => '',
-                       //                              ],
-                       //                              '???'
-                       //                      ],
+                       'all fields are empty' => [
+                               [
+                                       SpecialNewItem::FIELD_LANG => 'en',
+                                       SpecialNewItem::FIELD_LABEL => '',
+                                       SpecialNewItem::FIELD_DESCRIPTION => '',
+                                       SpecialNewItem::FIELD_ALIASES => '',
+                               ],
+                               'you need to fill'
+                       ],
                ];
        }
 
@@ -171,10 +197,10 @@
                }
 
                $formData = [
-                       'lang' => 'en',
-                       'label' => 'label1',
-                       'description' => 'description1',
-                       'aliases' => '',
+                       SpecialNewItem::FIELD_LANG => 'en',
+                       SpecialNewItem::FIELD_LABEL => 'label1',
+                       SpecialNewItem::FIELD_DESCRIPTION => 'description1',
+                       SpecialNewItem::FIELD_ALIASES => '',
                ];
                $this->executeSpecialPage( '', new FauxRequest( $formData, true 
) );
 
@@ -183,8 +209,25 @@
                $this->assertHtmlContainsErrorMessage( $html, 'already has 
label' );
        }
 
+       public function 
testErrorAboutNonExistentPageIsDisplayed_WhenSiteExistsButPageDoesNot() {
+               $existingSiteId = 'existing-site';
+               $formData = [
+                       SpecialNewItem::FIELD_LANG => 'en',
+                       SpecialNewItem::FIELD_LABEL => 'some label',
+                       SpecialNewItem::FIELD_DESCRIPTION => 'some description',
+                       SpecialNewItem::FIELD_ALIASES => '',
+                       SpecialNewItem::FIELD_SITE => $existingSiteId,
+                       SpecialNewItem::FIELD_PAGE => 'nonexistent-page'
+               ];
+               $this->givenSiteWithNoPagesExists( $existingSiteId );
+
+               list( $html ) = $this->executeSpecialPage( '', new FauxRequest( 
$formData, true ) );
+
+               $this->assertHtmlContainsErrorMessage( $html, 'could not be 
found on' );
+       }
+
        /**
-        * @param $itemUrl
+        * @param string $itemUrl
         * @return ItemId
         */
        protected function extractEntityIdFromUrl( $itemUrl ) {
@@ -202,25 +245,37 @@
                $this->assertInstanceOf( Item::class, $entity );
                /** @var Item $entity */
 
-               $language = $form['lang'];
-               if ( $form['label'] !== '' ) {
+               $language = $form[SpecialNewItem::FIELD_LANG];
+               if ( $form[SpecialNewItem::FIELD_LABEL] !== '' ) {
                        $this->assertSame(
-                               $form['label'],
+                               trim( $form[SpecialNewItem::FIELD_LABEL] ),
                                $entity->getLabels()->getByLanguage( $language 
)->getText()
                        );
                }
-               if ( $form['description'] !== '' ) {
+               if ( $form[SpecialNewItem::FIELD_DESCRIPTION] !== '' ) {
                        $this->assertSame(
-                               $form['description'],
+                               trim( $form[SpecialNewItem::FIELD_DESCRIPTION] 
),
                                $entity->getDescriptions()->getByLanguage( 
$language )->getText()
                        );
                }
-               if ( $form['aliases'] !== '' ) {
+               if ( $form[SpecialNewItem::FIELD_ALIASES] !== '' ) {
                        $this->assertArrayEquals(
-                               explode( '|', $form['aliases'] ),
+                               explode( '|', 
$form[SpecialNewItem::FIELD_ALIASES] ),
                                $entity->getAliasGroups()->getByLanguage( 
$language )->getAliases()
                        );
                }
        }
 
+       /**
+        * @param string $existingSiteId
+        */
+       private function givenSiteWithNoPagesExists( $existingSiteId ) {
+               /** @var \PHPUnit_Framework_MockObject_MockObject|Site 
$siteMock */
+               $siteMock = $this->getMock( Site::class, [ 'normalizePageName' 
] );
+               $siteMock->setGlobalId( $existingSiteId );
+               $siteMock->method( 'normalizePageName' )->willReturn( false );
+
+               $this->siteStore->saveSite( $siteMock );
+       }
+
 }
diff --git 
a/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialNewPropertyTest.php
 
b/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialNewPropertyTest.php
index 70ff7a6..5ea245c 100644
--- 
a/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialNewPropertyTest.php
+++ 
b/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialNewPropertyTest.php
@@ -36,11 +36,11 @@
 
                list( $html ) = $this->executeSpecialPage();
 
-               $this->assertHtmlContainsInputWithName( $html, 'lang' );
-               $this->assertHtmlContainsInputWithName( $html, 'label' );
-               $this->assertHtmlContainsInputWithName( $html, 'description' );
-               $this->assertHtmlContainsInputWithName( $html, 'aliases' );
-               $this->assertHtmlContainsSelectWithName( $html, 'datatype' );
+               $this->assertHtmlContainsInputWithName( $html, 
SpecialNewProperty::FIELD_LANG );
+               $this->assertHtmlContainsInputWithName( $html, 
SpecialNewProperty::FIELD_LABEL );
+               $this->assertHtmlContainsInputWithName( $html, 
SpecialNewProperty::FIELD_DESCRIPTION );
+               $this->assertHtmlContainsInputWithName( $html, 
SpecialNewProperty::FIELD_ALIASES );
+               $this->assertHtmlContainsSelectWithName( $html, 
SpecialNewProperty::FIELD_DATATYPE );
                $this->assertHtmlContainsSubmitControl( $html );
        }
 
@@ -52,18 +52,30 @@
 
                list( $html ) = $this->executeSpecialPage( $subPage );
 
-               $this->assertHtmlContainsInputWithNameAndValue( $html, 'label', 
$subPagePart1 );
-               $this->assertHtmlContainsInputWithNameAndValue( $html, 
'description', $subPagePart2 );
-               $this->assertHtmlContainsSelectWithNameAndSelectedValue( $html, 
'datatype', $subPagePart3 );
+               $this->assertHtmlContainsInputWithNameAndValue(
+                       $html,
+                       SpecialNewProperty::FIELD_LABEL,
+                       $subPagePart1
+               );
+               $this->assertHtmlContainsInputWithNameAndValue(
+                       $html,
+                       SpecialNewProperty::FIELD_DESCRIPTION,
+                       $subPagePart2
+               );
+               $this->assertHtmlContainsSelectWithNameAndSelectedValue(
+                       $html,
+                       SpecialNewProperty::FIELD_DATATYPE,
+                       $subPagePart3
+               );
        }
 
        public function 
testFailsAndDisplaysAnError_WhenTryToCreateSecondPropertyWithTheSameLabel() {
                $formData = [
-                       'lang' => 'en',
-                       'label' => 'label',
-                       'description' => '',
-                       'aliases' => '',
-                       'datatype' => 'string',
+                       SpecialNewProperty::FIELD_LANG => 'en',
+                       SpecialNewProperty::FIELD_LABEL => 'label',
+                       SpecialNewProperty::FIELD_DESCRIPTION => '',
+                       SpecialNewProperty::FIELD_ALIASES => '',
+                       SpecialNewProperty::FIELD_DATATYPE => 'string',
                ];
                $this->executeSpecialPage( '', new \FauxRequest( $formData, 
true ) );
 
@@ -81,65 +93,65 @@
                return [
                        'only label is set' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => 'label' . $labelIndex ++,
-                                       'description' => '',
-                                       'aliases' => '',
-                                       'datatype' => 'string',
+                                       SpecialNewProperty::FIELD_LANG => 'en',
+                                       SpecialNewProperty::FIELD_LABEL => 
'label' . $labelIndex ++,
+                                       SpecialNewProperty::FIELD_DESCRIPTION 
=> '',
+                                       SpecialNewProperty::FIELD_ALIASES => '',
+                                       SpecialNewProperty::FIELD_DATATYPE => 
'string',
                                ],
                        ],
                        'another language' => [
                                [
-                                       'lang' => 'fr',
-                                       'label' => 'label' . $labelIndex ++,
-                                       'description' => '',
-                                       'aliases' => '',
-                                       'datatype' => 'string',
+                                       SpecialNewProperty::FIELD_LANG => 'fr',
+                                       SpecialNewProperty::FIELD_LABEL => 
'label' . $labelIndex ++,
+                                       SpecialNewProperty::FIELD_DESCRIPTION 
=> '',
+                                       SpecialNewProperty::FIELD_ALIASES => '',
+                                       SpecialNewProperty::FIELD_DATATYPE => 
'string',
                                ],
                        ],
                        'only description is set' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => '',
-                                       'description' => 'desc',
-                                       'aliases' => '',
-                                       'datatype' => 'string',
+                                       SpecialNewProperty::FIELD_LANG => 'en',
+                                       SpecialNewProperty::FIELD_LABEL => '',
+                                       SpecialNewProperty::FIELD_DESCRIPTION 
=> 'desc',
+                                       SpecialNewProperty::FIELD_ALIASES => '',
+                                       SpecialNewProperty::FIELD_DATATYPE => 
'string',
                                ],
                        ],
                        'single alias' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => '',
-                                       'description' => '',
-                                       'aliases' => 'alias',
-                                       'datatype' => 'string',
+                                       SpecialNewProperty::FIELD_LANG => 'en',
+                                       SpecialNewProperty::FIELD_LABEL => '',
+                                       SpecialNewProperty::FIELD_DESCRIPTION 
=> '',
+                                       SpecialNewProperty::FIELD_ALIASES => 
'alias',
+                                       SpecialNewProperty::FIELD_DATATYPE => 
'string',
                                ],
                        ],
                        'multiple aliases' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => '',
-                                       'description' => '',
-                                       'aliases' => 'alias1|alias2|alias3',
-                                       'datatype' => 'string',
+                                       SpecialNewProperty::FIELD_LANG => 'en',
+                                       SpecialNewProperty::FIELD_LABEL => '',
+                                       SpecialNewProperty::FIELD_DESCRIPTION 
=> '',
+                                       SpecialNewProperty::FIELD_ALIASES => 
'alias1|alias2|alias3',
+                                       SpecialNewProperty::FIELD_DATATYPE => 
'string',
                                ],
                        ],
                        'another datatype is set' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => 'label' . $labelIndex ++,
-                                       'description' => '',
-                                       'aliases' => '',
-                                       'datatype' => 'url',
+                                       SpecialNewProperty::FIELD_LANG => 'en',
+                                       SpecialNewProperty::FIELD_LABEL => 
'label' . $labelIndex ++,
+                                       SpecialNewProperty::FIELD_DESCRIPTION 
=> '',
+                                       SpecialNewProperty::FIELD_ALIASES => '',
+                                       SpecialNewProperty::FIELD_DATATYPE => 
'url',
                                ],
                        ],
                        'all input is present' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => 'label' . $labelIndex,
-                                       'description' => 'desc',
-                                       'aliases' => 'a1|a2',
-                                       'datatype' => 'url',
+                                       SpecialNewProperty::FIELD_LANG => 'en',
+                                       SpecialNewProperty::FIELD_LABEL => 
'label' . $labelIndex,
+                                       SpecialNewProperty::FIELD_DESCRIPTION 
=> 'desc',
+                                       SpecialNewProperty::FIELD_ALIASES => 
'a1|a2',
+                                       SpecialNewProperty::FIELD_DATATYPE => 
'url',
                                ],
                        ],
                ];
@@ -154,34 +166,34 @@
                return [
                        'unknown language' => [
                                [
-                                       'lang' => 'some-weird-language',
-                                       'label' => 
'label-that-does-not-exist-1',
-                                       'description' => '',
-                                       'aliases' => '',
-                                       'datatype' => 'string',
+                                       SpecialNewProperty::FIELD_LANG => 
'some-weird-language',
+                                       SpecialNewProperty::FIELD_LABEL => 
'label-that-does-not-exist-1',
+                                       SpecialNewProperty::FIELD_DESCRIPTION 
=> '',
+                                       SpecialNewProperty::FIELD_ALIASES => '',
+                                       SpecialNewProperty::FIELD_DATATYPE => 
'string',
                                ],
                                'language code was not recognized',
                        ],
                        'unknown datatype' => [
                                [
-                                       'lang' => 'en',
-                                       'label' => 
'label-that-does-not-exist-2',
-                                       'description' => '',
-                                       'aliases' => '',
-                                       'datatype' => 'unknown-datatype',
+                                       SpecialNewProperty::FIELD_LANG => 'en',
+                                       SpecialNewProperty::FIELD_LABEL => 
'label-that-does-not-exist-2',
+                                       SpecialNewProperty::FIELD_DESCRIPTION 
=> '',
+                                       SpecialNewProperty::FIELD_ALIASES => '',
+                                       SpecialNewProperty::FIELD_DATATYPE => 
'unknown-datatype',
                                ],
                                'Invalid data type specified',
                        ],
-//                     'bad user token' => [  // TODO Probably should be 
implemented
-//                             [
-//                             ],
-//                             'try again',
-//                     ],
-//                     'all fields are empty' => [  // TODO Probably should be 
implemented
-//                             [
-//                             ],
-//                             '???'
-//                     ],
+                       'all fingerprint fields are empty' => [
+                               [
+                                       SpecialNewProperty::FIELD_LANG => 'en',
+                                       SpecialNewProperty::FIELD_LABEL => '',
+                                       SpecialNewProperty::FIELD_DESCRIPTION 
=> '',
+                                       SpecialNewProperty::FIELD_ALIASES => '',
+                                       SpecialNewProperty::FIELD_DATATYPE => 
'string',
+                               ],
+                               'you need to fill'
+                       ],
                ];
        }
 
@@ -205,29 +217,29 @@
                $this->assertInstanceOf( Property::class, $entity );
                /** @var Property $entity */
 
-               $language = $form['lang'];
-               if ( $form['label'] !== '' ) {
+               $language = $form[SpecialNewProperty::FIELD_LANG];
+               if ( $form[SpecialNewProperty::FIELD_LABEL] !== '' ) {
                        $this->assertSame(
-                               $form['label'],
+                               $form[SpecialNewProperty::FIELD_LABEL],
                                $entity->getLabels()->getByLanguage( $language 
)->getText()
                        );
                }
 
-               if ( $form['description'] !== '' ) {
+               if ( $form[SpecialNewProperty::FIELD_DESCRIPTION] !== '' ) {
                        $this->assertSame(
-                               $form['description'],
+                               $form[SpecialNewProperty::FIELD_DESCRIPTION],
                                $entity->getDescriptions()->getByLanguage( 
$language )->getText()
                        );
                }
 
-               if ( $form['aliases'] !== '' ) {
+               if ( $form[SpecialNewProperty::FIELD_ALIASES] !== '' ) {
                        $this->assertArrayEquals(
-                               explode( '|', $form['aliases'] ),
+                               explode( '|', 
$form[SpecialNewProperty::FIELD_ALIASES] ),
                                $entity->getAliasGroups()->getByLanguage( 
$language )->getAliases()
                        );
                }
 
-               $this->assertEquals( $form['datatype'], 
$entity->getDataTypeId() );
+               $this->assertEquals( $form[SpecialNewProperty::FIELD_DATATYPE], 
$entity->getDataTypeId() );
        }
 
 }
diff --git 
a/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialRedirectEntityTest.php
 
b/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialRedirectEntityTest.php
index a8caec8..cc3ca89 100644
--- 
a/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialRedirectEntityTest.php
+++ 
b/extensions/Wikibase/repo/tests/phpunit/includes/Specials/SpecialRedirectEntityTest.php
@@ -243,18 +243,19 @@
                return $permissionChecker;
        }
 
+       /**
+        * @param string $error
+        * @param string $html
+        */
        private function assertError( $error, $html ) {
-               // Match error strings as generated by the ExceptionLocalizer 
mock!
-               if ( !preg_match( '!<p class="error">\(@(.*?)@\)</p>!', $html, 
$m ) ) {
-                       $this->fail( 'Expected error ' . $error . '. No error 
found in page!' );
-               }
-
-               $this->assertEquals( $error, $m[1], 'Expected error ' . $error 
);
+               $this->assertContains( '<p class="error">(@' . $error . 
'@)</p>', $html );
        }
 
+       /**
+        * @param string $html
+        */
        private function assertNoError( $html ) {
-               $pattern = '!<p class="error"!';
-               $this->assertNotRegExp( $pattern, $html, 'Expected no error!' );
+               $this->assertNotContains( 'class="error"', $html );
        }
 
        public function testRedirectRequest() {
diff --git a/vendor/composer/autoload_classmap.php 
b/vendor/composer/autoload_classmap.php
index 0d15d11..a3bd1f7 100644
--- a/vendor/composer/autoload_classmap.php
+++ b/vendor/composer/autoload_classmap.php
@@ -1269,6 +1269,7 @@
     'Wikibase\\Repo\\Search\\Elastic\\Fields\\WikibaseFieldDefinitions' => 
$baseDir . 
'/extensions/Wikibase/repo/includes/Search/Elastic/Fields/WikibaseFieldDefinitions.php',
     'Wikibase\\Repo\\SiteLinkTargetProvider' => $baseDir . 
'/extensions/Wikibase/repo/includes/SiteLinkTargetProvider.php',
     'Wikibase\\Repo\\SnakFactory' => $baseDir . 
'/extensions/Wikibase/repo/includes/SnakFactory.php',
+    'Wikibase\\Repo\\Specials\\HTMLForm\\HTMLTrimmedTextField' => $baseDir . 
'/extensions/Wikibase/repo/includes/Specials/HTMLForm/HTMLTrimmedTextField.php',
     'Wikibase\\Repo\\Specials\\SpecialDispatchStats' => $baseDir . 
'/extensions/Wikibase/repo/includes/Specials/SpecialDispatchStats.php',
     'Wikibase\\Repo\\Specials\\SpecialEntitiesWithoutPage' => $baseDir . 
'/extensions/Wikibase/repo/includes/Specials/SpecialEntitiesWithoutPage.php',
     'Wikibase\\Repo\\Specials\\SpecialEntitiesWithoutPageFactory' => $baseDir 
. 
'/extensions/Wikibase/repo/includes/Specials/SpecialEntitiesWithoutPageFactory.php',
diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json
index c34d364..5bac5b4 100644
--- a/vendor/composer/installed.json
+++ b/vendor/composer/installed.json
@@ -115,19 +115,19 @@
         "source": {
             "type": "git",
             "url": 
"https://github.com/wikimedia/mediawiki-extensions-ArticlePlaceholder.git";,
-            "reference": "98a2db861a58102cdbc52707ff90e9f68899d02b"
+            "reference": "75a2540c6f19488a630a4f871c01912dd26f1c21"
         },
         "dist": {
             "type": "zip",
-            "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-ArticlePlaceholder/zipball/98a2db861a58102cdbc52707ff90e9f68899d02b";,
-            "reference": "98a2db861a58102cdbc52707ff90e9f68899d02b",
+            "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-ArticlePlaceholder/zipball/75a2540c6f19488a630a4f871c01912dd26f1c21";,
+            "reference": "75a2540c6f19488a630a4f871c01912dd26f1c21",
             "shasum": ""
         },
         "require-dev": {
             "jakub-onderka/php-parallel-lint": "0.9.2",
             "mediawiki/mediawiki-codesniffer": "0.7.2"
         },
-        "time": "2016-12-21 15:36:21",
+        "time": "2016-12-23 21:28:55",
         "type": "mediawiki-extension",
         "installation-source": "dist",
         "autoload": {
@@ -1406,12 +1406,12 @@
         "source": {
             "type": "git",
             "url": 
"https://github.com/wikimedia/mediawiki-extensions-Wikibase.git";,
-            "reference": "34c8556f728ae901bd33b9ad31fd669233290e51"
+            "reference": "1a771255cc07b3047e11c591091d642ea83f1abd"
         },
         "dist": {
             "type": "zip",
-            "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/34c8556f728ae901bd33b9ad31fd669233290e51";,
-            "reference": "34c8556f728ae901bd33b9ad31fd669233290e51",
+            "url": 
"https://api.github.com/repos/wikimedia/mediawiki-extensions-Wikibase/zipball/1a771255cc07b3047e11c591091d642ea83f1abd";,
+            "reference": "1a771255cc07b3047e11c591091d642ea83f1abd",
             "shasum": ""
         },
         "require": {
@@ -1444,7 +1444,7 @@
             "jakub-onderka/php-parallel-lint": "0.9.2",
             "mediawiki/mediawiki-codesniffer": "0.4.0|0.5.0"
         },
-        "time": "2016-12-23 09:08:26",
+        "time": "2016-12-23 21:34:43",
         "type": "mediawiki-extension",
         "installation-source": "dist",
         "autoload": {

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Id09acca49bb449004bbabfd71ee221b57492bce0
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Wikidata
Gerrit-Branch: master
Gerrit-Owner: WikidataBuilder <wikidata-servi...@wikimedia.de>

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

Reply via email to