修改URL格式

master
落雨楓 3 weeks ago
parent 63fea40ae4
commit 0179fe81ed

@ -1,4 +1,5 @@
<?php
namespace LatinizeUrl;
use Exception;
@ -7,6 +8,8 @@ use Fukuball\Jieba\Finalseg;
use Fukuball\Jieba\Posseg;
use MediaWiki\MediaWikiServices;
use Overtrue\Pinyin\Pinyin;
use MediaWiki\Status\Status;
use FormatJson;
class ChineseConvertor extends BaseConvertor {
private $config;
@ -15,8 +18,8 @@ class ChineseConvertor extends BaseConvertor {
private static $jiebaLoaded = false;
private static $pinyinParser = null;
public static function standalone(){
if(!self::$standalone){
public static function standalone() {
if (!self::$standalone) {
$service = MediaWikiServices::getInstance();
$config = $service->getMainConfig();
@ -27,31 +30,31 @@ class ChineseConvertor extends BaseConvertor {
return self::$standalone;
}
public static function onGetConvertor($langCode, &$convertor){
if(in_array($langCode, ['zh-cn', 'zh-hans'])){
public static function onGetConvertor($langCode, &$convertor) {
if (in_array($langCode, ['zh-cn', 'zh-hans'])) {
$convertor = self::standalone();
}
return true;
}
public function __construct($config){
public function __construct($config) {
$this->config = $config;
}
public function parse($hanzi){
public function parse($hanzi) {
$method = $this->config['parser'] . 'Parse';
if(is_callable([$this, $method])){
if (is_callable([$this, $method])) {
return call_user_func([$this, $method], $hanzi);
} else {
throw new Exception('Cannot find pinyin parser: ' . $this->config['parser']);
}
}
private function filteJiebaTag($segList){
private function filteJiebaTag($segList) {
$ret = [];
foreach($segList as $seg){
if($seg['tag'] === 'uv' || $seg['tag'] === 'ud'){ //介词
foreach ($segList as $seg) {
if ($seg['tag'] === 'uv' || $seg['tag'] === 'ud') { //介词
$index = count($ret) - 1;
$ret[$index] .= '的';
} else {
@ -64,16 +67,16 @@ class ChineseConvertor extends BaseConvertor {
/**
* 使用php内部方法实现汉字转拼音
*/
public function innerParse($hanzi){
public function innerParse($hanzi) {
$ret = [];
if(!self::$libLoaded){
if (!self::$libLoaded) {
require_once(dirname(__DIR__) . '/vendor/autoload.php');
self::$libLoaded = true;
}
$originalSentenceList = explode('/', $hanzi);
$sentenceList = [];
if(isset($this->config['cutWord']) && $this->config['cutWord']){ //需要分词
if(!self::$jiebaLoaded){
if (isset($this->config['cutWord']) && $this->config['cutWord']) { //需要分词
if (!self::$jiebaLoaded) {
ini_set('memory_limit', '1024M');
Jieba::init(['test' => true]);
Finalseg::init();
@ -82,33 +85,35 @@ class ChineseConvertor extends BaseConvertor {
self::$jiebaLoaded = true;
}
$length = count($originalSentenceList);
for($i = 0; $i < $length; $i ++){
for ($i = 0; $i < $length; $i++) {
$sentence = $originalSentenceList[$i];
$sentenceList[] = $this->filteJiebaTag(Posseg::cut($sentence));
if($i + 1 < $length){
if ($i + 1 < $length) {
$sentenceList[] = '/';
}
}
} else {
$length = count($originalSentenceList);
for($i = 0; $i < $length; $i ++){
for ($i = 0; $i < $length; $i++) {
$sentence = $originalSentenceList[$i];
$sentenceList[] = [$sentence];
if($i + 1 < $length){
if ($i + 1 < $length) {
$sentenceList[] = '/';
}
}
}
//分词后,进行拼音标注
if(!self::$pinyinParser){
if (!self::$pinyinParser) {
self::$pinyinParser = new Pinyin();
}
foreach($sentenceList as $segList){
if(is_array($segList)){
foreach ($sentenceList as $segList) {
if (is_array($segList)) {
$segPinyin = [];
foreach($segList as $seg){
$segPinyin[] = self::$pinyinParser->convert($seg,
PINYIN_NO_TONE | PINYIN_UMLAUT_V | PINYIN_KEEP_PUNCTUATION | PINYIN_KEEP_ENGLISH | PINYIN_KEEP_NUMBER);
foreach ($segList as $seg) {
$segPinyin[] = self::$pinyinParser->convert(
$seg,
PINYIN_NO_TONE | PINYIN_UMLAUT_V | PINYIN_KEEP_PUNCTUATION | PINYIN_KEEP_ENGLISH | PINYIN_KEEP_NUMBER
);
}
$ret[] = $segPinyin;
} else {
@ -121,11 +126,11 @@ class ChineseConvertor extends BaseConvertor {
/**
* 使用hook进行汉字转拼音
*/
public function hookParse($hanzi){
public function hookParse($hanzi) {
$pinyinList = null;
MediaWikiServices::getInstance()->getHookContainer()->run('Pinyin2Hanzi', [$hanzi, &$pinyinList]);
if(!$pinyinList){
if(isset($this->config['fallback'])){
if (!$pinyinList) {
if (isset($this->config['fallback'])) {
return $this->parse($hanzi, $this->config['fallback']);
} else {
throw new Exception('Hook Pinyin2Hanzi never handled.');
@ -133,16 +138,16 @@ class ChineseConvertor extends BaseConvertor {
}
}
private function fallbackOrException($hanzi, $message){
if(isset($this->config['fallback']) && $this->config['fallback'] != false){
private function fallbackOrException($hanzi, $message) {
if (isset($this->config['fallback']) && $this->config['fallback'] != false) {
return $this->parse($hanzi, $this->config['fallback']);
} else {
throw new Exception($message);
}
}
public function apiParse($hanzi){
if(!isset($this->config['url'])){
public function apiParse($hanzi) {
if (!isset($this->config['url'])) {
throw new Exception('LatinizeUrl remote api url not set.');
}
$factory = MediaWikiServices::getInstance()->getHttpRequestFactory();
@ -152,17 +157,17 @@ class ChineseConvertor extends BaseConvertor {
'sentence' => $hanzi
],
], __METHOD__);
$status = \Status::wrap($req->execute());
if(!$status->isOK()){
$status = Status::wrap($req->execute());
if (!$status->isOK()) {
$this->fallbackOrException($hanzi, 'Cannot use LatinizeUrl remote api.');
}
$json = \FormatJson::decode($req->getContent(), true);
if(isset($json["error"])){
$json = FormatJson::decode($req->getContent(), true);
if (isset($json["error"])) {
$this->fallbackOrException($hanzi, 'LatinizeUrl remote api error: ' . $json["error"]);
}
if(!isset($json["status"]) || $json["status"] !== 1){
if (!isset($json["status"]) || $json["status"] !== 1) {
$this->fallbackOrException($hanzi, 'Cannot use LatinizeUrl remote api.');
}
return $json["data"];
}
}
}

@ -1,39 +1,42 @@
<?php
/* Only support api parse yet */
namespace LatinizeUrl;
use Exception;
use MediaWiki\MediaWikiServices;
use MediaWiki\Status\Status;
use FormatJson;
class JapaneseConvertor extends BaseConvertor {
private $config;
private static $standalone = null;
public static function standalone(){
if(!self::$standalone){
public static function standalone() {
if (!self::$standalone) {
$service = MediaWikiServices::getInstance();
$config = $service->getMainConfig();
$wgLatinizeUrlJapaneseConvertorConfig = $config->get('LatinizeUrlJapaneseConvertorConfig');
self::$standalone = new self($wgLatinizeUrlJapaneseConvertorConfig);
}
return self::$standalone;
}
public static function onGetConvertor($langCode, &$convertor){
if(in_array($langCode, ['ja', 'ja-jp'])){
public static function onGetConvertor($langCode, &$convertor) {
if (in_array($langCode, ['ja', 'ja-jp'])) {
$convertor = self::standalone();
}
return true;
}
public function __construct($config){
public function __construct($config) {
$this->config = $config;
}
public function parse($kanji){
if(!isset($this->config['url'])){
public function parse($kanji) {
if (!isset($this->config['url'])) {
throw new Exception('LatinizeUrl remote api url not set.');
}
$factory = MediaWikiServices::getInstance()->getHttpRequestFactory();
@ -43,17 +46,17 @@ class JapaneseConvertor extends BaseConvertor {
'sentence' => $kanji
],
], __METHOD__);
$status = \Status::wrap($req->execute());
if(!$status->isOK()){
$status = Status::wrap($req->execute());
if (!$status->isOK()) {
throw new Exception('Cannot use LatinizeUrl remote api.');
}
$json = \FormatJson::decode($req->getContent(), true);
if(isset($json["error"])){
$json = FormatJson::decode($req->getContent(), true);
if (isset($json["error"])) {
throw new Exception('LatinizeUrl remote api error: ' . $json["error"]);
}
if(!isset($json["status"]) || $json["status"] !== 1){
if (!isset($json["status"]) || $json["status"] !== 1) {
throw new Exception('Cannot use LatinizeUrl remote api.');
}
return $json["data"];
}
}
}

@ -3,11 +3,11 @@
"author": "Hyperzlib",
"url": "https://github.com/Isekai-Project/mediawiki-extension-LatinizeUrl",
"descriptionmsg": "latinizeurl-desc",
"version": "1.0.4",
"version": "1.0.5",
"license-name": "MIT",
"type": "other",
"requires": {
"MediaWiki": ">= 1.39.0"
"MediaWiki": ">= 1.43.0"
},
"ExtensionMessagesFiles": {
"LatinizeUrlAlias": "LatinizeUrl.alias.php"
@ -32,12 +32,15 @@
"Collation::factory": [
"LatinizeUrl\\Hooks::onCollationFactory"
],
"SkinTemplateNavigation::Universal": [
"SidebarBeforeOutput": [
"LatinizeUrl\\Hooks::addToolboxLink"
],
"BeforePageDisplay": [
"LatinizeUrl\\Hooks::onBeforePageDisplay"
],
"BeforeInitialize": [
"LatinizeUrl\\Hooks::onBeforeInitialize"
],
"InitializeParseTitle": [
"LatinizeUrl\\Hooks::onInitializeParseTitle"
],

@ -1,6 +1,7 @@
<?php
namespace LatinizeUrl;
abstract class BaseConvertor {
abstract public function parse($words);
}
}

@ -1,39 +1,46 @@
<?php
namespace LatinizeUrl;
use MediaWiki\Actions\ActionEntryPoint;
use MediaWiki\Linker\LinkTarget;
use Title;
use User;
use MediaWiki\Title\Title;
use MediaWiki\SpecialPage\SpecialPage;
use MediaWiki\MediaWikiServices;
use MediaWiki\Page\ProperPageIdentity;
use MediaWiki\Permissions\Authority;
use MediaWiki\User\UserIdentity;
use TitleValue;
use MediaWiki\Title\TitleValue;
use Wikimedia\Rdbms\DBQueryError;
use MediaWiki\Output\OutputPage;
use MediaWiki\User\User;
use MediaWiki\Request\WebRequest;
use MediaWiki\Context\RequestContext;
use MediaWiki\Installer\DatabaseUpdater;
class Hooks {
public static $allowedNS = [NS_MAIN, NS_TALK];
public static function onLoadExtensionSchemaUpdates($updater){
public static function onLoadExtensionSchemaUpdates(DatabaseUpdater $updater) {
//更新数据库
$dir = dirname(__DIR__) . '/sql';
$dbType = $updater->getDB()->getType();
$dbType = $updater->getDB()->getType();
// For non-MySQL/MariaDB/SQLite DBMSes, use the appropriately named file
if($dbType == 'mysql'){
$filename = 'mysql.sql';
} elseif($dbType == 'sqlite'){
$filename = 'sqlite.sql';
if ($dbType == 'mysql') {
$updater->addExtensionTable('url_slug', "{$dir}/mysql.sql");
} elseif ($dbType == 'sqlite') {
$updater->addExtensionTable('url_slug', "{$dir}/sqlite.sql");
} else {
throw new \Exception('Database type not currently supported');
}
$updater->addExtensionTable('url_slug', "{$dir}/{$filename}");
//更新文件patch
global $IP;
$patcher = new Patcher($IP . '/includes/MediaWiki.php', 'LatinizeUrl', Utils::getVersion());
$patcher->patchInitializeParseTitleHook();
$patcher->save();
$patcher = new Patcher($IP . '/includes/actions/ActionEntryPoint.php', 'LatinizeUrl', Utils::getVersion());
$patcher->patchInitializeParseTitleHook();
$patcher->save();
}
/* 将拼音映射转换为原标题 */
@ -43,45 +50,62 @@ class Hooks {
$config = $service->getMainConfig();
$wgLatinizeUrlForceRedirect = $config->get('LatinizeUrlForceRedirect');
if(in_array($title->getNamespace(), self::$allowedNS)){
$realTitle = Utils::getTitleBySlugUrl($title, $title->getNamespace());
if($realTitle){
$slugText = $title->getText();
if (in_array($title->getNamespace(), self::$allowedNS)) {
$realTitle = Utils::getTitleBySlugUrl($slugText, $title->getNamespace());
if ($realTitle) {
$title = $realTitle;
$request->setVal('title', $title->getPrefixedDBkey());
} elseif($wgLatinizeUrlForceRedirect
&& !($request->getVal('action') && $request->getVal('action') != 'view')
&& !$request->getVal('veaction')
&& !defined('MW_API')
&& in_array($title->getNamespace(), self::$allowedNS)) { //把原标题页面重定向到拼音页面
$slug = Utils::getSlugUrlByTitle($title);
if($slug) $title = Title::newFromText($slug, $title->getNamespace());
if (
$wgLatinizeUrlForceRedirect
&& !($request->getVal('action') && $request->getVal('action') != 'view')
&& !$request->getVal('veaction')
&& !defined('MW_API')
&& in_array($title->getNamespace(), self::$allowedNS)
) { //把原标题页面重定向到拼音页面
$absoluteSlug = Utils::getSlugUrlByTitle($title);
$slugText = str_replace(' ', '_', $slugText);
$absoluteSlug = str_replace(' ', '_', $absoluteSlug);
if ($slugText !== $absoluteSlug) {
$title = Title::newFromText($absoluteSlug, $title->getNamespace());
}
}
}
}
}
public static function onGetArticleUrl(\Title &$title, &$url, $query){
public static function onBeforeInitialize(Title &$title, $unused, OutputPage $output, User $user, WebRequest $request, ActionEntryPoint $entryPoint) {
}
public static function onGetArticleUrl(Title &$title, &$url, $query) {
try {
if(in_array($title->getNamespace(), self::$allowedNS) && Utils::titleSlugExists($title)){
$slug = Title::newFromText(Utils::getSlugUrlByTitle($title), $title->getNamespace());
if ($slug) {
$slugEncoded = Utils::encodeUriComponent($slug->getPrefixedText());
$titleEncoded = Utils::encodeUriComponent($title->getPrefixedText());
$url = str_replace($titleEncoded, $slugEncoded, $url);
}
if (in_array($title->getNamespace(), self::$allowedNS) && Utils::titleSlugExists($title)) {
$slugText = Utils::getSlugUrlByTitle($title);
if (!$slugText) return;
$slugTitle = Title::newFromText($slugText, $title->getNamespace());
if (!$slugTitle) return;
$slugEncoded = Utils::encodeUriComponent($slugTitle->getPrefixedText());
$titleEncoded = Utils::encodeUriComponent($title->getPrefixedText());
$url = str_replace($titleEncoded, $slugEncoded, $url);
}
} catch(DBQueryError $ex){
} catch (DBQueryError $ex) {
}
}
public static function onPageDeleteComplete(ProperPageIdentity $page, Authority $deleter, $reason, $pageID, $deletedRev, $logEntry, $archivedRevisionCount) {
$title = TitleValue::newFromPage( $page );
if(in_array($title->getNamespace(), self::$allowedNS)){ //不是普通页面就跳过
$title = TitleValue::newFromPage($page);
if (in_array($title->getNamespace(), self::$allowedNS)) { //不是普通页面就跳过
Utils::removeTitleSlugMap($title->getText());
}
}
/**
* @param \WikiPage $wikiPage
* @param \MediaWiki\User\UserIdentity $user
@ -90,15 +114,19 @@ class Hooks {
* @param \MediaWiki\Revision\RevisionRecord $revisionRecord
* @param \MediaWiki\Storage\EditResult $editResult
*/
public static function onPageSaveComplete(&$wikiPage, $user, $summary, $flags, $revisionRecord, $editResult){
if(!in_array($wikiPage->getTitle()->getNamespace(), self::$allowedNS)){ //不是普通页面就跳过
public static function onPageSaveComplete(&$wikiPage, $user, $summary, $flags, $revisionRecord, $editResult) {
if (!in_array($wikiPage->getTitle()->getNamespace(), self::$allowedNS)) { //不是普通页面就跳过
return;
}
if ($flags & EDIT_NEW) {
$title = $wikiPage->getTitle();
$parsedData = Utils::parseTitleToAscii($title, $title->getPageLanguage());
Utils::addTitleSlugMap($title->getText(), $parsedData['slug'], $parsedData['latinize']);
if ($parsedData) {
Utils::addTitleSlugMap($title->getText(), $parsedData['slug'], $parsedData['latinize']);
}
}
}
@ -107,24 +135,23 @@ class Hooks {
return;
}
$title = MediaWikiServices::getInstance()->getTitleFactory()->newFromLinkTarget($new);
try {
$parsedData = Utils::parseTitleToAscii($title, $title->getPageLanguage());
Utils::addTitleSlugMap($title->getText(), $parsedData['slug'], $parsedData['latinize']);
} catch (\Exception $e) {
$parsedData = Utils::parseTitleToAscii($title, $title->getPageLanguage());
if ($parsedData) {
Utils::addTitleSlugMap($title->getText(), $parsedData['slug'], $parsedData['latinize']);
}
}
public static function onApiBeforeMain(\ApiBase &$processor){
public static function onApiBeforeMain(\ApiBase &$processor) {
$request = $processor->getRequest();
$titles = $request->getVal('titles');
if($titles){
if ($titles) {
$titles = explode('|', $titles);
foreach($titles as $id => $title){
foreach ($titles as $id => $title) {
$title = Title::newFromText($title);
$realTitle = Utils::getTitleBySlugUrl($title, $title->getNamespace());
if($realTitle){
if ($realTitle) {
$titles[$id] = $realTitle->getPrefixedText();
}
}
@ -132,33 +159,33 @@ class Hooks {
}
}
public static function addToolboxLink(\Skin $skin, array &$links){
public static function addToolboxLink(\Skin $skin, array &$links) {
$service = MediaWikiServices::getInstance();
$user = $skin->getContext()->getUser();
$title = $skin->getRelevantTitle();
if(in_array($title->getNamespace(), self::$allowedNS)){
if($service->getPermissionManager()->userHasRight($user, 'delete') || Utils::hasUserEditedPage($title, $user)){
$links['page-secondary']['custom-url'] = [
if (in_array($title->getNamespace(), self::$allowedNS)) {
if ($service->getPermissionManager()->userHasRight($user, 'delete') || Utils::hasUserEditedPage($title, $user)) {
$links['TOOLBOX']['custom-url'] = [
'class' => false,
'text' => wfMessage('latinizeurl-customurl')->text(),
'href' => \SpecialPage::getTitleFor('CustomUrl', $title->getPrefixedDBKey())->getLocalURL(),
'href' => SpecialPage::getTitleFor('CustomUrl', $title->getPrefixedDBKey())->getLocalURL(),
'id' => 'ca-custom-url',
];
}
}
}
public static function onBeforePageDisplay($out){
if($out->getSkin()->getSkinName() == 'timeless'){
public static function onBeforePageDisplay($out) {
if ($out->getSkin()->getSkinName() == 'timeless') {
$out->addModules('ext.latinizeurl.timeless');
}
}
public static function onCollationFactory($collationName, &$collationObject){
if($collationName == 'latinize'){
public static function onCollationFactory($collationName, &$collationObject) {
if ($collationName == 'latinize') {
$collationObject = new LatinizeCollation();
}
return true;
}
}
}

@ -1,4 +1,5 @@
<?php
namespace LatinizeUrl;
use Collation;
@ -7,15 +8,15 @@ use MediaWiki\MediaWikiServices;
class LatinizeCollation extends Collation {
private $cache;
public function __construct(){
public function __construct() {
$this->cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
}
private function getLatinize($string){
private function getLatinize($string) {
return $this->cache->getWithSetCallback(
$this->cache->makeKey('latinizeConvert', $string),
$this->cache::TTL_MINUTE * 10,
function() use($string){
function () use ($string) {
$convertor = Utils::getConvertor();
$latinize = $convertor->parse($string);
return Utils::wordListToUrl($latinize);
@ -23,29 +24,41 @@ class LatinizeCollation extends Collation {
);
}
public function getSortKey($string){
if(defined('MW_UPDATER')){
public function getSortKey($string) {
if (defined('MW_UPDATER')) {
return $string;
}
$slug = Utils::getSlugByTitle($string);
if($slug){
if ($slug) {
return ucfirst($slug);
} else {
return $this->getLatinize($string);
$latinize = $this->getLatinize($string);
if ($latinize) {
return $latinize;
}
return ucfirst($slug);
}
}
public function getFirstLetter($string){
if(defined('MW_UPDATER')){
public function getFirstLetter($string) {
if (defined('MW_UPDATER')) {
return mb_substr(0, 1, $string, 'UTF-8');
}
$slug = Utils::getSlugByTitle($string);
if($slug){
if ($slug) {
return strtoupper($slug[0]);
} else {
return strtoupper(mb_substr($this->getLatinize($string), 0, 1, 'UTF-8'));
$latinize = $this->getLatinize($string);
if ($latinize) {
return strtoupper(mb_substr($latinize, 0, 1, 'UTF-8'));
}
}
return mb_substr(0, 1, $string, 'UTF-8');
}
}
}

@ -1,4 +1,5 @@
<?php
namespace LatinizeUrl;
class Patcher {
@ -7,16 +8,16 @@ class Patcher {
private $tag;
private $version;
public function __construct($file, $tag, $version){
public function __construct($file, $tag, $version) {
$this->file = $file;
$this->content = file_get_contents($file);
$this->tag = $tag;
$this->version = $version;
}
public function findPatchVersion($name){
public function findPatchVersion($name) {
$regex = '/\/\/ Start ' . $this->tag . ' ([0-9.\-]+) ' . $name . ' Patch\n.*?\/\/ End ' . $this->tag . ' [0-9.\-]+ ' . $name . ' Patch/is';
if(preg_match($regex, $this->content, $matches, PREG_OFFSET_CAPTURE)){
if (preg_match($regex, $this->content, $matches, PREG_OFFSET_CAPTURE)) {
$ret = [];
$ret['start'] = $matches[0][1];
$ret['end'] = $ret['start'] + strlen($matches[0][0]);
@ -27,20 +28,20 @@ class Patcher {
}
}
public function patchInitializeParseTitleHook(){
public function patchInitializeParseTitleHook() {
$patchName = 'InitializeParseTitleHook';
$patchContent = ['MediaWikiServices::getInstance()->getHookContainer()->run( \'InitializeParseTitle\', [ &$ret, $request ] );'];
$patchContent = ['\MediaWiki\MediaWikiServices::getInstance()->getHookContainer()->run( \'InitializeParseTitle\', [ &$ret, $request ] );'];
$patchFinalContent = $this->makePatchContent($patchName, $patchContent, 2);
$currentPatch = $this->findPatchVersion($patchName);
if ($currentPatch) {
if($currentPatch['version'] != $this->version){ //需要更新
if ($currentPatch['version'] != $this->version) { //需要更新
$this->content = substr($this->content, 0, $currentPatch['start'] - 2)
. $patchFinalContent
. substr($this->content, $currentPatch['end'] + 1);
}
} else { //打新的补丁
$regex = '/(?!private function parseTitle\(\) \{(.*?))(?=[\t ]+return \$ret;)/is';
if(preg_match($regex, $this->content, $matches, PREG_OFFSET_CAPTURE)){
$regex = '/(?!protected function parseTitle\(\) \{(.*?))(?=[\t ]+return \$ret;)/is';
if (preg_match($regex, $this->content, $matches, PREG_OFFSET_CAPTURE)) {
$splitPos = $matches[0][1];
$this->content = substr($this->content, 0, $splitPos)
. $patchFinalContent
@ -49,8 +50,8 @@ class Patcher {
}
}
public function makePatchContent($name, $content, $indent = 0, $indentChar = "\t"){
if(!is_array($content)) $content = explode("\n", $content);
public function makePatchContent($name, $content, $indent = 0, $indentChar = "\t") {
if (!is_array($content)) $content = explode("\n", $content);
$lines = array_merge([
'// Start ' . $this->tag . ' ' . $this->version . ' ' . $name . ' Patch',
'// This code is added by ' . $this->tag . ' extension, Do not remove this code until you uninstall ' . $this->tag . ' extension.',
@ -58,14 +59,14 @@ class Patcher {
'// End ' . $this->tag . ' ' . $this->version . ' ' . $name . ' Patch',
]);
$contentText = '';
foreach($lines as $line){
foreach ($lines as $line) {
$contentText .= str_repeat($indentChar, $indent) . $line . "\n";
}
return $contentText;
}
public function save($file = null){
if(!$file) $file = $this->file;
public function save($file = null) {
if (!$file) $file = $this->file;
file_put_contents($file, $this->content);
}
}
}

@ -1,49 +1,48 @@
<?php
namespace LatinizeUrl;
use Article;
use Exception;
use ExtensionRegistry;
use Title;
use User;
use MediaWiki\Title\Title;
use MediaWiki\User\User;
use Language;
use MediaWiki\Extension\AbuseFilter\Consequences\Consequence\Tag;
use MediaWiki\MediaWikiServices;
use StubUserLang;
use MediaWiki\Registration\ExtensionRegistry;
class Utils {
private static $dbr = null;
private static $dbw = null;
private static $cache = null;
public static function initMasterDb(){
if(!self::$dbw){
public static function initMasterDb() {
if (!self::$dbw) {
self::$dbw = MediaWikiServices::getInstance()->getDBLoadBalancer()
->getMaintenanceConnectionRef(DB_PRIMARY);
}
}
public static function initReplicaDb(){
if(!self::$dbr){
public static function initReplicaDb() {
if (!self::$dbr) {
self::$dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()
->getMaintenanceConnectionRef(DB_REPLICA);
}
}
public static function initCache(){
if(!self::$cache){
public static function initCache() {
if (!self::$cache) {
self::$cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
}
}
public static function slugExists($slug, $excludeUrl = null){
if($excludeUrl){
public static function slugExists($slug, $excludeUrl = null) {
if ($excludeUrl) {
self::initReplicaDb();
$cond = [
'slug' => $slug,
];
$cond['url'] = ['!', self::$dbr->addQuotes($excludeUrl)];
$res = self::$dbr->selectField('url_slug', 'COUNT(*)', $cond, __METHOD__);
return intval($res) > 0;
@ -52,50 +51,67 @@ class Utils {
}
}
public static function slugUrlExists($url){
public static function slugUrlExists($url) {
return self::getTitleTextBySlugUrl($url) !== false;
}
public static function titleSlugExists($title){
public static function titleSlugExists($title) {
return self::getSlugByTitle($title) !== false;
}
public static function getTitleBySlug($slug, $namespace = NS_MAIN){
if($slug instanceof Title){
public static function getTitleBySlug($slug, $namespace = NS_MAIN) {
if ($slug instanceof Title) {
$namespace = $slug->getNamespace();
$slug = $slug->getText();
}
$titleText = self::getTitleTextBySlug($slug);
if($titleText){
if ($titleText) {
return Title::newFromText($titleText, $namespace);
} else {
return false;
}
}
public static function getTitleBySlugUrl($url, $namespace = NS_MAIN){
if($url instanceof Title){
/**
* 从URL中获取标题
* @param Title|string $url
* @param int $namespace
*/
public static function getTitleBySlugUrl($url, $namespace = NS_MAIN) {
if ($url instanceof Title) {
$namespace = $url->getNamespace();
$url = $url->getText();
}
$wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory();
// 新版在URL中加了pageId
if (preg_match('/^(\d+?)~/', $url, $matches)) {
$pageId = intval($matches[1]);
$wikiPage = $wikiPageFactory->newFromID($pageId);
if ($wikiPage) {
return $wikiPage->getTitle();
}
}
// 旧版URL
$titleText = self::getTitleTextBySlugUrl($url);
if($titleText){
if ($titleText) {
return Title::newFromText($titleText, $namespace);
} else {
return false;
}
}
public static function getTitleTextBySlug($slug){
public static function getTitleTextBySlug($slug) {
self::initCache();
self::initReplicaDb();
return self::$cache->getWithSetCallback(
self::$cache->makeKey('slug2title', $slug),
self::$cache::TTL_MINUTE * 10,
function() use($slug){
function () use ($slug) {
$res = self::$dbr->select('url_slug', ['title'], [
'slug' => $slug,
], __METHOD__, [
@ -111,20 +127,20 @@ class Utils {
);
}
public static function getTitleTextBySlugUrl($url){
public static function getTitleTextBySlugUrl($url) {
self::initCache();
self::initReplicaDb();
return self::$cache->getWithSetCallback(
self::$cache->makeKey('slugurl2title', $url),
self::$cache::TTL_MINUTE * 10,
function() use($url){
function () use ($url) {
$res = self::$dbr->select('url_slug', ['title'], [
'url' => $url,
], __METHOD__, [
'LIMIT' => 1,
]);
if($res->numRows() > 0){
if ($res->numRows() > 0) {
$data = $res->fetchRow();
return $data['title'];
} else {
@ -134,8 +150,8 @@ class Utils {
);
}
public static function getSlugByTitle($title){
if($title instanceof Title){
public static function getSlugByTitle($title) {
if ($title instanceof Title) {
$title = $title->getText();
}
@ -145,13 +161,13 @@ class Utils {
return self::$cache->getWithSetCallback(
self::$cache->makeKey('title2slug', $title),
self::$cache::TTL_MINUTE * 10,
function() use($title){
function () use ($title) {
$res = self::$dbr->select('url_slug', ['slug'], [
'title' => $title,
], __METHOD__, [
'LIMIT' => 1,
]);
if($res->numRows() > 0){
if ($res->numRows() > 0) {
$data = $res->fetchRow();
return $data['slug'];
} else {
@ -161,26 +177,33 @@ class Utils {
);
}
public static function getSlugUrlByTitle($title){
if($title instanceof Title){
$title = $title->getText();
public static function getSlugUrlByTitleWithoutId($title) {
if ($title instanceof Title) {
$titleText = $title->getText();
} else {
$titleText = $title;
$title = Title::newFromText($title);
}
self::initCache();
self::initReplicaDb();
return self::$cache->getWithSetCallback(
self::$cache->makeKey('title2slugurl', $title),
self::$cache->makeKey('title2slugurlorig', $titleText),
self::$cache::TTL_MINUTE * 10,
function() use($title){
function () use ($title, $titleText) {
$res = self::$dbr->select('url_slug', ['url'], [
'title' => $title,
], __METHOD__, [
'LIMIT' => 1,
]);
if($res->numRows() > 0){
if ($res->numRows() > 0) {
$data = $res->fetchRow();
return $data['url'];
$url = $data['url'];
return $url;
} else {
return false;
}
@ -188,20 +211,50 @@ class Utils {
);
}
public static function getSlugDataByTitle($title){
if($title instanceof Title){
public static function getSlugUrlByTitle($title) {
if (is_string($title)) {
$title = Title::newFromText($title);
}
if (!$title) return false;
return self::$cache->getWithSetCallback(
self::$cache->makeKey('title2slugurl', $title->getText()),
self::$cache::TTL_MINUTE * 10,
function () use ($title) {
$slugUrl = self::getSlugUrlByTitleWithoutId($title);
if (!$slugUrl) return false;
$wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory();
if (!$title->isMainPage()) {
$wikiPage = $wikiPageFactory->newFromTitle($title);
if ($wikiPage) {
$pageId = $wikiPage->getId();
$slugUrl = "{$pageId}~" . $slugUrl;
}
}
return $slugUrl;
}
);
}
public static function getSlugDataByTitle($title) {
if ($title instanceof Title) {
$title = $title->getText();
}
self::initCache();
self::initReplicaDb();
$res = self::$dbr->select('url_slug', '*', [
'title' => $title,
], __METHOD__, [
'LIMIT' => 1,
]);
if($res->numRows() > 0){
if ($res->numRows() > 0) {
$data = $res->fetchRow();
return $data;
} else {
@ -209,15 +262,15 @@ class Utils {
}
}
public static function addTitleSlugMap($title, $slug, $latinize = [], $custom = 0){
if(self::titleSlugExists($title)){
public static function addTitleSlugMap($title, $slug, $latinize = [], $custom = 0) {
if (self::titleSlugExists($title)) {
throw new Exception("Title slug map already exists: " . $title);
}
self::initMasterDb();
$exists = self::slugExists($slug);
if($exists){
if ($exists) {
$url = $slug . '-id';
} else {
$url = $slug;
@ -232,7 +285,7 @@ class Utils {
'latinize' => json_encode($latinize),
), __METHOD__);
$lastId = self::$dbw->insertId();
if($exists){
if ($exists) {
$url = $slug . '-' . $lastId;
self::$dbw->update('url_slug', [
'url' => $url,
@ -243,8 +296,8 @@ class Utils {
return $url;
}
public static function updateTitleSlugMap($title, $slug, $latinize = [], $custom = 0){
if(!self::titleSlugExists($title)){
public static function updateTitleSlugMap($title, $slug, $latinize = [], $custom = 0) {
if (!self::titleSlugExists($title)) {
throw new Exception("Title slug map not exists: " . $title);
}
self::initMasterDb();
@ -253,15 +306,15 @@ class Utils {
$res = self::$dbr->selectRow('url_slug', ['id', 'slug', 'url', 'show_id'], [
'title' => $title,
], __METHOD__);
$mapId = intval($res->id);
$oldSlug = $res->slug;
$oldUrl = $res->url;
if($oldSlug == $slug) return $oldUrl;
if ($oldSlug == $slug) return $oldUrl;
$exists = self::slugExists($slug, $slug);
if($exists){
if ($exists) {
$url = $slug . '-' . strval($mapId);
} else {
$url = $slug;
@ -273,7 +326,7 @@ class Utils {
'show_id' => $exists ? 1 : 0,
'is_custom' => $custom,
];
if(!empty($latinize)){
if (!empty($latinize)) {
$data['latinize'] = json_encode($latinize);
}
@ -288,18 +341,18 @@ class Utils {
return $url;
}
public static function replaceTitleSlugMap($title, $slug, $latinize = [], $custom = 0){
if(self::titleSlugExists($title)){
public static function replaceTitleSlugMap($title, $slug, $latinize = [], $custom = 0) {
if (self::titleSlugExists($title)) {
return self::updateTitleSlugMap($title, $slug, $latinize, $custom);
} else {
return self::addTitleSlugMap($title, $slug, $latinize, $custom);
}
}
public static function removeTitleSlugMap($title){
public static function removeTitleSlugMap($title) {
self::initMasterDb();
if(self::titleSlugExists($title)){
if (self::titleSlugExists($title)) {
$oldData = self::$dbr->selectRow('url_slug', ['slug', 'url'], [
'title' => $title,
], __METHOD__);
@ -307,7 +360,7 @@ class Utils {
self::$dbw->delete('url_slug', [
'title' => $title,
]);
self::$cache->delete(self::$cache->makeKey('slug2title', $oldData->slug));
self::$cache->delete(self::$cache->makeKey('slugurl2title', $oldData->url));
self::$cache->delete(self::$cache->makeKey('title2slug', $title));
@ -318,12 +371,14 @@ class Utils {
}
}
public static function hasUserEditedPage(Title $title, User $user){
if($user->isAnon()) return false;
if(!$title->exists()) return false;
$article = Article::newFromID($title->getArticleID());
if($article == null) return false;
$wikiPage = Article::newFromID($title->getArticleID())->getPage();
public static function hasUserEditedPage(Title $title, User $user) {
if ($user->isAnon()) return false;
if (!$title->exists()) return false;
$wikiPageFactory = MediaWikiServices::getInstance()->getWikiPageFactory();
$wikiPage = $wikiPageFactory->newFromTitle($title);
if (!$wikiPage) return false;
$contributors = $wikiPage->getContributors();
foreach ($contributors as $contributor) {
if ($contributor->equals($user)) {
@ -367,67 +422,77 @@ class Utils {
* @param Language|StubUserLang|string|null $language - 语言
* @return mixed 转换器
*/
public static function parseTitleToAscii(Title $title, Language $language){
$convertor = self::getConvertor($language);
if($title->isSubpage()){
//处理子页面,按照页面拆分
$titlePathList = explode('/', $title->getText());
$titlePathLen = count($titlePathList);
$unparsed = $title->getText();
$baseSlug = false;
for($i = $titlePathLen - 2; $i >= 0; $i --){
$titleSubPath = implode('/', array_slice($titlePathList, 0, $i + 1));
$baseTitle = Title::newFromText($titleSubPath, $title->getNamespace());
$baseSlug = self::getSlugUrlByTitle($baseTitle);
if($baseSlug){
$unparsed = implode('/', array_slice($titlePathList, $i + 1));
break;
public static function parseTitleToAscii(Title $title, Language $language) {
try {
$convertor = self::getConvertor($language);
if ($title->isSubpage()) {
//处理子页面,按照页面拆分
$titlePathList = explode('/', $title->getText());
$titlePathLen = count($titlePathList);
$unparsed = $title->getText();
$baseSlug = false;
for ($i = $titlePathLen - 2; $i >= 0; $i--) {
$titleSubPath = implode('/', array_slice($titlePathList, 0, $i + 1));
$baseTitle = Title::newFromText($titleSubPath, $title->getNamespace());
$baseSlug = self::getSlugUrlByTitle($baseTitle);
if ($baseSlug) {
$unparsed = implode('/', array_slice($titlePathList, $i + 1));
break;
}
}
}
$parsed = $convertor->parse($unparsed);
if($parsed){
$parsedSlug = self::wordListToUrl($parsed);
if($baseSlug){
return [
'slug' => $baseSlug . '/' . $parsedSlug,
'latinize' => array_merge([$baseSlug, '/'], $parsed),
];
$parsed = $convertor->parse($unparsed);
if ($parsed) {
$parsedSlug = self::wordListToUrl($parsed);
if ($baseSlug) {
return [
'slug' => $baseSlug . '/' . $parsedSlug,
'latinize' => array_merge([$baseSlug, '/'], $parsed),
];
} else {
return [
'slug' => $parsedSlug,
'latinize' => $parsed,
];
}
} else {
return false;
}
} else {
$parsed = $convertor->parse($title->getText());
if ($parsed) {
$parsedSlug = self::wordListToUrl($parsed);
return [
'slug' => $parsedSlug,
'latinize' => $parsed,
];
} else {
return false;
}
} else {
return false;
}
} else {
$parsed = $convertor->parse($title->getText());
if($parsed){
$parsedSlug = self::wordListToUrl($parsed);
return [
'slug' => $parsedSlug,
'latinize' => $parsed,
];
} else {
return false;
}
} catch (Exception $ex) {
wfLogWarning('Cannot parse title to ascii: ' . $ex->getMessage());
wfLogWarning($ex->getTraceAsString(), E_USER_ERROR);
return false;
}
}
public static function getVersion(){
public static function getVersion() {
return ExtensionRegistry::getInstance()->getAllThings()['LatinizeUrl']['version'];
}
public static function wordListToUrl($sentenceList){
/**
* @param string[] $sentenceList
* @return string
*/
public static function wordListToUrl($sentenceList) {
$strBuilder = [];
foreach($sentenceList as $pinyinList){
if(is_array($pinyinList)){
foreach ($sentenceList as $pinyinList) {
if (is_array($pinyinList)) {
$segStrBuilder = [];
foreach($pinyinList as $pinyinGroup){
if(is_array($pinyinGroup)){
foreach ($pinyinList as $pinyinGroup) {
if (is_array($pinyinGroup)) {
$groupStrBuilder = [];
foreach($pinyinGroup as $pinyin){
foreach ($pinyinGroup as $pinyin) {
$groupStrBuilder[] = ucfirst($pinyin);
}
$segStrBuilder[] = implode('', $groupStrBuilder);
@ -444,4 +509,4 @@ class Utils {
$str = preg_replace('/-([\x20-\x2f\x3a-\x40\x5b-\x60\x7a-\x7f])-/', '$1', $str);
return $str;
}
}
}

@ -1,51 +1,55 @@
<?php
namespace LatinizeUrl;
use UnlistedSpecialPage;
use Html;
use MediaWiki\MediaWikiServices;
use MediaWiki\SpecialPage\UnlistedSpecialPage;
use MediaWiki\Html\Html;
use MediaWiki\Session\CsrfTokenSet;
use MediaWiki\Tests\Session\CsrfTokenSetTest;
use MediaWiki\Title\Title;
use MediaWiki\Title\TitleArrayFromResult;
use ThrottledError;
class SpecialCustomUrl extends UnlistedSpecialPage {
/**
* @var string
*/
protected $target;
/**
* @var \Title
*/
protected $title;
/** @var string */
protected $slug;
/** @var bool */
protected $isAdmin;
/** @var bool */
protected $userEditedPage;
/** @var NamespaceInfo */
/**
* @var string
*/
protected $target;
/**
* @var Title
*/
protected $title;
/** @var string */
protected $slug;
/** @var bool */
protected $isAdmin;
/** @var bool */
protected $userEditedPage;
/** @var NamespaceInfo */
private $nsInfo;
/** @var LinkBatchFactory */
private $linkBatchFactory;
public function __construct() {
parent::__construct('CustomUrl', '', false);
public function __construct() {
parent::__construct('CustomUrl', '', false);
$service = MediaWikiServices::getInstance();
$this->nsInfo = $service->getNamespaceInfo();
$this->linkBatchFactory = $service->getLinkBatchFactory();
}
$service = MediaWikiServices::getInstance();
$this->nsInfo = $service->getNamespaceInfo();
$this->linkBatchFactory = $service->getLinkBatchFactory();
}
public function doesWrites() {
return true;
}
public function doesWrites() {
return true;
}
public function execute($par) {
public function execute($par) {
$this->useTransactionalTimeLimit();
$this->checkReadOnly();
@ -53,61 +57,67 @@ class SpecialCustomUrl extends UnlistedSpecialPage {
$this->setHeaders();
$this->outputHeader();
$service = MediaWikiServices::getInstance();
$service = MediaWikiServices::getInstance();
$request = $this->getRequest();
$this->target = $par ?? $request->getText('target');
$title = \Title::newFromText($this->target);
$this->target = $par ?? $request->getText('target');
$title = Title::newFromText($this->target);
$this->title = $title;
$this->getSkin()->setRelevantTitle($this->title);
$this->getSkin()->setRelevantTitle($this->title);
$user = $this->getUser();
if (!$title) {
throw new \ErrorPageError( 'notargettitle', 'notargettext' );
return;
throw new \ErrorPageError('notargettitle', 'notargettext');
return;
}
if (!$title->exists()) {
throw new \ErrorPageError( 'nopagetitle', 'nopagetext' );
}
throw new \ErrorPageError('nopagetitle', 'nopagetext');
}
$isAdmin = $service->getPermissionManager()->userHasRight($this->getUser(), 'move');
$this->isAdmin = $isAdmin;
$userEditedPage = Utils::hasUserEditedPage($this->title, $this->getUser());
$this->userEditedPage = $userEditedPage;
$isAdmin = $service->getPermissionManager()->userHasRight($this->getUser(), 'move');
$this->isAdmin = $isAdmin;
$userEditedPage = Utils::hasUserEditedPage($this->title, $this->getUser());
$this->userEditedPage = $userEditedPage;
if (!$this->hasAccess()) {
throw new \PermissionsError('move');
}
if (!$this->hasAccess()){
throw new \PermissionsError('move');
}
$this->slug = $this->getCurrentSlug();
$this->slug = $this->getCurrentSlug();
$csrfTokenObj = $request->getSession()->getToken();
if ($request->getRawVal('action') == 'submit' && $request->wasPosted() && $user->matchEditToken($request->getVal('wpEditToken'))) {
if ($request->getRawVal('action') == 'submit' && $request->wasPosted() && $csrfTokenObj->match($request->getVal('wpEditToken'))) {
$this->doSubmit();
} else {
$this->showForm( [] );
$this->showForm([]);
}
}
protected function hasAccess(){
return $this->isAdmin || $this->userEditedPage;
}
protected function showForm($err, $isPermError = false){
$user = $this->getUser();
$out = $this->getOutput();
$out->setPageTitle($this->msg('latinizeurl-customurl'));
$out->addModuleStyles([
}
protected function hasAccess() {
return $this->isAdmin || $this->userEditedPage;
}
protected function showForm($err, $isPermError = false) {
$user = $this->getUser();
$out = $this->getOutput();
$request = $this->getRequest();
$csrfTokenObj = $request->getSession()->getToken();
$out->setPageTitle($this->msg('latinizeurl-customurl')->text());
$out->addModuleStyles([
'mediawiki.special',
'mediawiki.interface.helpers.styles'
]);
$out->addModules('mediawiki.misc-authed-ooui');
$out->enableOOUI();
$out->enableOOUI();
$fields = [];
$fields[] = new \OOUI\FieldLayout(
$fields[] = new \OOUI\FieldLayout(
new \OOUI\TextInputWidget([
'name' => 'wpSlug',
'id' => 'wpSlug',
@ -115,27 +125,27 @@ class SpecialCustomUrl extends UnlistedSpecialPage {
]),
[
'label' => $this->msg('customurl-url-field-label')->text(),
'help' => $this->msg('customurl-url-field-help')->text(),
'help' => $this->msg('customurl-url-field-help')->text(),
'align' => 'top',
]
);
if ($this->title->hasSubpages()) {
$fields[] = new \OOUI\FieldLayout(
new \OOUI\CheckboxInputWidget([
'name' => 'wpRenameSubpage',
'id' => 'wpRenameSubpage',
'value' => '1',
]),
[
'label' => $this->msg('rename-subpage-checkbox-label')->text(),
'align' => 'inline',
]
);
}
$fields[] = new \OOUI\FieldLayout(
new \OOUI\ButtonInputWidget( [
if ($this->title->hasSubpages()) {
$fields[] = new \OOUI\FieldLayout(
new \OOUI\CheckboxInputWidget([
'name' => 'wpRenameSubpage',
'id' => 'wpRenameSubpage',
'value' => '1',
]),
[
'label' => $this->msg('rename-subpage-checkbox-label')->text(),
'align' => 'inline',
]
);
}
$fields[] = new \OOUI\FieldLayout(
new \OOUI\ButtonInputWidget([
'name' => 'wpConfirm',
'value' => $this->msg('htmlform-submit')->text(),
'label' => $this->msg('htmlform-submit')->text(),
@ -147,11 +157,11 @@ class SpecialCustomUrl extends UnlistedSpecialPage {
]
);
$fieldset = new \OOUI\FieldsetLayout( [
$fieldset = new \OOUI\FieldsetLayout([
'label' => $this->msg('customurl-legend')->text(),
'id' => 'mw-customurl-table',
'items' => $fields,
] );
]);
$form = new \OOUI\FormLayout([
'method' => 'post',
@ -159,14 +169,14 @@ class SpecialCustomUrl extends UnlistedSpecialPage {
'id' => 'customurl',
]);
$form->appendContent(
$form->appendContent(
$fieldset,
new \OOUI\HtmlSnippet(
Html::hidden('wpEditToken', $user->getEditToken())
Html::hidden('wpEditToken', $csrfTokenObj->toString())
)
);
$out->addHTML(
$out->addHTML(
new \OOUI\PanelLayout([
'classes' => ['movepage-wrapper', 'customurl-wrapper'],
'expanded' => false,
@ -176,21 +186,21 @@ class SpecialCustomUrl extends UnlistedSpecialPage {
])
);
if ($this->title->hasSubpages()) {
$this->showSubpages($this->title);
}
}
private function getCurrentSlug(){
$slug = Utils::getSlugUrlByTitle($this->title);
if($slug){
return $slug;
} else {
return $this->title->getText();
}
}
public function doSubmit() {
if ($this->title->hasSubpages()) {
$this->showSubpages($this->title);
}
}
private function getCurrentSlug() {
$slug = Utils::getSlugUrlByTitleWithoutId($this->title);
if ($slug) {
return $slug;
} else {
return $this->title->getText();
}
}
public function doSubmit() {
$user = $this->getUser();
if ($user->pingLimiter('customurl')) {
@ -198,111 +208,118 @@ class SpecialCustomUrl extends UnlistedSpecialPage {
}
$request = $this->getRequest();
$slug = $request->getText('wpSlug');
$renameSubpages = $request->getBool('wpRenameSubpage');
$originSlug = Utils::getSlugByTitle($this->title);
$latinize = [];
if (empty($slug)) { //自动生成
$parsedData = Utils::parseTitleToAscii($this->title, $this->title->getPageLanguage());
$slug = $parsedData['slug'];
$latinize = $parsedData['latinize'];
$custom = 0;
} else {
$slug = str_replace('_', ' ', $slug);
$latinize = [$slug];
$custom = 1;
}
if(Utils::titleSlugExists($this->title)){
$realSlug = Utils::updateTitleSlugMap($this->title->getText(), $slug, $latinize, $custom);
} else {
$realSlug = Utils::addTitleSlugMap($this->title->getText(), $slug, $latinize, $custom);
}
if($renameSubpages){
//更新子页面的slug
$subpages = $this->title->getSubpages();
$originSlugLen = strlen($originSlug);
/** @var \Title $subpage */
foreach($subpages as $subpage){
$originSubpaeSlug = Utils::getSlugByTitle($subpage);
if(strpos($originSubpaeSlug, $originSlug) === 0){
$newSubpageSlug = $realSlug . substr($originSubpaeSlug, $originSlugLen);
Utils::updateTitleSlugMap($subpage->getText(), $newSubpageSlug, [$newSubpageSlug], 1);
}
}
}
$this->slug = $realSlug;
$this->onSuccess();
return true;
}
/**
$slug = $request->getText('wpSlug');
$renameSubpages = $request->getBool('wpRenameSubpage');
$originSlug = Utils::getSlugByTitle($this->title);
$latinize = [];
if (empty($slug)) { //自动生成
$parsedData = Utils::parseTitleToAscii($this->title, $this->title->getPageLanguage());
$slug = $parsedData['slug'];
$latinize = $parsedData['latinize'];
$custom = 0;
} else {
$slug = str_replace('_', ' ', $slug);
$latinize = [$slug];
$custom = 1;
}
if (Utils::titleSlugExists($this->title)) {
$realSlug = Utils::updateTitleSlugMap($this->title->getText(), $slug, $latinize, $custom);
} else {
$realSlug = Utils::addTitleSlugMap($this->title->getText(), $slug, $latinize, $custom);
}
if ($renameSubpages) {
//更新子页面的slug
$subpages = $this->title->getSubpages();
$originSlugLen = strlen($originSlug);
/** @var \Title $subpage */
foreach ($subpages as $subpage) {
$originSubpaeSlug = Utils::getSlugByTitle($subpage);
if (strpos($originSubpaeSlug, $originSlug) === 0) {
$newSubpageSlug = $realSlug . substr($originSubpaeSlug, $originSlugLen);
Utils::updateTitleSlugMap($subpage->getText(), $newSubpageSlug, [$newSubpageSlug], 1);
}
}
}
$this->slug = $realSlug;
$this->onSuccess();
return true;
}
/**
* Show subpages of the page being moved. Section is not shown if both current
* namespace does not support subpages and no talk subpages were found.
*
* @param Title $title Page being moved.
*/
private function showSubpages( $title ) {
$nsHasSubpages = $this->nsInfo->hasSubpages( $title->getNamespace() );
private function showSubpages($title) {
$nsHasSubpages = $this->nsInfo->hasSubpages($title->getNamespace());
$subpages = $title->getSubpages();
$count = $subpages instanceof \TitleArray ? $subpages->count() : 0;
$count = $subpages instanceof TitleArrayFromResult ? $subpages->count() : 0;
$titleIsTalk = $title->isTalkPage();
$subpagesTalk = $title->getTalkPage()->getSubpages();
$countTalk = $subpagesTalk instanceof \TitleArray ? $subpagesTalk->count() : 0;
$talkPage = $title->getTalkPageIfDefined();
if ($talkPage) {
$subpagesTalk = $talkPage->getSubpages();
} else {
$subpagesTalk = [];
}
$countTalk = $subpagesTalk instanceof TitleArrayFromResult ? $subpagesTalk->count() : 0;
$totalCount = $count + $countTalk;
if ( !$nsHasSubpages && $countTalk == 0 ) {
if (!$nsHasSubpages && $countTalk == 0) {
return;
}
$this->getOutput()->wrapWikiMsg(
'== $1 ==',
[ 'movesubpage', ( $titleIsTalk ? $count : $totalCount ) ]
['movesubpage', ($titleIsTalk ? $count : $totalCount)]
);
if ( $nsHasSubpages ) {
$this->showSubpagesList( $subpages, $count, 'movesubpagetext', true );
if ($nsHasSubpages) {
$this->showSubpagesList($subpages, $count, 'movesubpagetext', true);
}
if ( !$titleIsTalk && $countTalk > 0 ) {
$this->showSubpagesList( $subpagesTalk, $countTalk, 'movesubpagetalktext' );
if (!$titleIsTalk && $countTalk > 0) {
$this->showSubpagesList($subpagesTalk, $countTalk, 'movesubpagetalktext');
}
}
private function showSubpagesList( $subpages, $pagecount, $wikiMsg, $noSubpageMsg = false ) {
private function showSubpagesList($subpages, $pagecount, $wikiMsg, $noSubpageMsg = false) {
$out = $this->getOutput();
# No subpages.
if ( $pagecount == 0 && $noSubpageMsg ) {
$out->addWikiMsg( 'movenosubpage' );
if ($pagecount == 0 && $noSubpageMsg) {
$out->addWikiMsg('movenosubpage');
return;
}
$out->addWikiMsg( $wikiMsg, $this->getLanguage()->formatNum( $pagecount ) );
$out->addHTML( "<ul>\n" );
$out->addWikiMsg($wikiMsg, $this->getLanguage()->formatNum($pagecount));
$out->addHTML("<ul>\n");
$linkBatch = $this->linkBatchFactory->newLinkBatch( $subpages );
$linkBatch->setCaller( __METHOD__ );
$linkBatch = $this->linkBatchFactory->newLinkBatch($subpages);
$linkBatch->setCaller(__METHOD__);
$linkBatch->execute();
$linkRenderer = $this->getLinkRenderer();
foreach ( $subpages as $subpage ) {
$link = $linkRenderer->makeLink( $subpage );
$out->addHTML( "<li>$link</li>\n" );
foreach ($subpages as $subpage) {
$link = $linkRenderer->makeLink($subpage);
$out->addHTML("<li>$link</li>\n");
}
$out->addHTML( "</ul>\n" );
$out->addHTML("</ul>\n");
}
public function onSuccess(){
$out = $this->getOutput();
$out->setPageTitle($this->msg('latinizeurl-customurl'));
$out->addWikiMsg('customurl-set-success', $this->title->getText(), str_replace(' ', '_', $this->slug));
}
public function onSuccess() {
$out = $this->getOutput();
$out->setPageTitle($this->msg('latinizeurl-customurl'));
$out->addWikiMsg('customurl-set-success', $this->title->getText(), str_replace(' ', '_', $this->slug));
}
protected function getGroupName() {
return 'pagetools';

Loading…
Cancel
Save