wikimedia / toolforge-bundle
Symfony 扩展包,提供有用的 Toolforge 功能。
Requires
- ext-intl: *
- doctrine/doctrine-bundle: ^2.2
- krinkle/intuition: ^2.3
- mediawiki/oauthclient: ^2.0
- symfony/cache: ^4.4|^5.0|^7
- symfony/config: ^4.4|^5.0|^7.0
- symfony/console: ^4.4|^5.2|^7
- symfony/dependency-injection: ^4.4|^5.1|^7
- symfony/http-client: ^4.4|^5.0|^7.0
- symfony/http-kernel: ^4.4|^5.0|^7.0
- symfony/process: ^4.4|^5.0|^7.0
- symfony/routing: ^4.4|^5.0|^7.0
- symfony/twig-bridge: ^4.4|^5.0|^7.0
- twig/twig: ^2.4|^3.0
Requires (Dev)
- slevomat/coding-standard: ^8.0
- symfony/phpunit-bridge: ^4.4|^5.1|^7
- dev-master
- 1.7.0
- 1.6.1
- 1.6.0
- 1.5.2
- 1.5.1
- 1.5.0
- 1.4.7
- 1.4.6
- 1.4.5
- 1.4.4
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.1
- 1.3.0
- 1.2.0
- 1.1.1
- 1.1.0
- 1.0.0
- 0.19.0
- 0.18.0
- 0.17.0
- 0.16.0
- 0.15.0
- 0.14.4
- 0.14.3
- 0.14.2
- 0.14.1
- 0.14.0
- 0.13.1
- 0.13.0
- 0.12.1
- 0.12.0
- 0.11.0
- 0.10.0
- 0.9.2
- 0.9.1
- 0.9.0
- 0.8.0
- 0.7.0
- 0.6.0
- 0.5.1
- 0.5.0
- 0.4.0
- 0.3.0
- 0.2.0
- 0.1.0
- dev-upgrade
- dev-cssjanus
This package is auto-updated.
Last update: 2024-09-16 06:02:39 UTC
README
一个 Symfony 4/5 扩展包,提供 Wikimedia Toolforge 中基于网络的工具的一些常用部分。
功能
- 针对 Meta Wiki 的 OAuth 用户身份验证。
- 使用 Intuition 和 jQuery.i18n 库进行国际化。
- 连接和查询 副本数据库 的接口
- PHP 代码检查规则集
- 基本 Wikimedia UI 样式表 (LESS)
待完成
- 通用语言选择器 (ULS)
- 可本地化路由
- OOUI
- CSSJanus
- Addwiki
- 将关键错误报告发送到工具维护者的电子邮件
请将所有问题报告到 Github 或 Phabricator(标记为 community-tech
)。
目录
安装
新项目
要快速启动新项目,首先确保您已安装 Composer 和 Symfony CLI,然后使用 Toolforge 模板
composer create-project wikimedia/toolforge-skeleton ./my-cool-tool
cd my-cool-tool
symfony server:start -d
导航到 http://localhost:8000,您应该能看到您的新工具正在运行。
现有项目
在现有的 Symfony 项目中安装代码
composer require wikimedia/toolforge-bundle
在您的 AppKernel
中注册该扩展包
class AppKernel extends Kernel {
public function registerBundles() {
$bundles = [
new Wikimedia\ToolforgeBundle\ToolforgeBundle(),
];
return $bundles;
}
}
或者 config/bundles.php
Wikimedia\ToolforgeBundle\ToolforgeBundle::class => ['dev' => true],
配置
OAuth
该扩展包创建了三个新的路由 /login
、/oauth_callback
和 /logout
。您的应用程序应该有一个名为 home
的路由。您需要通过在您的 config/routes.yaml
文件中添加以下内容来将这些路由注册到您的应用程序中(或等效的文件)
toolforge:
resource: '@ToolforgeBundle/Resources/config/routes.yaml'
要配置 OAuth,首先在 Meta Wiki 上申请 OAuth 消费者,回调 URL 为 <your-base-url>/oauth_callback
,并将消费者密钥和密钥添加到您的 .env
文件中。然后使用以下内容在 config/packages/toolforge.yaml
中将它们连接到您的应用程序配置中
toolforge:
oauth:
consumer_key: '%env(OAUTH_KEY)%'
consumer_secret: '%env(OAUTH_SECRET)%'
如果您需要验证到不同的维基,也可以将 toolforge.oauth.url
参数设置为 Special:OAuth
的完整 URL。
在相关的 Twig 模板(通常是 base.html.twig
)中添加登录链接,例如
{% if logged_in_user() %}
{{ msg( 'toolforge-logged-in-as', [ logged_in_user().username ] ) }}
<a href="{{ path('toolforge_logout') }}">{{ msg('toolforge-logout') }}</a>
{% else %}
<a href="{{ path('toolforge_login') }}">{{ msg('toolforge-login') }}</a>
{% endif %}
本节下面解释了国际化的部分。OAuth 特定的部分是 logged_in_user()
,这是一个扩展包提供的 Twig 函数,可以提供对当前登录用户的访问。
在开发过程中,有时您可能不想总是登录用户。要强制登录特定用户(但请注意,您仍然需要点击“登录”链接),在您的 config/packages/toolforge.yml
文件中添加 logged_in_user
键,例如
toolforge:
oauth:
logged_in_user: '%env(LOGGED_IN_USER)%'
在控制器中,您可以通过检查来测试用户是否已登录:
$this->get('session')->get('logged_in_user')
登录后的重定向
用户登录后,您可能希望将他们重定向回他们最初尝试查看的页面,而不是 home
路由。为此,首先确保您已注册您的 OAuth 消费者以使用 "允许消费者指定回调 URL..." 选项接受回调 URL。例如,回调的值可以是 https://my-tool.toolforge.org/oauth_callback
。
您的视图中的实现最好通过示例来说明。假设当前用户看到的页面显示了一个登录链接,并且您希望在用户验证后将其重定向回同一页面。您的 Twig 模板中的代码应类似于以下内容:
<a href="{{ path('toolforge_login', {'callback': url('toolforge_oauth_callback', {'redirect': app.request.uri})}) }}">Login</a>
在这里,app.request.uri
评估为用户当前查看的 URL。它作为 oauth_callback
路由的 redirect
提供的,而作为 login
路由的 callback
提供。登录链接的 URL 最终可能类似于以下内容:
https://my-tool.toolforge.org/login?callback=https%3A//my-tool.toolforge.org/oauth_callback%3Fredirect%3Dhttps%253A//my-tool.toolforge.org/my-page%253Ffoo%253Dbar
请注意,用于 redirect
值的 URL 进行了双重编码。在本例中,用户最终将被重定向回 https://my-tool.toolforge.org/my-page?foo=bar
。
国际化(Intuition 和 jQuery.i18n)
国际化处理方式类似于 MediaWiki 中的处理方式,翻译字符串存储在 i18n/
目录中。该包自带一些字符串,所有这些字符串都以 toolforge_
前缀开头;建议尽可能使用这些字符串,因为这可以减少翻译者的工作量。
1. PHP
在 PHP 中,通过以下方式在 config/packages/toolforge.yaml
中设置应用程序的 i18n '域':
toolforge:
intuition:
domain: 'app-name-here'
您可以通过类型提示将(该包的子类)Intuition 注入到您的控制器中,例如:
public function indexAction( Request $request, \Wikimedia\ToolforgeBundle\Service\Intuition $intuition ) { /*...*/ }
以下 Twig 函数和过滤器可用
msg( msg, params )
字符串 获取单个消息。bdi( text )
字符串 使用双向隔离标签包装一个字符串。msg_exists( msg )
布尔 检查是否存在给定消息。msg_if_exists( msg, params )
字符串 如果存在消息,则获取消息,否则返回提供的字符串。lang( lang )
字符串 当前或给定语言的代码。lang_name( lang )
字符串 当前或给定语言的名字。all_langs()
字符串[]i18n/
目录中定义的所有语言的列表(代码 => 名称)。is_rtl()
布尔 当前语言是否为从右到左。git_tag()
字符串 当前 Git 标签,如果没有标签,则是简短哈希。git_branch()
字符串 当前 Git 分支。git_hash()
字符串 当前 Git 哈希。git_hash_short()
字符串 当前 Git 哈希的简短版本。<number>|num_format
int|float 根据当前区域设置格式化数字。<strings>|list_format
字符串[] 将字符串数组格式化为分隔的内联列表。在英语中,这是以逗号分隔的,并在最后一个项目之前使用 "and"。
2. Javascript
在 Javascript 中,您需要做三件事来启用国际化
-
将以下内容添加到您的主 JS 文件(例如
app.js
)或webpack.config.js
:require('../vendor/wikimedia/toolforge-bundle/Resources/assets/toolforge.js');
-
将以下内容添加到您的 HTML 模板(在您的
app.js
之前):<script type="text/javascript" src="https://tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/3.3.1/jquery.min.js"></script> {% include '@toolforge/i18n.html.twig' %}
(如果已通过其他方式加载 jQuery,则可以省略 jQuery。)
-
并从
public/i18n/
链接到您的i18n/
目录,以便可以从 Javascript 加载语言文件。
然后您可以在任何地方使用:$.i18n( 'msg-name', paramOne, paramTwo )
获取 i18n 消息。
副本连接管理器
如果您的工具连接到Toolforge复制的多个数据库,您可以使用ToolforgeBundle的ReplicasClient
服务来确保您的应用程序打开的连接数不超过所需数量。
为了实现这一点,您首先需要将以下内容添加到您的config/packages/doctrine.yaml
doctrine.yaml
doctrine:
dbal:
connections:
toolforge_s1:
host: '%env(REPLICAS_HOST_S1)%'
port: '%env(REPLICAS_PORT_S1)%'
user: '%env(REPLICAS_USERNAME)%'
password: '%env(REPLICAS_PASSWORD)%'
toolforge_s2:
host: '%env(REPLICAS_HOST_S2)%'
port: '%env(REPLICAS_PORT_S2)%'
user: '%env(REPLICAS_USERNAME)%'
password: '%env(REPLICAS_PASSWORD)%'
toolforge_s3:
host: '%env(REPLICAS_HOST_S3)%'
port: '%env(REPLICAS_PORT_S3)%'
user: '%env(REPLICAS_USERNAME)%'
password: '%env(REPLICAS_PASSWORD)%'
toolforge_s4:
host: '%env(REPLICAS_HOST_S4)%'
port: '%env(REPLICAS_PORT_S4)%'
user: '%env(REPLICAS_USERNAME)%'
password: '%env(REPLICAS_PASSWORD)%'
toolforge_s5:
host: '%env(REPLICAS_HOST_S5)%'
port: '%env(REPLICAS_PORT_S5)%'
user: '%env(REPLICAS_USERNAME)%'
password: '%env(REPLICAS_PASSWORD)%'
toolforge_s6:
host: '%env(REPLICAS_HOST_S6)%'
port: '%env(REPLICAS_PORT_S6)%'
user: '%env(REPLICAS_USERNAME)%'
password: '%env(REPLICAS_PASSWORD)%'
toolforge_s7:
host: '%env(REPLICAS_HOST_S7)%'
port: '%env(REPLICAS_PORT_S7)%'
user: '%env(REPLICAS_USERNAME)%'
password: '%env(REPLICAS_PASSWORD)%'
toolforge_s8:
host: '%env(REPLICAS_HOST_S8)%'
port: '%env(REPLICAS_PORT_S8)%'
user: '%env(REPLICAS_USERNAME)%'
password: '%env(REPLICAS_PASSWORD)%'
# If you need to work with toolsdb
toolforge_toolsdb:
host: '%env(TOOLSDB_HOST)%'
port: '%env(TOOLSDB_PORT)%'
user: '%env(TOOLSDB_USERNAME)%'
password: '%env(TOOLSDB_PASSWORD)%'
# If you need to work with a Trove database
toolforge_trove:
host: '%env(TROVE_HOST)%'
port: '%env(TROVE_PORT)%'
user: '%env(TROVE_USERNAME)%'
password: '%env(TROVE_PASSWORD)%'
还需要根据需要将REPLICAS_HOST_
、REPLICAS_USERNAME
、REPLICAS_PASSWORD
和每个REPLICAS_PORT_
添加到.env文件中。如果添加了新的部分(这种情况很少见),则需要相应地更新这些内容。
在生产环境中,REPLICAS_HOST_S1
变量应为s1.web.db.svc.wikimedia.cloud
(或用analytics
替换web
),每个部分类似。生产环境中的REPLICAS_PORT_
变量应为3306
。对于本地环境
,请使用主机变量为127.0.0.1
,以及任何安全的端口范围(例如,s1
使用4711,s2
使用4712等)。
接下来,建立到复制的SSH隧道(仅在本地环境中需要)
php bin/console toolforge:ssh
如果需要,使用--bind-address
标志更改绑定地址。这可能对于Docker安装是必要的。
如果您需要针对tools-db进行操作,请传递--toolsdb
标志,并确保TOOLSBD_
环境变量设置正确。除非您有私有数据库,否则您应该能够使用与REPLICAS_USERNAME
和REPLICAS_PASSWORD
相同的用户名和密码。
如果您需要针对Trove数据库进行操作,请传递--trove
标志,并确保TROVE_
环境变量设置正确。这些凭证与复制品和toolsdb不同。
如果您的Toolforge UNIX shell用户名与本地不同,您需要使用--username
指定它。
要查询复制,注入ReplicasClient
服务,然后调用getConnection()
方法,传递一个有效的数据库,您应该会得到一个Doctrine\DBAL\Connection
对象。例如
# src/Controller/MyController.php
public function myMethod(ReplicasClient $client) {
$frConnection = $client->getConnection('frwiki');
$frUserId = $frConnection->executeQuery("SELECT user_id FROM user LIMIT 1")->fetch();
$ruConnection = $client->getConnection('ruwiki');
$ruUserId = $ruConnection->executeQuery("SELECT user_id FROM user LIMIT 1")->fetch();
# ...
}
在这个例子中,$frConnection
和$ruConnection
实际上指向同一个Connection
实例,因为(在编写本文时)frwiki
和ruwiki
都位于同一部分。ReplicasClient
知道这样做,因为它查询(并缓存)位于https://noc.wikimedia.org的dblists。
PHP 代码检查
您可以通过向项目composer.json
文件的require-dev
部分添加以下内容来使用bundle的phpcs规则
"slevomat/coding-standard": "^4.8"
然后在项目的.phpcs.xml
中用以下内容引用bundle的规则集
<rule ref="./vendor/wikimedia/toolforge-bundle/Resources/phpcs/ruleset.xml" />
Wikimedia UI 样式
您可能希望您的工具遵守Wikimedia设计风格指南。一个基本的LESS样式表,其中包含了一些这些设计元素,在bundle中可用。要使用它,首先安装所需的包
npm install wikimedia-ui-base less less-loader
然后导入它以及bundle的CSS文件(例如,在assets/app.less
文件顶部导入)
@import '../node_modules/wikimedia-ui-base/wikimedia-ui-base.less';
@import '../vendor/wikimedia/toolforge-bundle/Resources/assets/wikimedia-base.less';
部署脚本
该bundle包含一个用于Toolforge的部署脚本,其中应用程序在Kubernetes集群上运行。
它应该添加到您的工具的crontab中,例如每十分钟运行一次
*/10 * * * * /usr/bin/jsub -once -quiet /data/project/<toolname>/<app-dir>/vendor/wikimedia/toolforge-bundle/bin/deploy.sh prod /data/project/<toolname>/<app-dir>/
- 第一个参数是
prod
或dev
,具体取决于您是想运行最高标记版本,还是最新的master分支。 - 第二个是工具顶层目录的路径,通常是工具的主目录或其内部的一个目录(例如
/data/project/<toolname>/app
)。
会话
默认情况下,Symfony 使用 /
作为会话的cookie路径,但在Toolforge上这并不安全,因为这意味着不同的工具可以访问彼此的cookie。此外,Toolforge默认可能会回退到在php.ini中定义的会话过期时间,这仅有24分钟。为了解决这个问题,请在您的 framework.yaml
中设置以下内容
framework:
session:
storage_id: Wikimedia\ToolforgeBundle\Service\NativeSessionStorage
handler_id: 'session.handler.native_file'
save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
cookie_lifetime: 604800 # one week
示例
此包目前在以下项目中使用
许可
GPL 3.0或更高版本。