How to porting a Plugin 3.0.x to 3.n ?

I. Apply new techniques

II. Structure

3.03.n/4
[plugin code]
    ├── Controller
    ├── Entity
    │     ├── [xxx].php
    │     ├── [none]
    │     ├── [none]
    ├── Form
    │     ├── Type
    │     ├── Extension
    ├── Repository
    ├── Resource
    │     ├── doctrine
    │     ├── migration
    │     ├── [none]
    │     ├── locale/message.[ja,en].yml
    │     ├── template
    ├── ServiceProvider
    ├── [Name]Event.php
    ├── config.yml
    ├── event.yml
    ├── [none]
    ├── [none]
    ├── PluginManager.php
[plugin code]
    ├── Controller
    ├── Entity
    │     ├── [xxx].php
    │     ├── [xxx]Trait.php        [new]
    │     ├── [xxx]Extend.php       [new]
    ├── Form
    │     ├── Type
    │     ├── Extension
    ├── Repository
    ├── Resource
    │     ├──                       [removed]
    │     ├──                       [removed]
    │     ├── config/service.yml    [new]
    │     ├── locale/messages.[ja,en].yml [change name]
    │     ├── template
    ├──                             [removed]
    ├── [Name]Event.php
    ├── config.yml
    ├──                             [removed]
    ├── [xxx]QueryCustomizer.php    [new]
    ├── Nav.php                     [new]
    ├── PluginManager.php

III. Controller

3.03.n/4
public function index(Application $app, Request $request)
/**
 * @Method("POST")
 * @Route("/%eccube_admin_route%/plugin/ProductPriority/config", name="product_priority_admin_config")
 * @Template("@ProductPriority/admin/config.twig")
 */
public function index(Request $request)
$app['eccube.plugin.xxx']
public function __construct(xxxRepository $xxxRepository)
{
$this->xxxRepository = $xxxRepository;
}
use: $this->configRepository
$app['form.factory']
$this->formFactory (in AbstractController)
$app['eccube.plugin.xxx']
public function __construct(xxxRepository $xxxRepository)
{
$this->xxxRepository = $xxxRepository;
}
use: $this->xxxRepository
$app['orm.em']
$this->entityManager (in AbstractController)
$app->addSuccess
$this->addSuccess
return $app->render(
    'ProductPriority/Resource/template/admin/config.twig',
    [
        'form' => $form->createView(),
    ]
);
// if you use @Template, then
return [
   'form' => $form->createView(),
];
---
// if you don't use it,
return $this->render(
    '@ProductPriority/admin/config.twig',
    [
        'form' => $form->createView(),
    ]
);
$app->redirect($app->url('xxx'));
$this->redirectToRoute('xxx');

IV. Entity

  1. Entity
3.03.n/4
class Config extends AbstractEntity
use Doctrine\ORM\Mapping as ORM;
/**
 * @ORM\Table(name="plg_sample_payment_config")
 * @ORM\InheritanceType("SINGLE_TABLE")
 * @ORM\DiscriminatorColumn(name="discriminator_type", type="string", length=255)
 * @ORM\HasLifecycleCallbacks()
 * @ORM\Entity(repositoryClass="Plugin\SamplePayment\Repository\ConfigRepository")
 */
class Config extends AbstractEntity
private $id;
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer", options={"unsigned":true})
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;
  1. Trait ```php use Eccube\Annotation\EntityExtension; use Doctrine\ORM\Mapping as ORM; /**
    • @EntityExtension(“Eccube\Entity\Customer”) */ trait CustomerTrait { /**
    • カードの記憶用カラム. *
    • @var string
    • @ORM\Column(type=”smallint”, nullable=true) */ public $sample_payment_cards; } ```
  2. Extend
    use Eccube\Entity\Category;
    use Doctrine\ORM\Mapping as ORM;
    /**
     *
     * @ORM\Entity(repositoryClass="Plugin\ExtendCategory\Repository\ExtendCategoryRepository")
     */
    class ExtendCategory extends Category
    

V. Form

VI. Repository

class ConfigRepository extends AbstractRepository { public function __construct(RegistryInterface $registry) { // please pass the entity to construct parent::__construct($registry, Config::class); } }


## VII. Resource
- By deleting doctrine directory, they change into entities (see IV Entity).
- By deleting migration directory, you can create data in PluginManager, please see below.
- In now, you can define new services/parameter/constant in config/services.yml
- locale/`message`.[ja,en].yml change to locale/`messages`.[ja,en].yml. And you can use locale/messages.[ja,en].php

1. config/services.yml
```yml
# パラメータ定義
parameters:
   sample_payment.xxx: 1

# コンテナ定義
services:
  1. template: You change extend from:
3.03.n/4
default_frame.twig @admin/default_frame.twig

VIII. ServiceProvider

IX. Event

3.03.n/4
// event.yml ```yml admin.product.edit.complete: - [onAdminProductEditComplete, NORMAL] Admin/Order/edit.twig: - [onAdminOrderEditTwig, NORMAL] ``` // [xxx]Event.php ```php /** *例: * - array('eventName' => 'methodName') * - array('eventName' => array('methodName', $priority)) * - array('eventName' => array(array('methodName1', $priority), array('methodName2'))) */ public static function getSubscribedEvents() { return [ EccubeEvents::ADMIN_PRODUCT_EDIT_COMPLETE => 'onAdminProductEditComplete' '@admin/Order/edit.twig' => 'onAdminOrderEditTwig', ]; } ```
[xxx]Event.php ```php public function onProductDetailRender(TemplateEvent $event) { ... $twig = $this->app['twig']; $twigAppend = $twig->getLoader()->getSource('[plugin code]/Resource/template/default/xxx.twig'); $twigSource = $event->getSource(); // Render new template by `str_replace` $twigSource = $this->renderPosition($twigSource, $twigAppend, $this->pluginTag); ... } ``` [xxx]Event.php ```php public function onProductDetailRender(TemplateEvent $event) { // position will define by javascript in product_review.twig file $event->addSnippet('@[plugin code]/default/xxx.twig'); } ``` [plugin code]/Resource/template/default/xxx.twig ```js $(function () { $('#new_area').appendTo($('div.ec-layoutRole__main')); }); ``` ```html
...
```

X. config.yml

3.03.n/4
```yml name: [Name of Plugin] code: [Code of Plugin] version: [Version of Plugin] event: [Handle Class] service: - [Name of Plugin]ServiceProvider orm.path: - /Resource/doctrine const: Constant_ABC: XYZ ``` ```yml name: [Name of Plugin] code: [Code of Plugin] version: [Version of Plugin] ```

XI. QueryCustomizer

Repository class QueryKey
ProductRepository::getQueryBuilderBySearchData() QueryKey::PRODUCT_SEARCH
ProductRepository::getQueryBuilderBySearchDataForAdmin() QueryKey::PRODUCT_SEARCH_ADMIN
ProductRepository::getFavoriteProductQueryBuilderByCustomer QueryKey::PRODUCT_GET_FAVORITE
CustomerRepository::getQueryBuilderBySearchData() QueryKey::CUSTOMER_SEARCH
OrderRepository::getQueryBuilderBySearchData() QueryKey::ORDER_SEARCH
OrderRepository.getQueryBuilderBySearchDataForAdmin() QueryKey::ORDER_SEARCH_ADMIN
OrderRepository::getQueryBuilderByCustomer() QueryKey::ORDER_SEARCH_BY_CUSTOMER
class AdminProductListCustomizer extends OrderByCustomizer
{
    protected function createStatements($params, $queryKey)
    {
        return [new OrderByClause('p.id')];
    }

    public function getQueryKey()
    {
        return QueryKey::PRODUCT_SEARCH_ADMIN;
    }
}

XII. Nav

class SamplePaymentNav implements \Eccube\Common\EccubeNav
{
    public static function getNav()
    {
        return [
            'order' => [
                'children' => [
                    'sample_payment_admin_payment_status' => [
                        'name' => 'sample_payment.admin.nav.payment_list',
                        'url' => 'sample_payment_admin_payment_status',
                    ]
                ]
            ],
        ];
    }
}

XIII. Plugin manager

3.0 3.n/4
public function enable($config, $app)
public function enable($config, ContainerInterface $container)
$entityManager = $app['orm.em'];
$entityManager = $container->get('doctrine.orm.entity_manager');
// repository/service
$app['eccube.plugin.xxxx'];
$container->get([Repository,Service]::class);

XIV. Reference plugin

https://github.com/EC-CUBE/sample-payment-plugin