Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ClassDefinitionPatchBundle] introduce new Bundle to allow patching Pimcore Class Definitions #2279

Merged
merged 8 commits into from
May 14, 2023
Merged
1 change: 1 addition & 0 deletions bin/subtree-release
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,4 @@ split 'src/CoreShop/Bundle/VariantBundle' variant-bundle
split 'src/CoreShop/Bundle/StorageListBundle' storage-list-bundle
split 'src/CoreShop/Bundle/WishlistBundle' wishlist-bundle
split 'src/CoreShop/Bundle/MessengerBundle' messenger-bundle
split 'src/CoreShop/Bundle/ClassDefinitionPatchBundle' coreshop/class-definition-patch-bundle
2 changes: 2 additions & 0 deletions bin/subtree-split
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ remote variant-bundle [email protected]:CoreShop/VariantBundle.git
remote storage-list-bundle [email protected]:CoreShop/StorageListBundle.git
remote wishlist-bundle [email protected]:CoreShop/WishlistBundle.git
remote messenger-bundle [email protected]:CoreShop/MessengerBundle.git
remote class-definition-patch-bundle [email protected]:CoreShop/ClassDefinitionPatchBundle.git

split 'src/CoreShop/Component/Resource' resource
split 'src/CoreShop/Component/Registry' registry
Expand Down Expand Up @@ -177,3 +178,4 @@ split 'src/CoreShop/Bundle/VariantBundle' variant-bundle
split 'src/CoreShop/Bundle/StorageListBundle' storage-list-bundle
split 'src/CoreShop/Bundle/WishlistBundle' wishlist-bundle
split 'src/CoreShop/Bundle/MessengerBundle' messenger-bundle
split 'src/CoreShop/Bundle/ClassDefinitionPatchBundle' class-definition-patch-bundle
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
"coreshop/payum-payment": "self.version",
"coreshop/payum-payment-bundle": "self.version",
"coreshop/optimistic-entity-lock-bundle": "self.version",
"coreshop/messenger-bundle": "self.version"
"coreshop/messenger-bundle": "self.version",
"coreshop/class-definition-patch-bundle": "self.version"
},
"require": {
"php": "^8.0",
Expand All @@ -101,6 +102,7 @@
"php-http/guzzle7-adapter": "^0.1",
"pimcore/pimcore": "^10.5",
"rinvex/countries": "^7.3",
"sebastian/diff": "^4.0 | ^5.0",
"stof/doctrine-extensions-bundle": "^1.6",
"sylius/theme-bundle": "^2.2",
"symfony/notifier": "^5.4.0",
Expand Down
55 changes: 55 additions & 0 deletions docs/02_Bundles/ClassDefinitionPatch_Bundle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# CoreShop Class Definition Patch Bundle

CoreShop Class Definition Patch Bundle allows you to patch class definitions from other bundles. This is useful if you want to add new properties to existing classes with a configuration.

## Installation
```bash
$ composer require coreshop/class-definitions-patch-bundle:^3.0
```

### Adding required bundles to kernel
You need to enable the bundle inside the kernel.

```php
<?php

// app/AppKernel.php

public function registerBundlesToCollection(BundleCollection $collection)
{
$collection->addBundles([
new \CoreShop\Bundle\ClassDefinitionPatchBundle\CoreShopClassDefinitionPatchBundle(),
]);
}
```

### Usage

Add a configuration to patch a certain pimcore class definition:

```yaml
core_shop_class_definition_patch:
patches:
CoreShopCompany:
interface: 'blub'
fields:
name2:
before: 'addresses'
definition:
fieldtype: input
title: coreshop.company.name2
```

You can then run the command to preview it:

```bash
bin/console coreshop:patch:classes --dump
```



If you are happy with what you see, you can apply the patch. Since the patch is applied to your local definitions, and they should be part of your git repository, you should commit the changes and don't have to run the patch command on the deployment.

```bash
bin/console coreshop:patch:classes --force
```
Binary file added docs/02_Bundles/img/patch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion docs/02_Bundles/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ CoreShop is a set of Bundles that provide different functionality. Each Bundle i
- [User Bundle](./User_Bundle.md)
- [Variant Bundle](./Variant_Bundle.md)
- [Wishlist Bundle](./Wishlist_Bundle.md)
- [Workflow Bundle](./Workflow_Bundle.md)
- [Workflow Bundle](./Workflow_Bundle.md)
- [Class Definition Patch Bundle](./ClassDefinitionPatch_Bundle.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?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\Bundle\ClassDefinitionPatchBundle\Command;

use CoreShop\Bundle\ClassDefinitionPatchBundle\Console\ConsoleDiffer;
use CoreShop\Bundle\ClassDefinitionPatchBundle\PatcherInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

final class PatchCommand extends Command
{
public function __construct(
private PatcherInterface $patcher,
private ConsoleDiffer $consoleDiffer,
) {
parent::__construct();
}

protected function configure(): void
{
$this
->setName('coreshop:patch:classes')
->setDescription('Execute Class Patches.')
->addOption('force', 'f', null, 'Force execution of all patches.')
->addOption('dump', 'd', null, 'Dump the diff of all patches.')
->setHelp(
<<<EOT
The <info>%command.name%</info> executes all Class Patches.
EOT
);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
if ($input->getOption('dump')) {
foreach ($this->patcher->getPatches() as $patch) {
$output->writeln('<info>===================================</info>');
$output->writeln(sprintf('Diff for Class <comment>%s</comment>', $patch->getClassName()));
$output->writeln('<info>===================================</info>');
$output->writeln('');
$output->writeln(
$this->consoleDiffer->diff(
print_r($this->patcher->old($patch), true),
print_r($this->patcher->new($patch), true)
)
);
}
}

if ($input->getOption('force')) {
$this->patcher->patch();
}

return 0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?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\Bundle\ClassDefinitionPatchBundle\Console;

use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\String\UnicodeString;

class ColorConsoleDiffFormatter
{
/**
* @var string
* @see https://regex101.com/r/ovLMDF/1
*/
private const PLUS_START_REGEX = '#^(\+.*)#';

/**
* @var string
* @see https://regex101.com/r/xwywpa/1
*/
private const MINUT_START_REGEX = '#^(\-.*)#';

/**
* @var string
* @see https://regex101.com/r/CMlwa8/1
*/
private const AT_START_REGEX = '#^(@.*)#';

/**
* @var string
* @see https://regex101.com/r/qduj2O/1
*/
private const NEWLINES_REGEX = "#\n\r|\n#";

private string $template;

public function __construct()
{
$this->template = sprintf(
'<comment> ---------- begin diff ----------</comment>%s%%s%s<comment> ----------- end diff -----------</comment>' . PHP_EOL,
PHP_EOL,
PHP_EOL
);
}

public function format(string $diff): string
{
return $this->formatWithTemplate($diff, $this->template);
}

private function formatWithTemplate(string $diff, string $template): string
{
$escapedDiff = OutputFormatter::escape(rtrim($diff));

$escapedDiffLines = array_map(
static function(UnicodeString $string) {
return $string->toString();
}, (new UnicodeString($escapedDiff))->split(self::NEWLINES_REGEX)
);

// remove description of added + remove; obvious on diffs
foreach ($escapedDiffLines as $key => $escapedDiffLine) {
if ($escapedDiffLine === '--- Original') {
unset($escapedDiffLines[$key]);
}

if ($escapedDiffLine === '+++ New') {
unset($escapedDiffLines[$key]);
}
}

$coloredLines = array_map(function (string $string): string {
$string = $this->makePlusLinesGreen($string);
$string = $this->makeMinusLinesRed($string);
$string = $this->makeAtNoteCyan($string);

if ($string === ' ') {
return '';
}

return $string;
}, $escapedDiffLines);

return sprintf($template, implode(PHP_EOL, $coloredLines));
}

private function makePlusLinesGreen(string $string): string
{
return (new UnicodeString($string))->replace(self::PLUS_START_REGEX, '<fg=green>$1</fg=green>')->toString();
}

private function makeMinusLinesRed(string $string): string
{
return (new UnicodeString($string))->replace(self::MINUT_START_REGEX, '<fg=red>$1</fg=red>')->toString();
}

private function makeAtNoteCyan(string $string): string
{
return (new UnicodeString($string))->replace(self::AT_START_REGEX, '<fg=cyan>$1</fg=cyan>')->toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?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\Bundle\ClassDefinitionPatchBundle\Console;

use SebastianBergmann\Diff\Differ;

final class ConsoleDiffer
{
public function __construct(
private Differ $differ,
private ColorConsoleDiffFormatter $colorConsoleDiffFormatter
) {
}

public function diff(string $old, string $new): string
{
$diff = $this->differ->diff($old, $new);

return $this->colorConsoleDiffFormatter->format($diff);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?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\Bundle\ClassDefinitionPatchBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

final class CoreShopClassDefinitionPatchBundle extends Bundle
{
}
Loading