- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
对于初学者,我必须承认我的 PHP 技能很差(已经做了 3 天)
在过去的三天里,我对一个扩展进行了大量修改,该扩展分析了刚刚在 mediawiki 中编辑过的页面。最初的目的是解析页面以查找与数据库中其他页面名称匹配的文本,并自动链接它们。但它只会在“Main”命名空间(命名空间 0)中执行此功能。我修改了它以使用命名空间的加权白名单解析跨命名空间的链接。 (根据白名单中的位置按照先到先得的方式加权。如果白名单是 Development, Rules
,则开发优先于规则。)
我想进一步修改扩展,通过将当前页面的命名空间推到白名单数组的前面来确定当前页面的命名空间的优先级,并确定当前用户组隶属关系,从而进一步修改优先级列表。
如果有人能告诉我至少可以解释前两件事的网站,我将不胜感激。 (到目前为止,mediawiki 社区并没有多大用处)
如果你提供了一个代码示例,请尽量保持它的愚蠢性,我是这个{{耸肩}}的新手(意思是保持代码示例 php 简单......它是可扩展的,所以总是有更好的方法,但是我不熟悉额外的模块。)
有问题的 MediaWiki 版本是 1.21(截至 7-2013 当前稳定)
注意:由于某些原因,代码显示不正确,但没有丢失任何行。
白名单的数组定义为:
$wgLinkTitlesNamespaceWhitelist = array(5000, 5002, 5004, 5006,0);
主文件LinkTitles5000_body,php
if ( !defined( 'MEDIAWIKI' ) ) {
die( 'Not an entry point.' );
}
/*
function dump($var) {
error_log(print_r($var, TRUE) . "\n", 3, 'php://stderr');
};
*/
class LinkTitles_5000 {
static $safeTitle;
<pre><code> /// Setup function, hooks the extension's functions to MediaWiki events.
public static function setup() {
global $wgLinkTitlesParseOnEdit;
global $wgLinkTitlesParseOnRender;
global $wgHooks;
if ( $wgLinkTitlesParseOnEdit ) {
$wgHooks['ArticleSave'][] = 'LinkTitles_5000::onArticleSave';
};
if ( $wgLinkTitlesParseOnRender ) {
$wgHooks['ArticleAfterFetchContent'][] = 'LinkTitles_5000::onArticleAfterFetchContent';
};
$wgHooks['ParserBeforeTidy'][] = 'LinkTitles_5000::removeMagicWord';
}
/// This function is hooked to the ArticleSave event.
/// It will be called whenever a page is about to be
/// saved.
public static function onArticleSave( &$article, &$user, &$text, &$summary,
$minor, $watchthis, $sectionanchor, &$flags, &$status ) {
// To prevent time-consuming parsing of the page whenever
// it is edited and saved, we only parse it if the flag
// 'minor edits' is not set.
return $minor or self::parseContent( $article, $text );
}
/// Called when an ArticleAfterFetchContent event occurs; this requires the
/// $wgLinkTitlesParseOnRender option to be set to 'true'
public static function onArticleAfterFetchContent( &$article, &$content ) {
// The ArticleAfterFetchContent event is triggered whenever page content
// is retrieved from the database, i.e. also for editing etc.
// Therefore we access the global $action variabl to only parse the
// content when the page is viewed.
global $action;
if ( in_array( $action, array('view', 'render', 'purge') ) ) {
self::parseContent( $article, $content );
};
return true;
}
/// This function performs the actual parsing of the content.
static function parseContent( &$article, &$text ) {
// If the page contains the magic word '__NOAUTOLINKS__', do not parse
// the content.
$mw = MagicWord::get('MAG_LINKTITLES_TERMINOLOGY_NOAUTOLINKS');
if ( $mw -> match( $text ) ) {
return true;
}
// Configuration variables need to be defined here as globals.
global $wgLinkTitlesPreferShortTitles;
global $wgLinkTitlesMinimumTitleLength;
global $wgLinkTitlesParseHeadings;
global $wgLinkTitlesBlackList;
global $wgLinkTitlesSkipTemplates;
global $wgLinkTitlesFirstOnly;
global $wgLinkTitlesWordStartOnly;
global $wgLinkTitlesWordEndOnly;
// global $wgLinkTitlesIgnoreCase;
global $wgLinkTitlesSmartMode;
global $wgCapitalLinks;
global $wgLinkTitlesNamespaceWhitelist;
global $wgExtraNamespaces;
( $wgLinkTitlesWordStartOnly ) ? $wordStartDelim = '\b' : $wordStartDelim = '';
( $wgLinkTitlesWordEndOnly ) ? $wordEndDelim = '\b' : $wordEndDelim = '';
// ( $wgLinkTitlesIgnoreCase ) ? $regexModifier = 'i' : $regexModifier = '';
// To prevent adding self-references, we now
// extract the current page's title.
$myTitle = $article->getTitle()->getText();
( $wgLinkTitlesPreferShortTitles ) ? $sort_order = 'ASC' : $sort_order = 'DESC';
( $wgLinkTitlesFirstOnly ) ? $limit = 1 : $limit = -1;
if ( $wgLinkTitlesSkipTemplates )
{
$templatesDelimiter = '{{.+}}';
} else {
$templatesDelimiter = '{{[^|]+?}}|{{.+\|';
};
// Build a regular expression that will capture existing wiki links ("[[...]]"),
// wiki headings ("= ... =", "== ... ==" etc.),
// urls ("http://example.com", "[http://example.com]", "[http://example.com Description]",
// and email addresses ("mail@example.com").
// Since there is a user option to skip headings, we make this part of the expression
// optional. Note that in order to use preg_split(), it is important to have only one
// capturing subpattern (which precludes the use of conditional subpatterns).
( $wgLinkTitlesParseHeadings ) ? $delimiter = '' : $delimiter = '=+.+?=+|';
$urlPattern = '[a-z]+?\:\/\/(?:\S+\.)+\S+(?:\/.*)?';
$delimiter = '/(' . $delimiter . '\[\[.*?\]\]|' . $templatesDelimiter .
'|\[' . $urlPattern . '\s.+?\]|'. $urlPattern .
'(?=\s|$)|(?<=\b)\S+\@(?:\S+\.)+\S+(?=\b))/i';
$black_list = str_replace( '_', ' ',
'("' . implode( '", "',$wgLinkTitlesBlackList ) . '")' );
// Depending on the global setting $wgCapitalLinks, we need
// different callback functions further down.
if ( $wgCapitalLinks ) {
$callBack = "LinkTitles_5000::CallBackCaseInsensitive";
} else {
$callBack = "LinkTitles_5000::CallBackCaseSensitive";
}
# Added to suuport $wgLinkTitlesNamespaceWhitelist
foreach ($wgLinkTitlesNamespaceWhitelist as $LT_namespace){
# Create the link part reflecting NameSpace:
# if namespace is main (0) set to empty string
if ($LT_namespace === 0){
$LT_namespacePart = "";
} else {
$LT_namespacePart = str_replace('_', ' ', $wgExtraNamespaces[(int)$LT_namespace]);
$LT_namespacePart = $LT_namespacePart . ":";
}
# ===
// Build an SQL query and fetch all page titles ordered
// by length from shortest to longest.
// Only titles from 'normal' pages (namespace uid = 0)
// are returned.
$dbr = wfGetDB( DB_SLAVE );
# modified to suuport $wgLinkTitlesNamespaceWhitelist
# 'page_namespace = 0' becomes 'page_namespace = ' . $LT_namespace,
# ===
$res = $dbr->select(
$wgDBprefix . 'page',
'page_title, page_namespace',
array(
'page_namespace = ' . strval($LT_namespace),
'CHAR_LENGTH(page_title) >= ' . $wgLinkTitlesMinimumTitleLength,
'page_title NOT IN ' . $black_list,
),
__METHOD__,
array( 'ORDER BY' => 'CHAR_LENGTH(page_title) ' . $sort_order )
);
// Iterate through the page titles
foreach( $res as $row ) {
// Page titles are stored in the database with spaces
// replaced by underscores. Therefore we now convert
// the underscores back to spaces.
$title = str_replace('_', ' ', $row->page_title);
if ( $title != $myTitle ) {
LinkTitles_5000::$safeTitle = str_replace( '/', '\/', $title );
# add this to skip the function if more than 1 level of sub pages
# Thus if 0 or 1 "\/" is found we continue and process the entry
# if two or more are found we go AARRRRRGGGGHHHHH and skip it!
if (substr_count(LinkTitles_5000::$safeTitle, '\/') >1) {
continue;
}
# adding this to allow for sub pages to be broken into their parts
$LT5000_pos = strpos(LinkTitles_5000::$safeTitle, "\/");
if ($LT5000_pos !== false){
$LT5000_front = substr(LinkTitles_5000::$safeTitle, 0, $LT5000_pos);
$LT5000_back = substr(LinkTitles_5000::$safeTitle, $LT5000_pos+1);
LinkTitles_5000::$safeTitle = substr($title, $LT5000_pos+1);
} else {
$LT5000_back = '';
$LT5000_front = LinkTitles_5000::$safeTitle;;
}
// split the string by [[...]] groups
// credits to inhan @ StackOverflow for suggesting preg_split
// see http://stackoverflow.com/questions/10672286
$arr = preg_split( $delimiter, $text, -1, PREG_SPLIT_DELIM_CAPTURE );
// Depending on the global configuration setting $wgCapitalLinks,
// the title has to be searched for either in a strictly case-sensitive
// way, or in a 'fuzzy' way where the first letter of the title may
// be either case.
if ( $wgCapitalLinks ) {
$searchTerm = '((?i)' . LinkTitles_5000::$safeTitle[0] . '(?-i)' .
substr(LinkTitles_5000::$safeTitle, 1) . ')';
} else {
$searchTerm = '(' . LinkTitles_5000::$safeTitle . ')';
}
$LT5000_out = "[[" . $LT_namespacePart . $title . "|";
for ( $i = 0; $i < count( $arr ); $i+=2 ) {
// even indexes will point to text that is not enclosed by brackets
$arr[$i] = preg_replace( '/(?<![\:\.\@\/\?\&])' .
$wordStartDelim . $searchTerm . $wordEndDelim . '/',
$LT5000_out.'$1]]', $arr[$i], $limit, $count );
if (( $limit >= 0 ) && ( $count > 0 )) {
break;
};
};
$text = implode( '', $arr );
// If smart mode is turned on, the extension will perform a second
// pass on the page and add links with aliases where the case does
// not match.
if ($wgLinkTitlesSmartMode) {
// split the string by [[...]] groups
// credits to inhan @ StackOverflow for suggesting preg_split
// see http://stackoverflow.com/questions/10672286
$arr = preg_split( $delimiter, $text, -1, PREG_SPLIT_DELIM_CAPTURE );
for ( $i = 0; $i < count( $arr ); $i+=2 ) {
// even indexes will point to text that is not enclosed by brackets
$arr[$i] = preg_replace_callback( '/(?<![\:\.\@\/\?\&])' .
$wordStartDelim . '(' . LinkTitles_5000::$safeTitle . ')' .
$wordEndDelim . '/i', $callBack, $arr[$i], $limit, $count );
if (( $limit >= 0 ) && ( $count > 0 )) {
break;
};
};
$text = implode( '', $arr );
}
}; // if $title != $myTitle
}; // foreach $res as $row
}; // foreach $wgLinkTitlesNamespaceWhitelist as $LT_namespace
return true;
}
static function CallBackCaseInsensitive($matches) {
if ($LT5000_pos !== false){
# this if a / was found in the first place
$LT5000_call_out = $LT_namespacePart . $LT5000_front . '/' . $LT5000_back;
} else {
# this if there was no slash
$LT5000_call_out = $LT_namespacePart . $matches[0];
}
if ( strcmp(substr(LinkTitles_5000::$safeTitle, 1), substr($matches[0], 1)) == 0 ) {
return '[[' . $LT5000_call_out . '|]]';
} else {
return '[[' . $LT5000_call_out . '|' . $matches[0] . ']]';
}
}
static function CallBackCaseSensitive($matches) {
if ($LT5000_pos !== false){
# this if a / was found in the first place
$LT5000_call_out = $LT_namespacePart . $LT5000_front . '/' . $LT5000_back;
} else {
# this if there was no slash
$LT5000_call_out = $LT_namespacePart . $matches[0];
}
if ( strcmp(substr(LinkTitles_5000::$safeTitle, 0), substr($matches[0], 0)) == 0 ) {
return '[['. $LT5000_call_out . '|]]';
} else {
return '[[' . $LT5000_call_out . '|' . $matches[0] . ']]';
}
}
static function removeMagicWord( &$parser, &$text ) {
$mw = MagicWord::get('MAG_LINKTITLES_TERMINOLOGY_NOAUTOLINKS');
$mw -> matchAndRemove( $text );
return true;
}
}
</code></pre>
以及模块加载器函数 LinkTitles_5000.php:
if ( !defined( 'MEDIAWIKI' ) ) {
die( 'Not an entry point.' );
}
<pre><code>/*
error_reporting(E_ALL);
ini_set('display_errors', 'On');
ini_set('error_log', 'php://stderr');
$wgMainCacheType = CACHE_NONE;
$wgCacheDirectory = false;
*/
// Configuration variables
$wgLinkTitlesPreferShortTitles = false;
$wgLinkTitlesMinimumTitleLength = 3;
$wgLinkTitlesParseHeadings = false;
$wgLinkTitlesParseOnEdit = true;
$wgLinkTitlesParseOnRender = false;
$wgLinkTitlesSkipTemplates = false;
$wgLinkTitlesBlackList = array();
$wgLinkTitlesFirstOnly = false;
$wgLinkTitlesWordStartOnly = true;
$wgLinkTitlesWordEndOnly = true;
$wgLinkTitlesSmartMode = true;
$wgLinkTitlesNamespaceWhitelist = array();
</code></pre>
<p>$wgExtensionCredits['parserhook'][] = array(
'path' => <strong>FILE</strong>,
'name' => 'LinkTitles_5000',
'author' => '[<a href="https://www.mediawiki.org/wiki/User:Bovender" rel="noreferrer noopener nofollow">https://www.mediawiki.org/wiki/User:Bovender</a> Daniel Kraus]',
'url' => '<a href="https://www.mediawiki.org/wiki/Extension:LinkTitles" rel="noreferrer noopener nofollow">https://www.mediawiki.org/wiki/Extension:LinkTitles</a>',
'version' => '2.2.0',
'descriptionmsg' => 'linktitles-desc'
);</p>
<p>$wgExtensionMessagesFiles['LinkTitles_5000'] = dirname( <strong>FILE</strong> ) . '/LinkTitles_5000.i18n.php';
$wgExtensionMessagesFiles['LinkTitlesMagic_5000'] = dirname( <strong>FILE</strong> ) . '/LinkTitles_5000.i18n.magic.php';
$wgAutoloadClasses['LinkTitles_5000'] = dirname( <strong>FILE</strong> ) . '/LinkTitles_5000.body.php';
$wgExtensionFunctions[] = 'LinkTitles_5000::setup';</p>
<pre><code>// vim: ts=2:sw=2:noet
</code></pre>
最佳答案
很久以前就忘记了这个问题,但事实证明 MediaWiki 有一个功能可以解决这个问题
$myNamespace = $article->getTitle()->getNamespace();
由于文章对象默认传递给 Hook 到 on_save 进程的扩展,这将获取命名空间作为数值。
关于php - 确定 mediawiki 页面中的 namespace (api quest.),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17478630/
我有很多文本文件要上传到运行 MediaWiki 的 wiki。 我什至不知道这是否真的可能,但我想试一试。 每个文本文件的名称将是 wiki 页面的标题。 一个 wiki 页面对应一个文件。 我想从
是否可以使用 SyntaxHighlight GeSHi 在 MediaWiki 中缩进一段代码? ? 比如我希望下面的代码容器与三级列表对齐 * This is plain text of a fi
是否可以在 MediaWiki 中定义可缩进和可折叠的文本或代码块(例如,使用语法高亮格氏格式化)? 我在 Wikipedia 中看到了可折叠的表格和列表,并希望将相同的概念应用于段落和代码片段。 谢
mediawiki 数据库中的哪个表保存页面内容?我想直接访问 mediawiki 的数据库。 最佳答案 您可以查看database layout媒体维基。页面内容位于表格text (在 Postgr
在 MediaWiki 中,您可以使用变量(“Magic Word”),例如 {{PAGENAME}} 或 {{REVISIONDAY}} 获取与当前正在查看的页面相关的特定信息。是否有类似的变量(或
我正在尝试在 wiki 页面上放置一个对象列表,供多个团队标记他们使用的对象。为此,我为每个团队制作了一个带有一列的表格,并希望在这些列中放置一个复选框,以便团队进行标记。 这是我要做的事情的基本思想
有没有MediaWIki我可以在其中提交整个(可能非常大)mediawiki 文本(用于维基百科文章)的 API,这将给我提供与在 wikipedia 上查看的 HTML 文章完全相同的 HTML对于
有没有MediaWIki我可以在其中提交整个(可能非常大)mediawiki 文本(用于维基百科文章)的 API,这将给我提供与在 wikipedia 上查看的 HTML 文章完全相同的 HTML对于
我正在寻找一种方法来防止所有用户在 Mediawiki 中更改他们的密码(因为帐户创建和密码更改由中央 SSO 服务器处理)。 据我所知,Mediawiki 用户可以通过两种方式更改密码:使用登录页面
背景: 我与一个大型协作机构合作,该机构将大量文档集中在一个 wiki 结构中。我已经熟悉 wiki 标记,并且可以创建带有链接等的简单页面。 我合作的 wiki(基于 mediawiki 架构)的一
我正在运行一个 MediaWiki 实例,在撰写本文时我刚刚将其升级到最新版本 1.32.0。这个 wiki 已有近 10 年的历史,并且经历了多次升级。 这是一个法语维基,对于说法语的人来说,令人讨
通过访问 sysop 和数据库访问,我如何更改与用户关联的电子邮件地址? 数据库中的用户表将所有内容都编码为 BLOB。如果我可以解码和编码这些值,大概我可以更新 user.user_email。 最
MediaWiki 支持的侧边栏的默认左侧边栏包含诸如“随机页面”和“当前事件”之类的链接。我想隐藏这些。 除了使用 CSS ( display:none; ) 之外,还有其他方法可以做到这一点吗?
如何设置才能让 MediaWiki 不允许一个电子邮件地址创建多个帐户?垃圾邮件机器人仅使用一封电子邮件创建了 5 个帐户。 我一直在寻找配置设置或扩展,但没能找到。 与此相关的一个问题是使用类似于
我有一个包含不同类型类别的 mediawiki。 如果一个页面有 2 个类别 [[Category:Pear]][[Category:Strawberry]]) 我想添加第三个类别 [[Categor
我们的网络上有自定义协议(protocol),可以在我们的应用程序中打开窗口。我们想在我们的 Wiki 中放置此应用程序的链接,但 mediawiki 似乎唯一识别的协议(protocol)是 htt
我想在 mediawiki 中找到图像的确切 URL 以发送到我的 pinterest 代码中。要查找页面 URL,我使用 urlencode($wgTitle->getFullURL()) 但我无法
我不太确定这在 MediaWiki 中是否可行。 我有几个类别,每个类别包含几页。如果您打开一个类别页面,您将看到该类别的内容,通常由以下三个部分组成: 用户定义的文本(可以使用编辑链接进行编辑)。
我开发了一个应用程序,它在 mediawiki 站点上有一个手册/帮助系统。当用户在应用程序中需要帮助时,他/她可以点击一个按钮,访问维基上相应的帮助页面。这工作得很好,当我在应用程序中添加/更改功能
我刚刚安装了 Mediawiki 并意识到为新手配置它非常复杂。 作为我的第一个条目,我想更改字体颜色: {{ font color | green | green text }} 为此,我从 Wik
我是一名优秀的程序员,十分优秀!