ekino/wordpress-bundle

一个将Symfony与Wordpress连接的Symfony扩展包

安装次数: 41,929

依赖者: 0

建议者: 0

安全性: 0

星标: 311

关注者: 38

分支: 79

公开问题: 37

类型:symfony-bundle

1.2.3 2019-06-21 06:59 UTC

This package is auto-updated.

Last update: 2024-09-21 20:33:20 UTC


README

Build Status SensioLabsInsight

此扩展包用于将一些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() }}