You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
4.2 KiB

<?php
namespace core\services;
use core\entities\ModuleRecord;
use core\repositories\ModuleRepository;
use yii\helpers\FileHelper;
use Yii;
class ModuleService
{
private $modules;
private $permission_manager;
public function __construct(ModuleRepository $modules, PermissionManager $permission_manager)
{
$this->modules = $modules;
$this->permission_manager = $permission_manager;
}
public function create($name, $class, $type = 'common', $active = ModuleRecord::STATUS_DISABLED): ModuleRecord
{
$module = new ModuleRecord();
$module->name = $name;
$module->class = $class;
$module->type = $type;
$module->active = $active;
$this->modules->save($module);
return $module;
}
public function delete(ModuleRecord $module)
{
// connect manifest
$manifest = require Yii::getAlias('@common/modules/' . $module->name . '/manifest.php');
// down migrations
$migrations = $this->getMigrationFiles($module->name);
$migrations = array_reverse($migrations);
foreach ($migrations as $migrationPath) {
$migrationFile = basename($migrationPath);
$migration = str_replace('.php', '', $migrationFile);
if ($this->migrationExists($migration)) {
require $migrationPath;
$obj = new $migration;
if (method_exists($obj, 'safeDown')) {
$obj->safeDown();
Yii::$app->moduleManager->removeFromMigrationTable($migration);
}
elseif (method_exists($obj, 'down')) {
$obj->down();
Yii::$app->moduleManager->removeFromMigrationTable($migration);
}
}
}
// remove permissions
if (isset($manifest['permissions']) && is_array($manifest['permissions'])) {
$this->removePermissions($manifest['permissions']);
}
// delete files
$modulePath = Yii::getAlias('@common/modules/' . $module->name);
if (file_exists($modulePath)) {
FileHelper::removeDirectory($modulePath);
}
// delete module record
$this->modules->remove($module);
}
public function disable(ModuleRecord $module)
{
$module->active = ModuleRecord::STATUS_DISABLED;
$this->modules->save($module);
}
public function enable(ModuleRecord $module)
{
// connect manifest
$manifest = require Yii::getAlias('@common/modules/' . $module->name . '/manifest.php');
$module->active = ModuleRecord::STATUS_ENABLED;
// migration if not exists
$migrations = $this->getMigrationFiles($module->name);
foreach ($migrations as $migrationPath) {
$migrationFile = basename($migrationPath);
$migration = str_replace('.php', '', $migrationFile);
if (!$this->migrationExists($migration)) {
// run migration
require $migrationPath;
$obj = new $migration;
if (method_exists($obj, 'safeUp')) {
$obj->safeUp();
Yii::$app->moduleManager->appendToMigrationTable($migration);
}
elseif (method_exists($obj, 'up')) {
$obj->up();
Yii::$app->moduleManager->appendToMigrationTable($migration);
}
}
}
// add not exists permissions
if (isset($manifest['permissions']) && is_array($manifest['permissions'])) {
$this->assignPermissions($manifest['permissions']);
}
$this->modules->save($module);
}
private function assignPermissions(array $permissions): void
{
foreach ($permissions as $permission => $description) {
if (!$this->permission_manager->permissionExists($permission)) {
$this->permission_manager->create($permission, $description);
}
}
}
private function removePermissions(array $permissions)
{
foreach ($permissions as $permission => $description) {
if ($this->permission_manager->permissionExists($permission)) {
$this->permission_manager->delete($permission);
}
}
}
private function getMigrationFiles($module)
{
// migration if not exists
$migrationPath = Yii::getAlias('@common/modules/' . $module . '/migrations');
return file_exists($migrationPath) ? FileHelper::findFiles($migrationPath) : [];
}
private function migrationExists($name): bool
{
// check record exists
$connection = Yii::$app->getDb();
$command = $connection->createCommand("SELECT * FROM migration WHERE version = '$name'");
$result = $command->queryAll();
return $result ? true : false;
}
}