Skip to content

Instantly share code, notes, and snippets.

@kovenko
Last active May 1, 2020 13:37
Show Gist options
  • Save kovenko/c3061ad10c7419a34540041256e63e40 to your computer and use it in GitHub Desktop.
Save kovenko/c3061ad10c7419a34540041256e63e40 to your computer and use it in GitHub Desktop.
<?php
namespace Rgkh\Common\Doctrine\Factory;
use Doctrine\DBAL\Schema\Schema;
use Exception;
use Rgkh\Common\Doctrine\Migration\AbstractMigration;
use Rgkh\Common\Main\Entity\Reference;
use Rgkh\Common\Main\Entity\ReferenceCatalog;
use Rgkh\Common\Main\Repository\ReferenceRepository;
abstract class ReferenceMigration extends AbstractMigration
{
const DATA_MODIFICATION_LEVEL = 'dml';
/** @var ReferenceRepository $refs */
protected $refs = null;
/**
* Получение репозитория
*/
public function __construct()
{
$this->refs = $this->getDoctrine()->getRepository(Reference::class);
}
abstract public function upIfAllows(Schema $schema);
abstract public function downIfAllows(Schema $schema);
final public function up(Schema $schema)
{
ini_set('max_execution_time', 0);
$this->preConfigJournal();
if (!$this->necessaryMigrationsExists()) {
$this->write('<info>Exist not necessary migration</info>');
$this->addSql('SELECT TIMEOFDAY();'); //to avoid warning
return;
}
if (!$this->isAgreeToRunSpecialMigration()) {
$this->write('<info>' . $this->skipMessage() . '</info>');
$this->addSql('SELECT TIMEOFDAY();'); //to avoid warning
return;
}
$this->upIfAllows($schema);
}
final public function down(Schema $schema)
{
ini_set('max_execution_time', 0);
$this->preConfigJournal();
if ($this->isAgreeToRunSpecialMigration()) {
$this->downIfAllows($schema);
} else {
$this->write('<info>' . $this->skipMessage() . '</info>');
$this->addSql('SELECT TIMEOFDAY();'); //to avoid warning
}
}
/**
* Добавляет записи в справочник
*
* @param ReferenceCatalog | null $section
* @param array $items
* @return ReferenceCatalog | null
* @throws Exception
*/
protected function addItems(?ReferenceCatalog $section, array $items)
{
$retValue = null;
try {
if ($section) {
$this->refs->appendItems($section, $items);
} else {
throw new Exception("Каталог не найден: {$section}");
}
$retValue = $section;
} catch (Exception $e) {
$this->write("<info>Ошибка: {$e->getMessage()}</info>\n");
}
return $retValue;
}
/**
* Удаляет записи из справочника
*
* @param ReferenceCatalog | null $section
* @param array $items
* @return bool
* @throws Exception
*/
protected function deleteItems(?ReferenceCatalog $section, array $items)
{
/** @var ReferenceRepository $retValue */
$retValue = null;
try {
foreach($items as $item) {
$record = $this->refs->getCatalogItem($section->getCode(), $item['code']);
if ($record) {
$this->refs->deleteNodeHard($record);
}
}
$retValue = $section;
} catch (Exception $e) {
$this->write("<info>Ошибка: {$e->getMessage()}</info>\n");
}
return $retValue;
}
/**
* Получает каталог
*
* @param string $code
* @return ReferenceCatalog|null
* @throws Exception
*/
protected function getCatalog(string $code)
{
$retValue = null;
try {
$section = $this->refs->findOneCatalogByCode($code);
$retValue = $section;
if (!$section) {
throw new Exception("Каталог не найден: {$code}");
}
} catch (Exception $e) {
$this->write("<info>Ошибка: {$e->getMessage()}</info>\n");
}
return $retValue;
}
/**
* Добавляет справочник
*
* @param array $params
* [string code, string name, bool isExtendable, ReferenceCatalog parent, string description]
* @return ReferenceCatalog | null
* @throws Exception
*/
protected function createCatalog(array $params)
{
$retValue = null;
try {
$catalog = $this->refs->createCatalog(
$params['code'] || 'unassigned',
$params['name'] || 'unassigned',
$params['parent'] || null,
$params['isExtendable'] || false,
$params['description'] || null
);
$retValue = $catalog;
} catch (Exception $e) {
$this->write("<info>Ошибка: {$e->getMessage()}</info>\n");
}
return $retValue;
}
/**
* Удаляет справочник, справочник не должен содержать дочерних элементов
*
* @param ReferenceCatalog | null $section
* @return bool
* @throws Exception
*/
protected function deleteCatalog(?ReferenceCatalog $section)
{
$retValue = false;
try {
$items = $this->refs->getCatalogItems($section->getCode());
if (count($items)) {
throw new Exception("Каталог не пуст, требуется удалить дочерние элементы");
}
$this->refs->deleteNodeHard($section);
$retValue = true;
} catch (Exception $e) {
$this->write("<info>Ошибка: {$e->getMessage()}</info>\n");
}
return $retValue;
}
/**
* Уровень миграции
*
* @return string
*/
protected function getMigrationLevel()
{
return self::DATA_MODIFICATION_LEVEL;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment