setono/sylius-pickup-point-plugin 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

setono/sylius-pickup-point-plugin

Composer 安装命令:

composer require setono/sylius-pickup-point-plugin

包简介

Pickup point plugin for Sylius

README 文档

README

Latest Version Software License Build Status Code Coverage

Add a pickup-point chooser to your shipping checkout step.

List of pickup points

Supported providers

  • DAO
  • GLS
  • PostNord
  • Fake provider (for development/playing purposes — not enabled in prod)
  • ...or add your own

Compatibility

Plugin Sylius PHP Symfony
2.x ^2.0 >=8.2 ^6.4 || ^7.4
1.x ^1.0 >=8.1 ^5.4 || ^6.0

Migrating from 1.x to 2.x: see UPGRADE.md.

Screenshots

Shop

This is the shipping method step in the checkout process where you can choose a pickup point. The points are loaded asynchronously after the page renders, the nearest one is pre-selected, and the shopper can expand the list to pick another.

Screenshot showing checkout select shipping step with pickup points available

Admin

On the order you can see what pickup point the customer has chosen.

Screenshot showing admin order shipping page with pickup point address

When you edit shipping method you can associate a pickup point provider to that shipping method.

Screenshot showing admin shipping method with some pickup point providers

Installation

Step 1: Install and enable plugin

composer require setono/sylius-pickup-point-plugin

Add the bundle to your config/bundles.php:

<?php
# config/bundles.php

return [
    // ...
    Setono\SyliusPickupPointPlugin\SetonoSyliusPickupPointPlugin::class => ['all' => true],
    // ...
];

Step 2: Import routing

# config/routes/setono_sylius_pickup_point.yaml
setono_sylius_pickup_point:
    resource: "@SetonoSyliusPickupPointPlugin/config/routes.yaml"

If your store has localized URLs disabled, import @SetonoSyliusPickupPointPlugin/config/routes_no_locale.yaml instead.

Step 3: Customize resources

Shipment resource

<?php
// src/Entity/Shipment.php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Setono\SyliusPickupPointPlugin\Model\PickupPointAwareTrait;
use Setono\SyliusPickupPointPlugin\Model\ShipmentInterface;
use Sylius\Component\Core\Model\Shipment as BaseShipment;

#[ORM\Entity]
#[ORM\Table(name: 'sylius_shipment')]
class Shipment extends BaseShipment implements ShipmentInterface
{
    use PickupPointAwareTrait;
}

Shipping method resource

<?php
// src/Entity/ShippingMethod.php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Setono\SyliusPickupPointPlugin\Model\PickupPointProviderAwareTrait;
use Setono\SyliusPickupPointPlugin\Model\ShippingMethodInterface;
use Sylius\Component\Core\Model\ShippingMethod as BaseShippingMethod;

#[ORM\Entity]
#[ORM\Table(name: 'sylius_shipping_method')]
class ShippingMethod extends BaseShippingMethod implements ShippingMethodInterface
{
    use PickupPointProviderAwareTrait;
}

You can read about extending resources here.

Update shipping resources config

# config/packages/_sylius.yaml
sylius_shipping:
    resources:
        shipment:
            classes:
                model: App\Entity\Shipment
        shipping_method:
            classes:
                model: App\Entity\ShippingMethod

Step 4: Configure plugin

Enable desired providers

  • faker will not work in the production environment
  • Each carrier provider requires its corresponding bundle to be installed:
    • daosetono/dao-bundle
    • glssetono/gls-webservice-bundle
    • post_nordsetono/post-nord-bundle

The carrier bundles are listed in this plugin's suggest section — install only the ones you need.

# config/packages/setono_sylius_pickup_point.yaml
setono_sylius_pickup_point:
    providers:
        faker: true
        gls: true
        post_nord: true
        dao: true

Step 5: Database

bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate

Step 6: Validation groups

Add checkout_select_shipping to sylius.form.type.checkout_select_shipping.validation_groups:

# config/packages/_sylius.yaml
parameters:
    sylius.form.type.checkout_select_shipping.validation_groups: ['sylius', 'checkout_select_shipping']

Step 7: Install assets

bin/console assets:install

The plugin's JavaScript and CSS are auto-included on the shop checkout via Twig hooks (sylius_shop.checkout#javascripts / sylius_shop.checkout#stylesheets). The chooser is a framework-free ES module (loaded with <script type="module">) that builds its UI by cloning overridable Twig <template>s, so you can restyle or extend it without forking — see docs/customizing-the-chooser.md.

Step 8: Admin shipping method form

Add the pickupPointProvider field to your admin shipping-method form. With Sylius 2.x's Twig hooks the cleanest path is a project-local hook config that points at a template containing {{ form_row(form.pickupPointProvider) }}, attached to sylius_admin.shipping_method.update.content.form.options (or a form section you already render).

Creating a custom provider

A provider returns the pickup points near an order's address and re-resolves a single point by its id. To add your own carrier, implement Setono\SyliusPickupPointPlugin\Provider\ProviderInterface — or, more simply, extend the abstract Setono\SyliusPickupPointPlugin\Provider\Provider, which already handles the registered code (getCode()), so you only implement two methods.

<?php

declare(strict_types=1);

namespace App\PickupPoint;

use Setono\SyliusPickupPointPlugin\Attribute\AsProvider;
use Setono\SyliusPickupPointPlugin\DTO\Address;
use Setono\SyliusPickupPointPlugin\DTO\PickupPoint;
use Setono\SyliusPickupPointPlugin\Provider\Provider;

#[AsProvider(code: 'acme', name: 'ACME')]
final class AcmeProvider extends Provider
{
    public function __construct(
        private readonly AcmeClient $client, // your carrier's API client
    ) {
    }

    /**
     * @return list<PickupPoint>
     */
    public function findPickupPoints(Address $address): array
    {
        // Every Address field is nullable (the cart may not have a full address yet) — bail when a needed one is missing.
        if (null === $address->postalCode || null === $address->countryCode) {
            return [];
        }

        $points = [];
        foreach ($this->client->search($address->postalCode, $address->countryCode) as $shop) {
            $points[] = $this->transform($shop);
        }

        // Return them ordered by distance from the address: the first one is auto-selected at checkout.
        return $points;
    }

    public function findPickupPoint(string $id, array $metadata = []): ?PickupPoint
    {
        // Called when re-resolving a single point by id; $metadata carries the context you stored (see below).
        $shop = $this->client->get($id, $metadata['country'] ?? null);

        return null === $shop ? null : $this->transform($shop);
    }

    private function transform(object $shop): PickupPoint
    {
        $point = new PickupPoint();
        $point->provider = $this->getCode(); // always stamp the code the provider is registered under
        $point->id = (string) $shop->id;     // unique within this provider
        $point->name = $shop->name;
        $point->address = $shop->street;
        $point->zipCode = $shop->zip;
        $point->city = $shop->city;
        $point->country = $shop->countryCode;
        $point->latitude = (string) $shop->lat;
        $point->longitude = (string) $shop->lng;

        return $point;
    }
}

Register it. With Symfony autoconfiguration on (the default), the #[AsProvider(code, name)] attribute is all you need — the plugin turns it into the setono_sylius_pickup_point.provider tag and the compiler pass does the rest. Without autoconfiguration, tag the service yourself:

# config/services.yaml
services:
    App\PickupPoint\AcmeProvider:
        tags:
            - { name: 'setono_sylius_pickup_point.provider', code: 'acme', name: 'ACME' }

The code is the machine identifier (registry key, the value stored on the shipping method, and the provider part of the pickup-point token); name is the carrier's brand name shown to merchants in the admin form.

Use it. A custom provider is just a registered service — it does not go in the setono_sylius_pickup_point.providers config (that toggle is only for the plugin's bundled optional providers). To put it to work, edit a shipping method in the admin and set its Pickup point provider to yours (ACME); its points are then fetched live at that method's checkout.

Good to know:

  • Providers are called live and lazily — construction is deferred until the provider is first used, and the /pickup-points endpoint wraps each provider in its own try/catch, so a slow or throwing carrier degrades gracefully instead of blocking checkout.
  • The submitted token is the whole PickupPoint, decoded straight back on submit — findPickupPoint() is only for re-resolving a point from a bare id/metadata. Put any extra context your API needs to do that into PickupPoint::$metadata (it round-trips inside the identifier); the well-known country is folded in for you.
  • Build an Address from an order with Address::fromOrder($order) when calling a provider outside checkout.

Play

To see the pickup points list, use the following example address at checkout:

Dannebrogsgade 1
9000 Aalborg
DK
Hämeentie 1
00350 Helsinki
FI
Vasterhaninge 1
137 94 Stockholm
SE

Providers have pickup points in the following countries:

So, to play with all 3 providers at once — use a DK address.

setono/sylius-pickup-point-plugin 适用场景与选型建议

setono/sylius-pickup-point-plugin 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 63.53k 次下载、GitHub Stars 达 20, 最近一次更新时间为 2018 年 09 月 18 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「sylius」 「sylius-plugin」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 setono/sylius-pickup-point-plugin 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 setono/sylius-pickup-point-plugin 我们能提供哪些服务?
定制开发 / 二次开发

基于 setono/sylius-pickup-point-plugin 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 63.53k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 20
  • 点击次数: 1
  • 依赖项目数: 7
  • 推荐数: 0

GitHub 信息

  • Stars: 20
  • Watchers: 1
  • Forks: 20
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2018-09-18