bitbag/vuestorefront-plugin

BitBag VueStorefront 与 Sylius 的桥梁。


README

⚠️ 注意! 当前解决方案已弃用,因为它是为 Vue Storefront v1 创建的。对于 Vue Storefront 2 集成,请查看我们的 GraphQL 基于的集成,可在以下位置找到:

https://github.com/BitBagCommerce/SyliusGraphQLPlugin

https://github.com/vuestorefront-community/sylius

如果您想了解更多关于新集成的内容,请阅读我们的博客 -> https://bitbag.io/blog/introduction-to-vue-storefront-2sylius-integration-technical-aspects

BitBag SyliusVueStorefrontPlugin

Slack Support

在 BitBag,我们坚信开源。然而,我们之所以能够做到这一点,正是因为我们的优秀客户,他们慷慨地与社区分享我们工作的一部分。因此,如果您觉得我们有可能合作,请随时联系我们。您可以在https://bitbag.io/上了解更多关于我们的专业服务、技术和联系信息。

目录

概述

本文档假设您已经熟悉 Vue Storefront 和其技术栈。
如果不是这样,请查看 VSF 文档GitHub 仓库

如果您对 Sylius 新手,请查看 Sylius 文档Sylius-Standard

根据您的偏好,此插件也可以完全替换 VSF API - 如果您选择这样做,您只需要 VSF 前端应用。
Sylius ShopBundle 也将不再需要,因为 Vue Storefront 将成为您新的 ... Storefront。 :)

我们在这里帮助

此开源插件是为了帮助 Sylius 社区而开发的。如果您有任何其他问题,需要安装或配置插件的帮助,或需要任何关于您的 Sylius 项目的帮助 - 请告诉我们!

安装

支持的版本

要求

我们致力于稳定、受支持和最新的包版本。我们建议您也这样做。
请参阅 Vue Storefront 要求

重要提示
请检查存储在 tests/Application 目录中(特别是 config 子目录)的文件
以确保您完全理解下面写的安装步骤。

我们建议您禁用 Sylius ShopBundle,因为您将不再需要它。
有关详细信息,请参阅 Sylius 文档 - 如何禁用 Sylius 商店?

首先,将此插件作为依赖项添加到您的 Sylius 项目中。

$ composer require bitbag/vuestorefront-plugin:v2.1.1

将插件添加到 config/bundles.php 文件中(如果尚未添加)

return [
    ...
    FOS\ElasticaBundle\FOSElasticaBundle::class => ['all' => true],
    BitBag\SyliusVueStorefrontPlugin\SyliusVueStorefrontPlugin::class => ['all' => true],
    Lexik\Bundle\JWTAuthenticationBundle\LexikJWTAuthenticationBundle::class => ['all' => true],
    Gesdinet\JWTRefreshTokenBundle\GesdinetJWTRefreshTokenBundle::class => ['all' => true],

    // Optional, for handling CORS (Cross-Origin Resource Sharing) requests 
    Nelmio\CorsBundle\NelmioCorsBundle::class => ['all' => true],
];

将几个变量添加到您的 .env 文件中

APP_CHANNEL_CODE="<code of Sylius channel you want to use>"

JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem 
JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem
JWT_PASSPHRASE=bitbag

ELASTICSEARCH_HOST=localhost
ELASTICSEARCH_PORT=9200
ELASTICSEARCH_INDEX=vue_storefront_catalog

// Set transport value to "https" and ssl to "true" when using an ssl connection
ELASTICSEARCH_TRANSPORT=http
ELASTICSEARCH_SSL=false
// Leave blank if authentication is not required
ELASTICSEARCH_USERNAME=
ELASTICSEARCH_PASSWORD=

// Optionally, when using Nelmio CORS Bundle
CORS_ALLOW_ORIGIN=^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$

要在 Sylius 项目目录中生成 JWT 公钥和私钥,请运行以下命令

$ mkdir -p config/jwt
$ openssl genpkey -out config/jwt/private.pem -aes256 -algorithm rsa -pkeyopt rsa_keygen_bits:4096
$ openssl pkey -in config/jwt/private.pem -out config/jwt/public.pem -pubout

然后使用在上述命令运行期间输入的密码设置环境变量 JWT_PASSPHRASE 的值。

下一步是将以下行添加到 config/packages/_sylius.yaml 文件的 imports 部分的末尾

- { resource: "@SyliusVueStorefrontPlugin/Resources/config/config.yaml" }

这是为了加载一些插件配置。

现在需要编辑 config/packages/security.yaml 文件。

在文件顶部添加以下行到 parameters 键下

bitbag.vue_storefront.security.regex: "^/vsbridge"

将以下代码添加到 security -> firewalls 键的顶部(顺序非常重要)

        vs_bridge_user_login:
            pattern: "%bitbag.vue_storefront.security.regex%/user/login"
            stateless: true
            anonymous: true
            provider: sylius_shop_user_provider
            json_login:
                provider: sylius_shop_user_provider
                check_path: /vsbridge/user/login
                password_path: password
                success_handler: bitbag_sylius_vue_storefront_plugin.lexik_jwt_authentication.handler.authentication_success
                failure_handler: bitbag_sylius_vue_storefront_plugin.lexik_jwt_authentication.handler.authentication_failure
                require_previous_session: false

        vs_bridge:
            pattern: "%bitbag.vue_storefront.security.regex%"
            stateless: true
            anonymous: true
            provider: sylius_shop_user_provider
            guard:
                provider: sylius_shop_user_provider
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

因此,它应该看起来像这样

    firewalls:
        vs_bridge_user_login:
            pattern: "%bitbag.vue_storefront.security.regex%/user/login"
            stateless: true
            anonymous: true
            provider: sylius_shop_user_provider
            json_login:
                provider: sylius_shop_user_provider
                check_path: /vsbridge/user/login
                password_path: password
                success_handler: bitbag_sylius_vue_storefront_plugin.lexik_jwt_authentication.handler.authentication_success
                failure_handler: bitbag_sylius_vue_storefront_plugin.lexik_jwt_authentication.handler.authentication_failure
                require_previous_session: false

        vs_bridge:
            pattern: "%bitbag.vue_storefront.security.regex%"
            stateless: true
            anonymous: true
            provider: sylius_shop_user_provider
            guard:
                provider: sylius_shop_user_provider
                authenticators:
                    - lexik_jwt_authentication.jwt_token_authenticator

然后,在 security -> access_control 部分下添加一行

- { path: "%bitbag.vue_storefront.security.regex%/user/login", role: IS_AUTHENTICATED_ANONYMOUSLY }

现在,转到您的 Sylius 应用中的 config/routes.yaml 文件,并将以下内容粘贴到其中

sylius_vue_storefront_plugin:
    resource: "@SyliusVueStorefrontPlugin/Resources/config/routing.yaml"

以加载 API 端点的所有路由的配置。

config/packages 目录下创建新文件 gesdinet_jwt_refresh_token.yaml(或按您喜欢的任何名称命名)并粘贴以下内容

gesdinet_jwt_refresh_token:
    firewall: vs_bridge
    token_parameter_name: refreshToken
    user_provider: sylius_shop_user_provider

将您的 config/packages/lexik_jwt_authentication.yaml 文件的内容替换为以下配置

lexik_jwt_authentication:
    secret_key: '%env(resolve:JWT_SECRET_KEY)%'
    public_key: '%env(resolve:JWT_PUBLIC_KEY)%'
    pass_phrase: '%env(JWT_PASSPHRASE)%'

    token_extractors:
        query_parameter:
            enabled: true
            name: token

然后添加

translator: { fallbacks: ["%locale%"] }

config/packages/framework.yaml 中的 framework 键下,之后它应该看起来像这样

framework:
    translator: { fallbacks: ["%locale%"] }
    secret: '%env(APP_SECRET)%'
    form: true
    csrf_protection: true
    templating: { engines: ["twig"] }
    session:
        handler_id: ~

将您的 config/fos_elastica.yaml 的内容设置为以下内容

imports:
    - { resource: "@SyliusVueStorefrontPlugin/Resources/config/indexes/attribute.yaml" }
    - { resource: "@SyliusVueStorefrontPlugin/Resources/config/indexes/category.yaml" }
    - { resource: "@SyliusVueStorefrontPlugin/Resources/config/indexes/product.yaml" }

fos_elastica:
    clients:
        default: { host: '%env(ELASTICSEARCH_HOST)%', port: '%env(ELASTICSEARCH_PORT)%' }

在您的 config/packages/fos_rest.yaml 中的 fos_rest.format_listener.rules 下添加以下规则

- { path: '^/vsbridge/.*', priorities: ['json', 'xml'], fallback_format: json, prefer_extension: true }

例如,文件之后应该看起来像这样

fos_rest:
    exception: true
    view:
        formats:
            json: true
            xml:  true
        empty_content: 204
    format_listener:
        rules:
            - { path: '^/api/.*', priorities: ['json', 'xml'], fallback_format: json, prefer_extension: true }
            - { path: '^/vsbridge/.*', priorities: ['json', 'xml'], fallback_format: json, prefer_extension: true }
            - { path: '^/', stop: true }

转到您的 src/Entity/Order/OrderItem.php 文件,将其修改为从我们的插件扩展 OrderItem 实体。

更改

use Sylius\Component\Core\Model\OrderItem as BaseOrderItem;

use BitBag\SyliusVueStorefrontPlugin\Sylius\Entity\Order\OrderItem as BaseOrderItem;

将此存储库中的 etc/vsf-config/local.json 文件复制到 Vue Storefront 项目目录下的 config/local.json
在此文件中,您只需要将每个 <insert-your-hostname> 的出现替换为您的商店的 URL。
您不需要更改其他任何内容,因为我们已经提供了敏感的默认值,这些默认值在 Vue Storefront v1.12 中已被证明有效。
如果您的配置设置与插件提供的默认设置不同并且您遇到问题,请毫不犹豫地在 GitHub 上创建问题或直接联系我们在 hello@bitbag.io

架构

VueStorefront 以两种方式获取数据 - 静态动态
更新频率较低的数据存储在 Elasticsearch

  1. 产品
  2. 分类(Sylius 税级)
  3. 属性(Sylius 产品选项)

其他所有内容都是通过提供的 API 动态获取的,包括

  • 客户账户(Sylius Customer、ShopUser)
  • 购物车、订单(Sylius Order)
  • 运输方式
  • 支付方式
  • 等等...

Elasticsearch

与 Elasticsearch 相关的一切都包含在 Elastisearch 中,除了 FOS Elastica Bundle 配置,可以在 src/Resources/config/indexes 目录中找到。
为了将 Sylius 中的数据映射到 ES,我们创建了提供对象转换到 ES 索引的 Transformer
索引模式在 Document 目录中存储的文件中描述。

再次强调,目前仅完全支持 Elasticsearch 6
ES 7 的支持正在路上 - 一旦 ruflin/elasticaFOSElasticaBundle 开始支持它,我们也将支持。

在 Sylius 标准应用中使用插件,与 VSF

您一定在 Sylius 实例中有产品、税级等,才能从 VSF 中受益。
因此,我们假设您已经有一个正在运行的商店。
如果情况不是这样,你可能需要在全新克隆的Sylius Standard仓库上运行以下命令。

$ composer install 
$ yarn install
$ yarn build
$ php bin/console doctrine:database:create
$ php bin/console doctrine:schema:update --force
$ php bin/console sylius:fixtures:load

.. 以将所有需要的实体从 fixtures 添加到数据库中。

只有在这种情况下,你才能运行

$ php bin/console fos:elastica:populate

以填充 Elasticsearch 索引,并让插件中的更新器自动实时更新 ES 中的数据。

已知问题

加载 fixtures 期间出现可翻译 trait 错误

在这种情况下,为了能够加载 fixtures,请转到文件vendor/bitbag/vuestorefront-plugin/src/Resources/config/indexes/product.yaml,并注释掉最后一行(即defer:true那一行)。

然后清除缓存,加载 fixtures,之后取消注释该行。

与 taxons(分类)相关的 500 错误

如果你在你的管理面板中看到类似的内容,例如

{
    "result": "Variable \"taxons\" does not exist.",
    "code": 500
}

这意味着你正在使用无效版本的doctrine/inflector包。

要修复它,请将以下块添加到你的composer.json文件中

"conflict": {
    "doctrine/inflector": "^1.4"
},

请确保

"bitbag/vuestorefront-plugin": "v2.1.1"

出现在你的composer.json文件中的require部分,然后运行

$ composer update

扩展插件

扩展请求、命令/查询

扩展现有请求类并添加新属性的最简单方法是继承它们。
由于我们以去规范化方式处理传入请求,所以你不需要在该类中构造函数。你只需

  • 将公共属性添加到类中
  • 重写 getCommand()getQuery() 方法

可选地,你可能想添加约束来验证传入的数据。
我们使用单独的.xml文件来做到这一点,如src/Resources/config/validation目录中所示。

例如,让我们添加地区到优惠券

use BitBag\SyliusVueStorefrontPlugin\Request\Cart\ApplyCouponRequest;

final class ApplyLocalizedCouponRequest extends ApplyCouponRequest
{
    /** @var string */
    pubic $locale;

    public function getCommand(): CommandInterface
    {
        return new ApplyCoupon($this->token, $this->cartId, $this->coupon, $this->locale);
    }
}

以相同的方式,命令需要通过扩展 ApplyCoupon 类来创建。
然后你只需要更改配置文件中的一个参数

bitbag_sylius_vue_storefront_plugin:
    request_classes:
        apply_coupon: \AddLocalizedCouponRequest

扩展处理器

扩展处理器的主要方法是通过装饰它。这使得在处理器前后添加功能变得简单。
请查看以下扩展视图的示例,或遵循Symfony 文档 - 如何装饰服务指南。

但是,如果你想更改处理器的逻辑,你需要重写它。
这可以通过使用相同的服务 ID 注册新处理器来实现。
不要使用新的服务 ID 仅添加它,否则,它将执行两个处理器。

扩展视图

在扩展视图时,需要修改两个地方 - 视图类和视图工厂。

ViewFactories 应像上述处理器一样被装饰。你也可以完全覆盖它们,如果你喜欢这样做。

use BitBag\SyliusVueStorefrontPlugin\Factory\Cart\Totals\TotalsViewFactoryInterface;

class NiceTotalViewFactory implements TotalViewFactoryInterface
{
    private $innerTotalViewFactory;

    public function __construct(TotalsViewFactoryInterface $innerTotalViewFactory)
    {
        $this->innerTotalViewFactory = $innerTotalViewFactory;
    }

    public function create(OrderInterface $order): NiceTotalView
    {
        /** @var NiceTotalView $totalView */
        $totalView = $this->innerTotalViewFactory->createNew();

        $totalView->nicePersonDiscount = $orderInterface->getNiceDiscount();

        return $totalView;
    }
}

你需要在这个 xml(或 yaml)文件中定义此服务

<service class="NiceTotalView" id="app.factory.nice_total_view_factory"
         decorates="bitbag_sylius_vue_storefront_plugin.factory.cart.totals.totals_view_factory">
       <argument type="service" id="app.factory.nice_total_view_factory.inner" />
</service>

并更改配置文件中的视图类

bitbag_sylius_vue_storefront_plugin:
    view_classes:
        totals: \NiceTotalView

关于我们

BitBag是一家提供高质量 电子商务和数字体验软件 的代理机构。我们主要的专业领域包括B2C、B2B和多卖场电子商务的咨询和开发。与Sylius相关的服务范围包括

  • 战略发展领域的咨询
  • 个性化的 无头软件开发
  • 系统维护和长期支持
  • 外包
  • 插件开发
  • 数据迁移

关于Sylius的一些数字

  • 20+专家,包括顾问、UI/UX设计师、Sylius培训的前端和后端开发者
  • 100+项目在Sylius之上交付
  • 20+国家的客户
  • 3+年的Sylius生态系统经验。

如果您需要帮助进行Sylius开发,请直接联系我们,无需犹豫。您可以在此网站填写表格,或发送电子邮件至hello@bitbag.io

社区

对于在线沟通,我们邀请您在Sylius Slack上与我们和其他用户聊天。

Vue Storefront + Sylius 示例

我们创建了一个示例应用程序,展示了此插件的使用。访问vsf.bitbag.shop查看!
Sylius 管理面板可通过syliusvsf.bitbag.shop/admin访问。管理员凭据:sylius : sylius如果您需要了解此插件的概览,请安排与我们的专家进行咨询。

开发者额外资源

为了能够为插件做出贡献,请确保您熟悉以下内容:

此外,您可能还希望更好地了解 VSF:

许可

此插件源代码完全免费,并按MIT许可协议发布。

联系

如果您想联系我们,最佳方式是在我们的网站上填写表格,或发送电子邮件至hello@bitbag.io提出您的问题(们)。我们保证尽快回复!