Skip to content

Commit

Permalink
Inital commit
Browse files Browse the repository at this point in the history
  • Loading branch information
adrozdek committed Oct 31, 2018
0 parents commit 36e4a53
Show file tree
Hide file tree
Showing 9 changed files with 460 additions and 0 deletions.
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
Divante_ClassLocker
====================
Divante Class Locker bundle was created to block modifications on attributes in classes.

## Compatibility
This module is compatible with Pimcore >= 5.2

## Dependencies
pitpit/php-diff

## Events
- pimcore.class.preUpdate
- Blocking any changes in class' attributes defined in config.

## Module goal
The goal of this module is:
- blocking modifications in class' attributes defined in config.

## Installing/Getting started
```bash
composer require divanteltd/pimcore-class-locker
```
In Pimcore panel select Extensions and click Enable.

Define which attributes cannot be changed in which class in your bundle's config.yml:
```yaml
divante_class_locker:
classes:
class_name1:
- attribute1
- attribute2

class_name2: [attribute1, attribute2]
```
## Contributing
If you'd like to contribute, please fork the repository and use a feature branch. Pull requests are warmly welcome.
## Licensing
GPL-3.0-or-later
## Standards & Code Quality
This module respects all Pimcore 5 code quality rules and our own PHPCS and PHPMD rulesets.
## About Authors
![Divante-logo](http://divante.co/logo-HG.png "Divante")
We are a Software House from Europe, existing from 2008 and employing about 150 people. Our core competencies are built around Magento, Pimcore and bespoke software projects (we love Symfony3, Node.js, Angular, React, Vue.js). We specialize in sophisticated integration projects trying to connect hardcore IT with good product design and UX.
We work for Clients like INTERSPORT, ING, Odlo, Onderdelenwinkel and CDP, the company that produced The Witcher game. We develop two projects: [Open Loyalty](http://www.openloyalty.io/ "Open Loyalty") - an open source loyalty program and [Vue.js Storefront](https://github.com/DivanteLtd/vue-storefront "Vue.js Storefront").
We are part of the OEX Group which is listed on the Warsaw Stock Exchange. Our annual revenue has been growing at a minimum of about 30% year on year.
Visit our website [Divante.co](https://divante.co/ "Divante.co") for more information.
44 changes: 44 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "divanteltd/pimcore-class-locker",
"type": "pimcore-bundle",
"license": "GPL-3.0-or-later",
"description": "Divante Class Locker bundle was created to block modifications on attributes in classes.",
"keywords": [
"pimcore",
"pimcore-bundle"
],
"homepage": "https://www.divante.co",
"authors": [
{
"name": "Michał Bolka",
"email": "[email protected]",
"role": "Developer"
},
{
"name": "Jakub Płaskonka",
"email": "[email protected]",
"role": "Developer"
},
{
"name": "Agata Drozdek",
"email": "[email protected]",
"role": "Developer"
}
],
"require": {
"pimcore/pimcore": ">=5.2",
"pitpit/php-diff": "@dev"
},
"autoload": {
"psr-4": {
"ClassLockerBundle\\": "src/"
}
},
"extra": {
"pimcore": {
"bundles": [
"ClassLockerBundle\\ClassLockerBundle"
]
}
}
}
41 changes: 41 additions & 0 deletions src/ClassLockerBundle/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php
/**
* @category    DivanteClassLocker
* @date        22/10/2017 10:39
* @author      Jakub Płaskonka <[email protected]> | Agata Drozdek <[email protected]>
* @copyright   Copyright (c) 2017 Divante Ltd. (https://divante.co)
*/

namespace Divante\ClassLockerBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

/**
* Class Configuration
* @package Divante\ClassLockerBundle\DependencyInjection
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('divante_class_locker');

$rootNode
->children()
->arrayNode('classes')
->useAttributeAsKey('name')
->prototype('array')
->scalarPrototype()->end()
->end()
->end()
->end()
->end();

return $treeBuilder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
/**
* @category    DivanteClassLocker
* @date        22/10/2017 10:39
* @author      Jakub Płaskonka <[email protected]> | Agata Drozdek <[email protected]>
* @copyright   Copyright (c) 2017 Divante Ltd. (https://divante.co)
*/

namespace Divante\ClassLockerBundle\DependencyInjection;

use Divante\ClassLockerBundle\EventListener\ClassListener;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;

/**
* This is the class that loads and manages your bundle configuration.
*
* @link http://symfony.com/doc/current/cookbook/bundles/extension.html
*/
class DivanteClassLockerExtension extends Extension
{
/**
* {@inheritdoc}
* @param array $configs
* @param ContainerBuilder $container
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);

$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.yml');

$listener = $container->getDefinition(ClassListener::class);
$listener->setArgument('$lockedClasses', $config['classes']);
}
}
45 changes: 45 additions & 0 deletions src/ClassLockerBundle/DivanteClassLockerBundle.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* @category    Wurth
* @date        22/10/2017 10:39
* @author      Jakub Płaskonka <[email protected]>
* @copyright   Copyright (c) 2017 Divante Ltd. (https://divante.co)
*/

namespace Divante\ClassLockerBundle;

use Pimcore\Extension\Bundle\AbstractPimcoreBundle;

/**
* Class DivanteClassLockerBundle
* @package Divante\ClassLockerBundle
*/
class DivanteClassLockerBundle extends AbstractPimcoreBundle
{

/**
* @return array
*/
public function getJsPaths()
{
return [
'/bundles/divanteclasslocker/js/pimcore/startup.js',
];
}

/**
* @inheritdoc
*/
public function getNiceName()
{
return "Divante Class Locker";
}

/**
* @inheritdoc
*/
public function getVersion()
{
return "2.0.0";
}
}
71 changes: 71 additions & 0 deletions src/ClassLockerBundle/EventListener/ClassListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/**
* @category    DivanteClassLocker
* @date        22/10/2017 10:39
* @author      Jakub Płaskonka <[email protected]> | Michal Bolka <[email protected]>
* @copyright   Copyright (c) 2017 Divante Ltd. (https://divante.co)
*/

namespace Divante\ClassLockerBundle\EventListener;

use Divante\ClassLockerBundle\Service\ClassLockerService;
use Pimcore\Event\Model\DataObject\ClassDefinitionEvent;
use Pimcore\Model\DataObject\ClassDefinition;

/**
* Class ClassListener
* @package Divante\ClassLockerBundle\EventListener
*/
class ClassListener
{
/** @var ClassLockerService */
protected $lockerService;

/**
* @var array
*/
protected $lockedClasses;

/**
* ClassListener constructor.
* @param ClassLockerService $lockerService
* @param array $lockedClasses
*/
public function __construct(ClassLockerService $lockerService, array $lockedClasses)
{
$this->lockerService = $lockerService;
$this->lockedClasses = $lockedClasses;
}

/**
* @param ClassDefinitionEvent $classDefinitionEvent
* @throws \Exception
* @return void
*/
public function onPreUpdate(ClassDefinitionEvent $classDefinitionEvent): void
{
$classDefinition = $classDefinitionEvent->getClassDefinition();
if (array_key_exists($classDefinition->getName(), $this->lockedClasses)) {
$this->preProcessTargetClass($classDefinition);
}
}

/**
* @param ClassDefinition $targetClass
* @throws \Exception
* @return void
*/
protected function preProcessTargetClass(ClassDefinition $targetClass): void
{
$sharedFieldsNames = $this->lockedClasses[$targetClass->getName()] ?: [];

$differences = $this->lockerService->fetchSharedAttributesChanges($targetClass);
$intersectedValues = array_intersect($sharedFieldsNames, $differences);
$count = count($intersectedValues);

if ($count > 0) {
$glue = (php_sapi_name() == "cli") ? "\n" : "<br/>";
throw new \Exception("You cannot modify following fields:<br/> " . implode($glue, $sharedFieldsNames));
}
}
}
11 changes: 11 additions & 0 deletions src/ClassLockerBundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: true

Divante\ClassLockerBundle\EventListener\ClassListener:
tags:
- { name: kernel.event_listener, event: pimcore.class.preUpdate, method: onPreUpdate }

Divante\ClassLockerBundle\Service\ClassLockerService: ~
46 changes: 46 additions & 0 deletions src/ClassLockerBundle/Resources/public/js/pimcore/startup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
pimcore.registerNS("pimcore.plugin.DivanteClassLockerBundle");

pimcore.plugin.DivanteClassLockerBundle = Class.create(pimcore.plugin.admin, {
getClassName: function () {
return "pimcore.plugin.DivanteClassLockerBundle";
},

initialize: function () {
pimcore.plugin.broker.registerPlugin(this);
},

pimcoreReady: function (params, broker) {
//alert("DivanteClassLockerBundle ready!");
}
});

var DivanteClassLockerBundlePlugin = new pimcore.plugin.DivanteClassLockerBundle();
Ext.define('overrides.pimcore.object.classes.klass',{
override:'pimcore.object.classes.klass',
saveOnComplete: function (response) {

try {
var res = Ext.decode(response.responseText);
if(res.success) {
// refresh all class stores
this.parentPanel.tree.getStore().load();
pimcore.globalmanager.get("object_types_store").load();
pimcore.globalmanager.get("object_types_store_create").load();

// set the current modification date, to detect modifcations on the class which are not made here
this.data.modificationDate = res['class'].modificationDate;

pimcore.helpers.showNotification(t("success"), t("class_saved_successfully"), "success");
} else {
throw res.message;
}
} catch (e) {
this.saveOnError(e);
}

},

saveOnError: function (e) {
pimcore.helpers.showNotification(t("error"), t(e), "error");
}
});
Loading

0 comments on commit 36e4a53

Please sign in to comment.