Skip to content

Commit

Permalink
Merge pull request #2536 from dpfaffenbauer/attributes-for-pimcore-mo…
Browse files Browse the repository at this point in the history
…dels

[ResourceBundle] auto registration of pimcore models
  • Loading branch information
dpfaffenbauer committed Feb 9, 2024
2 parents c34b3af + 2912bbd commit b335da9
Show file tree
Hide file tree
Showing 14 changed files with 529 additions and 95 deletions.
208 changes: 116 additions & 92 deletions docs/03_Bundles/Resource_Bundle/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,107 +33,131 @@ public function registerBundlesToCollection(BundleCollection $collection)

To create custom entities or extend existing CoreShop Doctrine entities:

1. **Enable Doctrine ORM**:

```yaml
# app/config/config.yml
doctrine:
orm:
mappings:
App:
is_bundle: false
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
```

2. **Create Your Entity**:

```php
# src/Entity/CustomEntity.php
<?php

declare(strict_types=1);

namespace App\Entity;

// Entity implementation
```

3. **Register as a CoreShop Resource**:

```yaml
# app/config/config.yml
core_shop_resource:
resources:
app.custom_entity:
classes:
model: App\Entity\CustomEntity
interface: CoreShop\Component\Resource\Model\ResourceInterface
repository: CoreShop\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository
```

4. **Configure Routes**:

```yaml
# config/routes.yaml
coreshop_admin_custom_entity:
type: coreshop.resources
resource: |
alias: app.custom_entity
# additional routes
```

5. **Configure Serializer**:

```yaml
# app/config/config.yml
jms_serializer:
metadata:
directories:
app:
namespace_prefix: "App\\Entity"
path: "%kernel.project_dir%/config/jms_serializer"
```

```yaml
# config/jms_serializer/CustomEntity.yml
AppBundle\Model\CustomEntity:
exclusion_policy: ALL
xml_root_name: custom_entity
properties:
id:
expose: true
type: integer
groups: [List, Detailed]
name:
expose: true
type: array
groups: [List, Detailed]
```
#### 1. Enable Doctrine ORM

```yaml
# app/config/config.yml
doctrine:
orm:
mappings:
App:
is_bundle: false
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
```

#### 2. Create Your Entity
```php
# src/Entity/CustomEntity.php
<?php

declare(strict_types=1);

namespace App\Entity;

// Entity implementation
```

#### 3. Register as a CoreShop Resource

```yaml
# app/config/config.yml
core_shop_resource:
resources:
app.custom_entity:
classes:
model: App\Entity\CustomEntity
interface: CoreShop\Component\Resource\Model\ResourceInterface
repository: CoreShop\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository
```

#### 4. Configure Routes

```yaml
# config/routes.yaml
coreshop_admin_custom_entity:
type: coreshop.resources
resource: |
alias: app.custom_entity
# additional routes
```

#### Configure Serializer

```yaml
# app/config/config.yml
jms_serializer:
metadata:
directories:
app:
namespace_prefix: "App\\Entity"
path: "%kernel.project_dir%/config/jms_serializer"
```

```yaml
# config/jms_serializer/CustomEntity.yml
AppBundle\Model\CustomEntity:
exclusion_policy: ALL
xml_root_name: custom_entity
properties:
id:
expose: true
type: integer
groups: [List, Detailed]
name:
expose: true
type: array
groups: [List, Detailed]
```

### Adding Custom Pimcore Entities

Similar to Doctrine entities, you can register Pimcore DataObject Classes:

1. **Model Implementation**:
#### 1. Model Implementation:

Extend from `CoreShop\Component\Resource\Pimcore\Model\AbstractPimcoreModel` or
implement `CoreShop\Component\Resource\Model\ResourceInterface`.

#### 2. Register as CoreShop Resource:

```yaml
# app/config/config.yml
core_shop_resource:
pimcore:
app.my_data_object_class:
classes:
model: Pimcore\Model\DataObject\MyDataObjectClass
interface: CoreShop\Component\Resource\Model\ResourceInterface
```
#### 2.1. Register as a CoreShop Resource with PHP Attributes:

Since CoreShop 4.1.0, it is also possible to use PHP Attributes to register new Entities.

You can do this by adding the following Attribute to your Entity Class:

Extend from `CoreShop\Component\Resource\Pimcore\Model\AbstractPimcoreModel` or
implement `CoreShop\Component\Resource\Model\ResourceInterface`.
```php

use CoreShop\Bundle\ResourceBundle\Attribute\AsPimcoreModel;
use CoreShop\Component\Resource\Pimcore\Model\AbstractPimcoreModel;

#[AsPimcoreModel(
pimcoreModel: 'Pimcore\Model\DataObject\MyDataObjectClass',
type: 'object'
)]
class MyDataObjectClass extends AbstractPimcoreModel
{

}
```

2. **Register as CoreShop Resource**:
For this to work, you have to make sure that your `core_shop_resource` Mapping Path is set.
Per default, it points to `%kernel.project_dir%/src/Model`.

```yaml
# app/config/config.yml
core_shop_resource:
pimcore:
app.my_data_object_class:
classes:
model: Pimcore\Model\DataObject\MyDataObjectClass
interface: CoreShop\Component\Resource\Model\ResourceInterface
```
#### 3. Usage

3. **Usage**: Utilize CoreShop's repository service or Pimcore's listing classes for data manipulation and retrieval.
Utilize CoreShop's repository service or Pimcore's listing classes for data manipulation and retrieval.

The Resource Bundle is the backbone of CoreShop, enhancing its capabilities and providing a robust framework for
managing models and data in Pimcore.
41 changes: 39 additions & 2 deletions docs/03_Development/03_Products/05_Multiple_Product_DataObjects.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
CoreShop allows you to create a new custom Product Type. The most single interface implementation that can be added to
the cart
is the `CoreShop\Component\Order\Model\PurchasableInterface`. You therefore have to at least implement this interface if
you want to add a new Product Type and allow it to be added the the cart.
you want to add a new Product Type and allow it to be added to the cart.

If you need Product Price Rules, Product Specific Price Rules and Quantity Price Rules, you have to go for
the `CoreShop\Component\Core\Model\ProductInterface`.
Expand Down Expand Up @@ -38,14 +38,51 @@ CoreShop will then create separate Services for you, the mains one are the Facto
Repository (`app.repository.my_product`, `app.factory.my_product`).
You don't need to use them in your Project, but they are quite important internally for CoreShop.

### Alternative using Attributes
Since CoreShop 4.1.0, it is also possible to use PHP Attributes to register new Product Types.
You can do this by adding the following Attribute to your Product Class:

```php
<?php

declare(strict_types=1);

namespace App\Model;

use CoreShop\Bundle\ResourceBundle\Attribute\AsPimcoreModel;
use CoreShop\Component\Order\Model\PurchasableInterface;
use CoreShop\Component\Resource\Pimcore\Model\AbstractPimcoreModel;

#[AsPimcoreModel(
pimcoreModel: 'Pimcore\Model\DataObject\MyProduct',
type: 'object',
interface: PurchasableInterface::class
)]
class MyProduct extends AbstractPimcoreModel implements PurchasableInterface
{

}
```

For this to work, you have to make sure that your `core_shop_resource` Mapping Path is set.
Per default, it points to `%kernel.project_dir%/src/Model`.

You can change this configuration by adding the following to your Symfony Config:

```yaml
core_shop_resource:
mapping:
path: '%kernel.project_dir%/src/Model'
```

## Price Calculators

Since you added a new Product Class, you also need Price Calculators for it. CoreShop has a few Price Calculators
already, but you can add your own.

> If you just added a Purchasable, you have to create a new Price Calculator.
To create a new Price Calculator, you need implement the
To create a new Price Calculator, you need to implement the
interfaces `CoreShop\Component\Order\Calculator\PurchasablePriceCalculatorInterface`
and `CoreShop\Component\Order\Calculator\PurchasableRetailPriceCalculatorInterface`.

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@domain @pimcore
Feature: Adding a new pimcore Class

Scenario: Create a new pimcore class
Given there is a pimcore class "Car"
And the definitions parent class is set to "\CoreShop\Behat\Model\Car"
And the class "Car" is registered as Pimcore Resource
50 changes: 50 additions & 0 deletions src/CoreShop/Behat/Context/Domain/ResourceContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.org)
* @license https://www.coreshop.org/license GPLv3 and CCL
*
*/

namespace CoreShop\Behat\Context\Domain;

use Behat\Behat\Context\Context;
use CoreShop\Component\Core\Model\CarrierInterface;
use CoreShop\Component\Core\Model\OrderInterface;
use CoreShop\Component\Core\Model\OrderItemInterface;
use CoreShop\Component\Core\Model\ProductInterface;
use CoreShop\Component\Order\Context\CartContextInterface;
use CoreShop\Component\Product\Model\ProductUnitInterface;
use CoreShop\Component\Resource\Metadata\Registry;
use CoreShop\Component\Taxation\Model\TaxItemInterface;
use Pimcore\Model\DataObject\Fieldcollection;
use Symfony\Component\Form\FormInterface;
use Webmozart\Assert\Assert;

final class ResourceContext implements Context
{
public function __construct(
private Registry $metadataRegistry,
) {
}

/**
* @Then /^the (class "[^"]+") is registered as Pimcore Resource$/
*/
public function theClassIsRegisteredAsPimcoreResource(): void
{
$car = $this->metadataRegistry->get('app.car');

Assert::eq($car->getClass('model'), 'Pimcore\Model\DataObject\Car');
}
}
31 changes: 31 additions & 0 deletions src/CoreShop/Behat/Model/Car.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

/*
* CoreShop
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - CoreShop Commercial License (CCL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) CoreShop GmbH (https://www.coreshop.org)
* @license https://www.coreshop.org/license GPLv3 and CCL
*
*/

namespace CoreShop\Behat\Model;

use CoreShop\Bundle\ResourceBundle\Attribute\AsPimcoreModel;
use CoreShop\Component\Resource\Pimcore\Model\AbstractPimcoreModel;

#[AsPimcoreModel(
pimcoreModel: 'Pimcore\Model\DataObject\Car',
type: 'object'
)]
class Car extends AbstractPimcoreModel
{

}
5 changes: 5 additions & 0 deletions src/CoreShop/Behat/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ payum:
core_shop_address:
autoconfigure_with_attributes: true

core_shop_resource:
mapping:
paths:
- '%kernel.project_dir%/src/CoreShop/Behat/Model'

services:
_defaults:
public: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,10 @@ services:
- '@coreshop.behat.shared_storage'
tags:
- { name: fob.context_service }

coreshop.behat.context.domain.resource:
class: CoreShop\Behat\Context\Domain\ResourceContext
arguments:
- '@CoreShop\Component\Resource\Metadata\RegistryInterface'
tags:
- { name: fob.context_service }

0 comments on commit b335da9

Please sign in to comment.