Skip to content

Commit

Permalink
Merge pull request #142 from Arno2005/master
Browse files Browse the repository at this point in the history
Install default modules by command
  • Loading branch information
armanist authored Aug 6, 2024
2 parents c5fe125 + eb964a3 commit 31a4657
Show file tree
Hide file tree
Showing 73 changed files with 4,672 additions and 185 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"rakibtg/sleekdb": "^2.13",
"laminas/laminas-text": "^2.9",
"swagger-api/swagger-ui": "^4.14",
"zircote/swagger-php": "^4.4",
"zircote/swagger-php": "~4.4",
"psr/simple-cache": "^1.0",
"vaibhavpandeyvpz/phemail": "^1.1"

Expand Down
198 changes: 14 additions & 184 deletions src/Console/Commands/ModuleGenerateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@

namespace Quantum\Console\Commands;

use Quantum\Libraries\Module\ModuleManager;
use Quantum\Libraries\Storage\FileSystem;
use Quantum\Console\QtCommand;
use Quantum\Di\Di;
use Exception;

/**
* Class OpenApiUiAssetsCommand
* @package Quantum\Console\Commands
*/
class ModuleGenerateCommand extends QtCommand
{

/**
* File System
* @var FileSystem
Expand Down Expand Up @@ -62,199 +62,29 @@ class ModuleGenerateCommand extends QtCommand
* @var array
*/
protected $options = [
['yes', 'y', 'none', 'Module enabled status']
];

/**
* Folder names
* @var string[][]
*/
protected $folders = [
DS,
DS . 'Controllers',
DS . 'Models',
DS . 'Config',
DS . 'Views',
DS . 'Views' . DS . 'layouts',
DS . 'Views' . DS . 'partials',
['yes', 'y', 'none', 'Module enabled status'],
['template', 't', 'optional', 'The module template', 'web'],
['demo', 'd', 'optional', 'Use demo template', 'no'],
];

/**
* Executes the command
* @throws \Quantum\Exceptions\FileSystemException
* @throws \Quantum\Exceptions\DiException
* @throws Exception
*/
public function exec()
{
$this->fs = Di::get(FileSystem::class);
$newModuleName = ucfirst($this->getArgument('module'));
try {
$moduleName = $this->getArgument('module');

$modulesConfigPath = base_dir() . DS . 'shared' . DS . 'config' . DS . 'modules.php';
$modules = require_once $modulesConfigPath;
$moduleManager = new ModuleManager($moduleName, $this->getOption('template'), $this->getOption('demo'), $this->getOption('yes'));

foreach ($modules['modules'] as $module => $options) {
if ($module == $newModuleName || $options['prefix'] == strtolower($newModuleName)) {
$this->error('A module or prefix named ' . $newModuleName . ' already exists');
return;
}
}

$this->fs->put(
$modulesConfigPath,
str_replace(
"'modules' => [",
$this->addModuleConfig($newModuleName),
$this->fs->get($modulesConfigPath)
)
);
$moduleManager->addModuleConfig();

foreach ($this->folders as $folder) {
$this->fs->makeDirectory(modules_dir() . DS . $newModuleName . $folder);
}

$files = [
'Controllers' . DS . 'MainController.php' => $this->controllerTemplate($newModuleName),
'Views' . DS . 'index.php' => $this->viewTemplate($newModuleName),
'Views' . DS . 'layouts' . DS . 'main.php' => $this->viewLayoutsTemplate(),
'Views' . DS . 'partials' . DS . 'bubbles.php' => $this->viewBubblesTemplate(),
'Config' . DS . 'routes.php' => $this->routesTemplate(),
];
$moduleManager->writeContents();

foreach ($files as $file => $value) {
$this->fs->put(modules_dir() . DS . $newModuleName . DS . $file, $value);
$this->info($moduleName . ' module resources successfully published');
} catch (Exception $e) {
$this->error($e->getMessage());
}

$this->info($newModuleName . ' module resources successfully published');
}

/**
* Add module to config
* @param string $module
* @return string
*/
private function addModuleConfig(string $module): string
{
$enabled = $this->getOption('yes') ? "true" : "false";

return "'modules' => [
'" . $module . "' => [
'prefix' => '" . strtolower($module) . "',
'enabled' => " . $enabled . ",
],";
}

/**
* Controller template
* @param string $moduleName
* @return string
*/
private function controllerTemplate($moduleName)
{
return '<?php
namespace Modules\\' . $moduleName . '\Controllers;
use Quantum\Factory\ViewFactory;
use Quantum\Mvc\QtController;
use Quantum\Http\Response;
class MainController extends QtController
{
public function index(Response $response, ViewFactory $view)
{
$view->setLayout(\'layouts' . DS . 'main\');
$view->setParams([
\'title\' => config()->get(\'app_name\'),
]);
$response->html($view->render(\'index\'));
}
};';
}

/**
* View template
* @param string $moduleName
* @return string
*/
private function viewTemplate($moduleName)
{
return '<div class="main-wrapper teal accent-4">
<div class="container wrapper">
<div class="center-align white-text">
<div class="logo-block">
<img src="<?php echo base_url() ?>/assets/images/quantum-logo-white.png" alt="<?php echo config()->get(\'app_name\') ?>" />
</div>
<h1>' . strtoupper($moduleName) . ' HOME PAGE</h1>
</div>
</div>
</div>
<?php echo partial(\'partials' . DS . 'bubbles\') ?>';
}

/**
* View bubbles template
* @param string $moduleName
* @return string
*/
private function viewBubblesTemplate()
{
return '<ul class="bg-bubbles">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>';
}

/**
* viewLayouts template
* @return string
*/
private function viewLayoutsTemplate()
{
return '<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?php echo $title ?></title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="shortcut icon" href="<?php echo asset()->url(\'images/favicon.ico\') ?>">
<link rel=\'stylesheet\' href=\'<?php echo asset()->url(\'css/materialize.min.css\') ?>\' type=\'text/css\' media=\'screen,projection\' />
<link rel=\'stylesheet\' href=\'<?php echo asset()->url(\'css/custom.css\') ?>\' type=\'text/css\' />
</head>
<body>
<main><?php echo view() ?></main>
<?php echo debugbar() ?>
<script type=\'text/javascript\' src=\'<?php echo asset()->url(\'js/materialize.min.js\') ?>\'></script>
<script type=\'text/javascript\' src=\'<?php echo asset()->url(\'js/custom.js\') ?>\'></script>
</body>
</html>';
}

/**
* Routes template
* @return string
*/
private function routesTemplate()
{
return '<?php
use Quantum\Factory\ViewFactory;
use Quantum\Http\Response;
return function ($route) {
$route->get(\'/\', \'MainController\', \'index\');
};';
}
}
107 changes: 107 additions & 0 deletions src/Libraries/Module/ModuleManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php

namespace Quantum\Libraries\Module;

use Quantum\Di\Di;
use Quantum\Libraries\Storage\FileSystem;

class ModuleManager{

protected $fs;
protected $optionEnabled;

private $moduleName;
private $template;
private $demo;
private $modulePath;
private $templatePath;

function __construct(string $moduleName, string $template, string $demo, $enabled){
$this->moduleName = $moduleName;

$this->template = $template;

$this->demo = $demo;

$this->optionEnabled = $enabled;

$type = $this->demo == "yes" ? "Demo" : "Default";

$this->templatePath = __DIR__ . DS . "Templates" . DS . $type . DS . ucfirst($this->template);

$this->modulePath = modules_dir() . DS . $this->moduleName;

$this->fs = Di::get(FileSystem::class);
}

public function writeContents()
{
if (!$this->fs->isDirectory(modules_dir())) {
$this->fs->makeDirectory(modules_dir());
}
$this->copyDirectoryWithTemplates($this->templatePath, $this->modulePath);
}

public function addModuleConfig()
{
$modulesConfigPath = base_dir() . DS . 'shared' . DS . 'config' . DS . 'modules.php';
$modules = require $modulesConfigPath;

foreach ($modules['modules'] as $module => $options) {
if ($module == $this->moduleName || $options['prefix'] == strtolower($this->moduleName)) {
throw new \Exception("A module or prefix named '$this->moduleName' already exists");
}
}

$this->fs->put(
$modulesConfigPath,
str_replace(
"'modules' => [",
$this->writeModuleConfig($this->moduleName),
$this->fs->get($modulesConfigPath)
)
);
}

private function copyDirectoryWithTemplates($src, $dst) {
if (!$this->fs->isDirectory($src)) {
throw new \Exception("Directory '$src' does not exist");
}

if (!$this->fs->isDirectory($dst)) {
$this->fs->makeDirectory($dst);
}

$dir = $this->fs->listDirectory($src);

foreach ($dir as $file) {
$srcPath = $file;
$dstPath = str_replace($src, $dst, $file);

if ($this->fs->isDirectory($srcPath)) {
$this->copyDirectoryWithTemplates($srcPath, $dstPath);
} else {
$processedContent = require_once $srcPath;
$this->fs->put($dstPath, $processedContent);
}
}
}

/**
* Add module to config
* @param string $module
* @return string
*/
private function writeModuleConfig(string $module): string
{
$enabled = $this->optionEnabled ? "true" : "false";

$prefix = $this->template == "web" && $this->demo == "yes" ? "" : strtolower($module);

return "'modules' => [
'" . $module . "' => [
'prefix' => '" . $prefix . "',
'enabled' => " . $enabled . ",
],";
}
}
17 changes: 17 additions & 0 deletions src/Libraries/Module/Templates/Default/Api/Config/cors.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

return '<?php
return [
/**
* ---------------------------------------------------------
* Cross-Origin Resource Sharing (CORS) Configuration
* ---------------------------------------------------------
* Settings defined here determines the cross-origin resource sharing
*/
\'Access-Control-Allow-Origin\' => \'*\',
\'Access-Control-Allow-Headers\' => \'Origin, X-Requested-With, Content-Type, Accept, Authorization, refresh_token\',
\'Access-Control-Allow-Methods\' => \'GET, POST, PUT, DELETE, OPTIONS\',
\'Access-Control-Allow-Credentials\' => true,
];
';
20 changes: 20 additions & 0 deletions src/Libraries/Module/Templates/Default/Api/Config/routes.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

return '<?php
use Quantum\Factory\ViewFactory;
use Quantum\Http\Response;
return function ($route) {
$route->group("openapi", function ($route) {
$route->get("docs", function (Quantum\Http\Response $response) {
$response->html(partial("openApi/openApi"));
});
$route->get("spec", function (Quantum\Http\Response $response) {
$fs = Quantum\Di\Di::get(Quantum\Libraries\Storage\FileSystem::class);
$response->json((array) json_decode($fs->get(modules_dir() . "\Api\Resources\openapi\spec.json")));
});
});
$route->get(\'/\', \'MainController\', \'index\');
};';
Loading

0 comments on commit 31a4657

Please sign in to comment.