Created
April 25, 2018 16:26
-
-
Save anyt/53619b281e716db440416eb38f322f02 to your computer and use it in GitHub Desktop.
Proper way to update oro_entity_config_xxx after removing a field https://oroinc.com/orocrm/forums/topic/proper-way-to-update-oro_entity_config_xxx-after-removing-a-field
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Demo\Bundle\CalendarBundle\Migrations\Schema\v2_3; | |
use Doctrine\DBAL\Schema\Schema; | |
use Oro\Bundle\EntityExtendBundle\Tools\ExtendDbIdentifierNameGenerator; | |
use Oro\Bundle\MigrationBundle\Migration\Extension\NameGeneratorAwareInterface; | |
use Oro\Bundle\MigrationBundle\Migration\Migration; | |
use Oro\Bundle\MigrationBundle\Migration\QueryBag; | |
use Oro\Bundle\MigrationBundle\Tools\DbIdentifierNameGenerator; | |
/** | |
* This migration should not be executed during install, | |
* because during install many-to-many relation associatedContacts is not created. | |
*/ | |
class RemoveAssociatedContacts implements Migration, NameGeneratorAwareInterface | |
{ | |
const ACCOUNT_CLASS = 'OroCRM\\Bundle\\AccountBundle\\Entity\\Account'; | |
const CALENDAR_EVENT_CLASS = 'Oro\\Bundle\\CalendarBundle\\Entity\\CalendarEvent'; | |
/** | |
* @var ExtendDbIdentifierNameGenerator | |
*/ | |
protected $nameGenerator; | |
/** | |
* {@inheritdoc} | |
*/ | |
public function up(Schema $schema, QueryBag $queries) | |
{ | |
// Cleanup entity config of field associatedContacts | |
$this->deleteEntityFieldConfig( | |
self::CALENDAR_EVENT_CLASS, | |
'associatedContacts', | |
$queries | |
); | |
// Cleanup entity config of calendar event entity | |
$queries->addPostQuery( | |
new UpdateEntityConfigDataQuery( | |
function ($data) { | |
$relationKey = | |
'manyToMany|' | |
. self::CALENDAR_EVENT_CLASS . '|' | |
. self::ACCOUNT_CLASS . '|' . | |
'associatedContacts'; | |
unset($data['extend']['relation'][$relationKey]); | |
unset($data['extend']['schema']['relation']['associatedContacts']); | |
unset($data['extend']['schema']['default']['default_associatedContacts']); | |
unset($data['extend']['schema']['addremove']['associatedContacts']); | |
return $data; | |
}, | |
self::CALENDAR_EVENT_CLASS | |
) | |
); | |
// Cleanup entity config of account entity | |
$queries->addPostQuery( | |
new UpdateEntityConfigDataQuery( | |
function ($data) { | |
$relationKey = | |
'manyToMany|' | |
. self::CALENDAR_EVENT_CLASS . '|' | |
. self::ACCOUNT_CLASS . '|' | |
. 'associatedContacts'; | |
unset($data['extend']['relation'][$relationKey]); | |
unset($data['extend']['schema']['relation']['calendarevent_associatedContacts']); | |
unset($data['extend']['schema']['addremove']['calendarevent_associatedContacts']); | |
return $data; | |
}, | |
self::ACCOUNT_CLASS | |
) | |
); | |
// Drop many-to-many table | |
$manyToManyTableName = $this->nameGenerator->generateManyToManyJoinTableName( | |
self::CALENDAR_EVENT_CLASS, | |
'associatedContacts', | |
self::ACCOUNT_CLASS | |
); | |
$schema->dropTable($manyToManyTableName); | |
// Drop column for default value of many-to-many relation | |
$table = $schema->getTable('oro_calendar_event'); | |
$table->dropIndex('uniq_2ddc40dd47325b55'); | |
$table->removeForeignKey('fk_2ddc40dd47325b55'); | |
$table->dropColumn('default_associatedcontacts_id'); | |
} | |
/** | |
* @param string $entityClassName | |
* @param string $fieldName | |
* @param QueryBag $queries | |
*/ | |
protected function deleteEntityFieldConfig($entityClassName, $fieldName, QueryBag $queries) | |
{ | |
$entityClassName = addslashes($entityClassName); | |
$sql = <<<DQL | |
DELETE FROM oro_entity_config_index_value | |
WHERE entity_id IS NULL AND field_id IN ( | |
SELECT oecf.id FROM oro_entity_config_field AS oecf | |
WHERE | |
oecf.field_name = '$fieldName' | |
AND | |
oecf.entity_id = ( | |
SELECT oec.id | |
FROM oro_entity_config AS oec | |
WHERE oec.class_name = '' | |
) | |
); | |
DELETE FROM oro_entity_config_field | |
WHERE field_name = '$fieldName' AND | |
entity_id IN ( | |
SELECT id FROM oro_entity_config | |
WHERE class_name = '$entityClassName' | |
); | |
DQL; | |
$queries->addPostQuery($sql); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function setNameGenerator(DbIdentifierNameGenerator $nameGenerator) | |
{ | |
$this->nameGenerator = $nameGenerator; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Demo\Bundle\CalendarBundle\Migrations\Schema\v2_3; | |
use Psr\Log\LoggerInterface; | |
use Oro\Bundle\MigrationBundle\Migration\ArrayLogger; | |
use Oro\Bundle\MigrationBundle\Migration\ParametrizedMigrationQuery; | |
/** | |
* Update entity config data using callback. | |
*/ | |
class UpdateEntityConfigDataQuery extends ParametrizedMigrationQuery | |
{ | |
const CALENDAR_EVENT_CLASS = 'Oro\\Bundle\\CalendarBundle\\Entity\\CalendarEvent'; | |
const ACCOUNT_CLASS = 'OroCRM\\Bundle\\AccountBundle\\Entity\\Account'; | |
/** | |
* @var callable | |
*/ | |
protected $updateCallback; | |
/** | |
* @var string | |
*/ | |
protected $className; | |
/** | |
* @param callable $updateCallback | |
* @param string $className | |
*/ | |
public function __construct($updateCallback, $className) | |
{ | |
$this->updateCallback = $updateCallback; | |
$this->className = $className; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getDescription() | |
{ | |
$logger = new ArrayLogger(); | |
$this->doExecute($logger, true); | |
return $logger->getMessages(); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function execute(LoggerInterface $logger) | |
{ | |
$this->doExecute($logger); | |
} | |
/** | |
* @param LoggerInterface $logger | |
* @param bool $dryRun | |
* | |
* @SuppressWarnings(PHPMD.NPathComplexity) | |
* @SuppressWarnings(PHPMD.CyclomaticComplexity) | |
*/ | |
public function doExecute(LoggerInterface $logger, $dryRun = false) | |
{ | |
$data = $this->loadEntityConfigData($logger, $this->className); | |
$data = call_user_func($this->updateCallback, $data); | |
$query = 'UPDATE oro_entity_config SET data = :data WHERE class_name = :class_name'; | |
$params = ['data' => $data, 'class_name' => $this->className]; | |
$types = ['data' => 'array', 'class_name' => 'string']; | |
$this->logQuery($logger, $query, $params, $types); | |
if (!$dryRun) { | |
$this->connection->executeUpdate($query, $params, $types); | |
} | |
} | |
/** | |
* @param LoggerInterface $logger | |
* | |
* @return array | |
*/ | |
protected function loadEntityConfigData(LoggerInterface $logger) | |
{ | |
$sql = 'SELECT data FROM oro_entity_config WHERE class_name = :class_name'; | |
$params = ['class_name' => $this->className]; | |
$types = ['class_name' => 'string']; | |
$this->logQuery($logger, $sql, $params, $types); | |
$result = []; | |
$rows = $this->connection->fetchAll($sql, $params, $types); | |
if (isset($rows[0])) { | |
$result = $this->connection->convertToPHPValue($rows[0]['data'], 'array'); | |
} | |
return $result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment