Ignore:
Timestamp:
Feb 17, 2021, 12:30:23 PM (4 years ago)
Author:
chronos
Message:
File:
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/Packages/Common/Module.php

    r898 r899  
    11<?php
    2 
    3 /* This implementation will not support installation from remote source. Just
    4  * installation of already presented modules mainly to persistence preparation.
    5  */
    62
    73class ModuleType
     
    3733}
    3834
    39 class AppModule
     35class Module extends Model
    4036{
    4137  public int $Id;
     
    4743  public string $HomePage;
    4844  public string $Description;
     45  public int $Type; // ModuleType
     46  public array $Dependencies;
     47  public array $Models; // Model
    4948  public bool $Running;
    5049  public bool $Enabled;
    5150  public bool $Installed;
    5251  public string $InstalledVersion;
    53   public int $Type;
    54   public array $Dependencies;
    5552  public Database $Database;
    5653  public System $System;
    57   public AppModuleManager $Manager;
     54  public ModuleManager $Manager;
    5855  public $OnChange;
    59   public array $Models;
    60 
    61   function __construct(Application $System)
    62   {
    63     $this->System = &$System;
    64     $this->Database = &$System->Database;
    65     $this->Installed = false;
    66     $this->InstalledVersion = '';
    67     $this->Enabled = false;
    68     $this->Running = false;
     56
     57  function __construct(System $System)
     58  {
     59    parent::__construct($System);
     60    $this->Name = '';
    6961    $this->HomePage = '';
    7062    $this->License = '';
     
    7466    $this->Description = '';
    7567    $this->Dependencies = array();
     68    $this->Models = array();
    7669    $this->Type = ModuleType::Library;
    77     $this->Models = array();
    78   }
    79 
    80   function GetModels(): array
    81   {
    82     return array();
     70    $this->Installed = false;
     71    $this->InstalledVersion = '';
     72    $this->Enabled = false;
     73    $this->Running = false;
     74  }
     75
     76  static function GetName()
     77  {
     78    $ClassName = get_called_class();
     79    if (substr($ClassName, 0, 6) == 'Module') return substr($ClassName, 6);
     80      else return $ClassName;
     81  }
     82
     83  static function GetModelDesc(): ModelDesc
     84  {
     85    $Desc = new ModelDesc(self::GetClassName());
     86    $Desc->AddString('Name');
     87    $Desc->AddString('Title');
     88    $Desc->AddString('Creator');
     89    $Desc->AddString('Version');
     90    $Desc->AddString('License');
     91    $Desc->AddBoolean('Installed');
     92    $Desc->AddString('InstalledVersion');
     93    $Desc->AddString('Description');
     94    return $Desc;
    8395  }
    8496
     
    8698  {
    8799    if ($this->Installed) return;
    88     echo('Install mod '.$this->Name.'<br/>');
    89100    $List = array();
    90101    $this->Manager->EnumDependenciesCascade($this, $List, array(ModuleCondition::NotInstalled));
     
    99110      call_user_func($this->Manager->OnInstallModule, $this);
    100111    }
    101     $this->InstallModels();
     112    $this->InstallModels($this->Models);
    102113    $this->DoInstall();
    103114  }
     
    112123    $this->Manager->PerformList($List, array(ModuleAction::Uninstall), array(ModuleCondition::Installed));
    113124    $this->DoUninstall();
    114     $this->UninstallModels();
     125    $this->UninstallModels($this->Models);
    115126    if ($this->Manager->OnUninstallModule != null)
    116127    {
     
    218229  }
    219230
    220   function InstallModels(): void
     231  function InstallModels(array $Models): void
    221232  {
    222233    if ($this->Manager->OnInstallModel != null)
    223234    {
    224       foreach ($this->GetModels() as $Model)
     235      foreach ($Models as $Model)
    225236      {
    226         call_user_func($this->Manager->OnInstallModel, $Model::GetDesc(), $this);
     237        call_user_func($this->Manager->OnInstallModel, $Model::GetModelDesc(), $this);
    227238      }
    228239    }
    229240  }
    230241
    231   function UninstallModels(): void
     242  function UninstallModels(array $Models): void
    232243  {
    233244    if ($this->Manager->OnUninstallModel != null)
    234245    {
    235       foreach (array_reverse($this->GetModels()) as $Model)
     246      foreach (array_reverse($Models) as $Model)
    236247      {
    237         call_user_func($this->Manager->OnUninstallModel, $Model::GetDesc(), $this);
     248        call_user_func($this->Manager->OnUninstallModel, $Model::GetModelDesc(), $this);
    238249      }
    239250    }
    240251  }
    241252}
    242 
    243 /* Manage installed modules */
    244 class AppModuleManager
    245 {
    246   public array $Modules;
    247   public System $System;
    248   public string $FileName;
    249   public string $ModulesDir;
    250   public $OnLoadModules;
    251   public $OnInstallModel;
    252   public $OnUninstsallModel;
    253   public $OnInstallModule;
    254   public $OnUninstsallModule;
    255 
    256   function __construct(System $System)
    257   {
    258     $this->Modules = array();
    259     $this->System = &$System;
    260     $this->FileName = dirname(__FILE__).'/../../Config/ModulesConfig.php';
    261     $this->ModulesDir = dirname(__FILE__).'/../../Modules';
    262     $this->OnInstallModel = null;
    263     $this->OnUninstallModel = null;
    264     $this->OnInstallModule = null;
    265     $this->OnUninstallModule = null;
    266   }
    267 
    268   function Perform(array $Actions, array $Conditions = array(ModuleCondition::All)): void
    269   {
    270     $this->PerformList($this->Modules, $Actions, $Conditions);
    271   }
    272 
    273   function PerformList(array $List, array $Actions, array $Conditions = array(ModuleCondition::All)): void
    274   {
    275     foreach ($List as $Module)
    276     {
    277       if (in_array(ModuleCondition::All, $Conditions) or
    278         ($Module->Running and in_array(ModuleCondition::Running, $Conditions)) or
    279         (!$Module->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or
    280         ($Module->Installed and in_array(ModuleCondition::Installed, $Conditions)) or
    281         (!$Module->Installed and in_array(ModuleCondition::NotInstalled, $Conditions)) or
    282         ($Module->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or
    283         (!$Module->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions)) or
    284         (($Module->Type == ModuleType::System) and in_array(ModuleCondition::System, $Conditions)) or
    285         (($Module->Type == ModuleType::Application) and in_array(ModuleCondition::Application, $Conditions)) or
    286         (($Module->Type == ModuleType::Library) and in_array(ModuleCondition::Library, $Conditions)))
    287       {
    288         foreach ($Actions as $Action)
    289         {
    290           if ($Action == ModuleAction::Start) $Module->Start();
    291           if ($Action == ModuleAction::Stop) $Module->Stop();
    292           if ($Action == ModuleAction::Install) $Module->Install();
    293           if ($Action == ModuleAction::Uninstall) $Module->Uninstall();
    294           if ($Action == ModuleAction::Enable) $Module->Enable();
    295           if ($Action == ModuleAction::Disable) $Module->Disable();
    296           if ($Action == ModuleAction::Upgrade) $Module->Upgrade();
    297         }
    298       }
    299     }
    300   }
    301 
    302   function EnumDependenciesCascade(AppModule $Module, array &$List, array $Conditions = array(ModuleCondition::All))
    303   {
    304     foreach ($Module->Dependencies as $Dependency)
    305     {
    306       if (!array_key_exists($Dependency, $this->Modules))
    307         throw new Exception(sprintf(T('Module "%s" dependency "%s" not found'), $Module->Name, $Dependency));
    308       $DepModule = $this->Modules[$Dependency];
    309       if (in_array(ModuleCondition::All, $Conditions) or
    310         ($DepModule->Running and in_array(ModuleCondition::Running, $Conditions)) or
    311         (!$DepModule->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or
    312         ($DepModule->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or
    313         (!$DepModule->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions)) or
    314         ($DepModule->Installed and in_array(ModuleCondition::Installed, $Conditions)) or
    315         (!$DepModule->Installed and in_array(ModuleCondition::NotInstalled, $Conditions)) or
    316         (($Module->Type == ModuleType::System) and in_array(ModuleCondition::System, $Conditions)) or
    317         (($Module->Type == ModuleType::Application) and in_array(ModuleCondition::Application, $Conditions)) or
    318         (($Module->Type == ModuleType::Library) and in_array(ModuleCondition::Library, $Conditions)))
    319       {
    320         array_push($List, $DepModule);
    321         $this->EnumDependenciesCascade($DepModule, $List, $Conditions);
    322       }
    323     }
    324   }
    325 
    326   function EnumSuperiorDependenciesCascade(AppModule $Module, array &$List, array $Conditions = array(ModuleCondition::All))
    327   {
    328     foreach ($this->Modules as $RefModule)
    329     {
    330       if (in_array($Module->Name, $RefModule->Dependencies) and
    331           (in_array(ModuleCondition::All, $Conditions) or
    332           ($RefModule->Running and in_array(ModuleCondition::Running, $Conditions)) or
    333           (!$RefModule->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or
    334           ($RefModule->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or
    335           (!$RefModule->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions)) or
    336           ($RefModule->Installed and in_array(ModuleCondition::Installed, $Conditions)) or
    337           (!$RefModule->Installed and in_array(ModuleCondition::NotInstalled, $Conditions)) or
    338           (($Module->Type == ModuleType::System) and in_array(ModuleCondition::System, $Conditions)) or
    339           (($Module->Type == ModuleType::Application) and in_array(ModuleCondition::Application, $Conditions)) or
    340           (($Module->Type == ModuleType::Library) and in_array(ModuleCondition::Library, $Conditions))))
    341         {
    342         array_push($List, $RefModule);
    343         $this->EnumSuperiorDependenciesCascade($RefModule, $List, $Conditions);
    344       }
    345     }
    346   }
    347 
    348   function StartAll(array $Conditions = array(ModuleCondition::All)): void
    349   {
    350     $this->Perform(array(ModuleAction::Start), $Conditions);
    351   }
    352 
    353   function StopAll(array $Conditions = array(ModuleCondition::All)): void
    354   {
    355     $this->Perform(array(ModuleAction::Stop), $Conditions);
    356   }
    357 
    358   function InstallAll(array $Conditions = array(ModuleCondition::All)): void
    359   {
    360     $this->Perform(array(ModuleAction::Install), $Conditions);
    361     $this->SaveState();
    362   }
    363 
    364   function UninstallAll(array $Conditions = array(ModuleCondition::All)): void
    365   {
    366     $this->Perform(array(ModuleAction::Uninstall), $Conditions);
    367     $this->SaveState();
    368   }
    369 
    370   function EnableAll(array $Conditions = array(ModuleCondition::All)): void
    371   {
    372     $this->Perform(array(ModuleAction::Enable), $Conditions);
    373     $this->SaveState();
    374   }
    375 
    376   function DisableAll(array $Conditions = array(ModuleCondition::All)): void
    377   {
    378     $this->Perform(array(ModuleAction::Disable), $Conditions);
    379     $this->SaveState();
    380   }
    381 
    382   function UpgradeAll(array $Conditions = array(ModuleCondition::All)): void
    383   {
    384     $this->Perform(array(ModuleAction::Upgrade), $Conditions);
    385     $this->SaveState();
    386   }
    387 
    388   function ModulePresent(string $Name): bool
    389   {
    390     return array_key_exists($Name, $this->Modules);
    391   }
    392 
    393   function ModuleEnabled(string $Name): bool
    394   {
    395     return array_key_exists($Name, $this->Modules) and $this->Modules[$Name]->Enabled;
    396   }
    397 
    398   function ModuleRunning(string $Name): bool
    399   {
    400     return array_key_exists($Name, $this->Modules) and $this->Modules[$Name]->Running;
    401   }
    402 
    403   function GetModule(string $Name): AppModule
    404   {
    405     return $this->Modules[$Name];
    406   }
    407 
    408   function SearchModuleById(int $Id): string
    409   {
    410     foreach ($this->Modules as $Module)
    411     {
    412       if ($Module->Id == $Id) return $Module->Name;
    413     }
    414     return '';
    415   }
    416 
    417   function LoadState(): void
    418   {
    419     $ConfigModules = array();
    420     include $this->FileName;
    421     foreach ($ConfigModules as $Mod)
    422     {
    423       $ModuleName = $Mod['Name'];
    424       if (array_key_exists($ModuleName, $this->Modules))
    425       {
    426         if (array_key_exists('Enabled', $Mod))
    427         {
    428           $this->Modules[$ModuleName]->Enabled = $Mod['Enabled'];
    429         }
    430         if (array_key_exists('Installed', $Mod))
    431         {
    432           $this->Modules[$ModuleName]->Installed = $Mod['Installed'];
    433         }
    434         if (array_key_exists('InstalledVersion', $Mod))
    435         {
    436           $this->Modules[$ModuleName]->InstalledVersion = $Mod['InstalledVersion'];
    437         }
    438       }
    439     }
    440   }
    441 
    442   function SaveState(): void
    443   {
    444     $Data = array();
    445     foreach ($this->Modules as $Module)
    446     {
    447       $Data[] = array(
    448         'Name' => $Module->Name,
    449         'Enabled' => $Module->Enabled,
    450         'InstalledVersion' => $Module->InstalledVersion,
    451         'Installed' => $Module->Installed
    452       );
    453     }
    454     if (file_put_contents($this->FileName, "<?php \n\n\$ConfigModules = ".var_export($Data, true).";\n") === FALSE)
    455     {
    456       echo($this->FileName.' is not writeable.');
    457     }
    458   }
    459 
    460   function RegisterModule(AppModule $Module): void
    461   {
    462     $this->Modules[$Module->Name] = &$Module;
    463     $Module->Manager = &$this;
    464     $Module->OnChange = &$this->OnModuleChange;
    465   }
    466 
    467   function UnregisterModule(AppModule $Module): void
    468   {
    469     unset($this->Modules[array_search($Module, $this->Modules)]);
    470   }
    471 
    472   function GetUniqueModuleId()
    473   {
    474     $Id = 1;
    475     foreach ($this->Modules as $Module)
    476     {
    477       if ($Module->Id >= $Id) $Id = $Module->Id + 1;
    478     }
    479     return $Id;
    480   }
    481 
    482   function LoadModule(string $FileName): AppModule
    483   {
    484     include_once($FileName);
    485     $ModuleName = 'Module'.pathinfo($FileName, PATHINFO_FILENAME);
    486     $Module = new $ModuleName($this->System);
    487     $Module->Id = $this->GetUniqueModuleId();
    488     $this->RegisterModule($Module);
    489     return $Module;
    490   }
    491 
    492   function LoadModulesFromDir(string $Directory): void
    493   {
    494     $List = scandir($Directory);
    495     foreach ($List as $Item)
    496     {
    497       if (is_dir($Directory.'/'.$Item) and ($Item != '.') and ($Item != '..') and ($Item != '.svn'))
    498       {
    499         $this->LoadModule($Directory.'/'.$Item.'/'.$Item.'.php');
    500       }
    501     }
    502   }
    503 
    504   function LoadModules(): void
    505   {
    506     if (is_array($this->OnLoadModules) and (count($this->OnLoadModules) == 2) and method_exists($this->OnLoadModules[0], $this->OnLoadModules[1]))
    507       call_user_func($this->OnLoadModules);
    508     else $this->LoadModulesFromDir($this->ModulesDir);
    509   }
    510 }
Note: See TracChangeset for help on using the changeset viewer.