ekino / wordpress-bundle
一个将Symfony与Wordpress连接的Symfony扩展包
Requires
- php: ^5.4|^7.0
- doctrine/doctrine-bundle: ^1.0
- doctrine/orm: ^2.2
- hautelook/phpass: 0.3
- symfony/framework-bundle: ^2.6|^3.0|^4.0
- symfony/monolog-bundle: ^2.2|^3.0|^4.0
- symfony/security-bundle: ^2.6|^3.0|^4.0
Suggests
README
此扩展包用于将一些Symfony服务引入Wordpress,并使用Symfony操作Wordpress。
以下是一些功能:
- 在Wordpress中使用自定义的Symfony服务
- 使用Symfony操作Wordpress数据库
- 从Wordpress创建自定义的Symfony路由
- 在Wordpress上认证后,在Symfony上也能认证,并拥有正确的用户角色。(需要ekino-wordpress-symfony Wordpress插件)
- 捕获一些Wordpress钩子并由Symfony EventDispatcher分发。(需要ekino-wordpress-symfony Wordpress插件)
安装
本安装教程的想法是让WordPress在以下架构下通过web根渲染
project
|-- wordpress (web root)
|-- symfony (not available over HTTP)
1) 安装Symfony和WordPress
通过解压从https://www.wordpress.org下载的最新WordPress源代码到wordpress
目录中安装你的Wordpress项目。在symfony
目录中使用composer(例如)或新的Symfony Installer工具安装Symfony
$ php composer.phar create-project symfony/framework-standard-edition symfony/
2) 将ekino/wordpress-bundle安装到Symfony项目中
编辑symfony/composer.json
文件以添加此扩展包包
"require": { ... "ekino/wordpress-bundle": "dev-master" },
运行php composer.phar update ekino/wordpress-bundle
然后,将扩展包添加到symfony/app/AppKernel.php
<?php public function registerBundles() { $bundles = array( ... new Ekino\WordpressBundle\EkinoWordpressBundle(), ); ... return $bundles; }
在你的symfony/app/config/routing.yml
中添加WordpressBundle路由文件,在你的自定义路由之后以捕获所有Wordpress路由
... ekino_wordpress: resource: "@EkinoWordpressBundle/Resources/config/routing.xml"
编辑你的配置并在你的app/config.yml
中指定以下选项
ekino_wordpress: globals: # If you have some custom global variables that WordPress needs - wp_global_variable_1 - wp_global_variable_2 table_prefix: "wp_" # If you have a specific Wordpress table prefix wordpress_directory: "%kernel.root_dir%/../../wordpress" load_twig_extension: true # If you want to enable native WordPress functions (ie : get_option() => wp_get_option()) enable_wordpress_listener: false # If you want to disable the WordPress request listener security: firewall_name: "secured_area" # This is the firewall default name login_url: "/wp-login.php" # Absolute URL to the wordpress login page
此外,如果你想使用UserHook
在Symfony上进行认证,你应该将此配置添加到你的symfony/app/security.yml
security: providers: main: entity: { class: Ekino\WordpressBundle\Entity\User, property: login } # Example firewall for an area within a Symfony application protected by a WordPress login firewalls: secured_area: pattern: ^/admin access_denied_handler: ekino.wordpress.security.entry_point entry_point: ekino.wordpress.security.entry_point anonymous: ~ access_control: - { path: ^/admin, roles: ROLE_WP_ADMINISTRATOR }
3) 更新你的WordPress index.php文件以加载Symfony库
<?php use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Debug\Debug; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Retrieves or sets the Symfony Dependency Injection container * * @param ContainerInterface|string $id * * @return mixed */ function symfony($id) { static $container; if ($id instanceof ContainerInterface) { $container = $id; return; } return $container->get($id); } $loader = require_once __DIR__.'/../symfony/var/bootstrap.php.cache'; // Load application kernel require_once __DIR__.'/../symfony/app/AppKernel.php'; $sfKernel = new AppKernel('dev', true); $sfKernel->loadClassCache(); $sfKernel->boot(); // Add Symfony container as a global variable to be used in Wordpress $sfContainer = $sfKernel->getContainer(); if (true === $sfContainer->getParameter('kernel.debug', false)) { Debug::enable(); } symfony($sfContainer); $sfRequest = Request::createFromGlobals(); $sfResponse = $sfKernel->handle($sfRequest); $sfResponse->send(); $sfKernel->terminate($sfRequest, $sfResponse);
4) 在只暴露Symfony的情况下
为了避免一些Wordpress插件的问题,你需要将web/app.php
代码包裹在一个函数中,如下所示
<?php use Symfony\Component\HttpFoundation\Request; // change for app_dev.php function run(){ $loader = require_once __DIR__.'/../var/bootstrap.php.cache'; require_once __DIR__.'/../app/AppKernel.php'; $kernel = new AppKernel('dev', true); $kernel->loadClassCache(); Request::enableHttpMethodParameterOverride(); $request = Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); $kernel->terminate($request, $response); } run();
5) 编辑WordPress根项目目录中的.htaccess文件
放置以下规则
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .? - [L]
# Rewrite all other queries to the front controller.
RewriteRule .? %{ENV:BASE}/index.php [L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
RedirectMatch 302 ^/$ /index.php/
</IfModule>
</IfModule>
现在你可以开始了。
在Symfony中使用
你可以通过调用以下服务在Symfony中调用Wordpress表管理器
所以,在自定义的Symfony控制器中,你可以创建/更新/删除Wordpress数据库中的数据,如下所示
# Here an example that sets user #2 as author for post #1 $postManager = $this->get('ekino.wordpress.manager.post'); $userManager = $this->get('ekino.wordpress.manager.user'); $user = $userManager->find(2); $post = $postManager->find(1); $post->setAuthor($user); $postManager->save($post);
在WordPress中使用
从Symfony容器中调用一个服务
只需使用symfony()
方法并像这样调用你的自定义服务
$service = symfony('my.custom.symfony.service');
覆盖
实体
对于每个Wordpress实体,你都可以覆盖默认的类。为此,只需在你的config.yml
中添加以下配置(对于Post
实体)
ekino_wordpress: services: post: class: MyApp\AppBundle\Entity\Post
为了在创建新实例时避免进一步的问题(例如),请始终使用管理器来创建新实体($container->get('ekino.wordpress.manager.post')->create()
)。
管理器
你也可以使用你自己的管理器。为了自定义它,按照以下方式注册你的服务——应将其标记为私有
ekino_wordpress: services: comment: manager: my_custom_comment_service
现在你可以通过常规命令使用你的管理器了,例如从控制器中:$this->get('ekino.wordpress.manager.comment')
仓储
实现你的自定义仓储类就像这样做
ekino_wordpress: services: comment_meta: repository_class: MyApp\MyBundle\Repository\ORM\CustomCommentMetaRepository
额外
启用跨应用程序I18n支持
如果您已经有一个处理 I18n 的 WordPress 插件,EkinoWordpressBundle 允许在 Symfony 和 WordPress 之间持久化语言切换。要这样做,只需从 WordPress 插件中获取 Cookie 名称,并在配置中提供其名称,如下所示
ekino_wordpress: i18n_cookie_name: pll_language # This value is the one used in "polylang" WP plugin
此外,您可以在 Symfony 中实现自己的跨应用程序语言切换器。例如
<?php namespace Acme\DemoBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; class LanguageController extends Controller { /** * @param Request $request * @param string $locale * * @return RedirectResponse */ public function toggleLocaleAction(Request $request, $locale) { $response = new RedirectResponse($this->generateUrl('homepage')); $response->headers->setCookie(new Cookie($this->getWpCookieName(), $locale, time() + 31536000, '/', $request->getHost())); return $response; } /** * @return string */ protected function getWpCookieName() { return $this->container->getParameter('ekino.wordpress.i18n_cookie_name'); } }
处理受密码保护的帖子
如果您使用受密码保护的帖子并且已经定义了自己的 COOKIEHASH
常量,您可以在 config.yml
文件中使用 cookie_hash
参数提供它。然后您将能够使用 wp_post_password_required
twig 函数,该函数的行为与 post_password_required
WordPress 函数完全相同。
在 Symfony 的 Twig 渲染的路由中显示 WordPress 主题
您可以通过使用此包中可用的以下 Twig 函数,在 Symfony 的 Twig 模板中显示 WordPress 的头部(如果可用的话,还有管理菜单栏),侧边栏和页脚。
{{ wp_get_header() }} {{ wp_get_sidebar() }} <div id="main"> Your Twig code comes here </div> {{ wp_get_footer() }}