Sistema web para crear proyecto web nuevo

This commit is contained in:
2020-07-03 17:21:55 -04:00
parent af3507bda5
commit ad3952501f
53 changed files with 2437 additions and 0 deletions

View File

@ -0,0 +1,62 @@
<?php
namespace ProVM\Projects\Common\Controller\API;
use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use ProVM\Common\Define\Controller\Json;
use ProVM\Projects\Common\Service\Projects;
class Create {
use Json;
public function createFolder(Request $request, Response $response, Projects $service, $project): Response {
$estado = $service->createFolder($project);
$output = [
'project' => $project,
'estado' => $estado
];
return $this->withJson($response, $output);
}
public function createSubfolders(Request $request, Response $response, Projects $service, $project): Response {
$estado = $service->createSubfolders($project);
$output = [
'project' => $project,
'estado' => $estado
];
return $this->withJson($response, $output);
}
public function gitInit(Request $request, Response $response, Projects $service, $project): Response {
$estado = $service->gitInit($project);
$output = [
'project' => $project,
'estado' => $estado
];
return $this->withJson($response, $output);
}
public function addComposer(Request $request, Response $response, Projects $service, $project): Response {
$post = $request->getParsedBody();
$estado = $service->addComposer($project, $post['composer']);
$output = [
'project' => $project,
'estado' => $estado
];
return $this->withJson($response, $output);
}
public function addFiles(Request $request, Response $response, Projects $service, $project): Response {
$estado = $service->addFiles($project);
$output = [
'project' => $project,
'estado' => $estado
];
return $this->withJson($response, $output);
}
public function gitPush(Request $request, Response $response, Projects $service, $project): Response {
$estado = $service->gitPush($project);
$output = [
'project' => $project,
'estado' => $estado['estado'],
'error' => $estado['error']
];
return $this->withJson($response, $output);
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace ProVM\Projects\Common\Controller\API;
use Psr\Container\ContainerInterface as Container;
use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use ProVM\Common\Define\Controller\Json;
use ProVM\Common\Service\Composer;
class Dependencies {
use Json;
public function search(Request $request, Response $response, Composer $composer): Response {
$get = $request->getQueryParams();
$query = $get['query'];
if (strlen($query) < 3) {
$output = [
'success' => false,
'results' => []
];
return $this->withJson($response, $output);
}
$results = $composer->search($query);
$output = [
'success' => (count($results) > 0),
'results' => []
];
foreach ($results as $result) {
$output['results'] []= [
'value' => $result->name,
'name' => implode(': ', (array) $result),
'text' => $result->name
];
}
return $this->withJson($response, $output);
}
}

View File

@ -0,0 +1,75 @@
<?php
namespace ProVM\Projects\Common\Controller\Web;
use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use ProVM\Common\Alias\View;
use ProVM\Common\Service\Composer;
use ProVM\Projects\Common\Service\Projects;
class Create {
/**
* Step 1
* Formulario de datos
*/
public function __invoke(Request $request, Response $response, View $view): Response {
$defaults = (object) [
'require' => [
'slim/slim',
'nyholm/psr7',
'nyholm/psr7-server',
'php-di/slim-bridge',
'rubellum/slim-blade-view',
'nesbot/carbon'
],
'require-dev' => [
'phpunit/phpunit',
'kint-php/kint'
]
];
return $view->render($response, 'create.step1', compact('defaults'));
}
/**
* Step 2
* Revision y confirmacion de datos
*/
public function step2(Request $request, Response $response, Composer $composer, Projects $service, View $view): Response {
$post = $request->getParsedBody();
$name = $post['nombre'];
$exists = $service->exists($name);
$require = explode(',', $post['dependencias'][0]);
$require = $composer->getLatest($require, Composer::MAYOR);
$require_dev = explode(',', $post['dependencias-dev'][0]);
$require_dev = $composer->getLatest($require_dev, Composer::MAYOR);
$json = json_encode([
'name' => implode('/', ['provm', $name]),
'descripcion' => $post['descripcion'],
'type' => 'project',
'require' => $require,
'require-dev' => $require_dev,
'authors' => [
[
'name' => 'Aldarien',
'email' => 'aldarien85@gmail.com'
]
],
'autoload' => [
'psr-4' => [
implode("\\", [
'ProVM',
ucwords($post['nombre']),
'Common'
]) . "\\" => 'common'
]
]
], \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE);
return $view->render($response, 'create.step2', ['step' => 2, 'exists' => $exists, 'composer' => $json]);
}
public function step3(Request $request, Response $response, Projects $service, View $view): Response {
$post = $request->getParsedBody();
$name = explode('/', json_decode($post['composer'])->name)[1];
$composer = $post['composer'];
$step = 3;
return $view->render($response, 'create.step3', compact('step', 'name', 'composer'));
}
}

View File

@ -0,0 +1,14 @@
<?php
namespace ProVM\Projects\Common\Controller\Web;
use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use ProVM\Common\Alias\View;
use ProVM\Projects\Common\Service\Projects;
class Home {
public function __invoke(Request $request, Response $response, Projects $service, View $view): Response {
$projects = $service->list();
return $view->render($response, 'home', compact('projects'));
}
}

View File

@ -0,0 +1,181 @@
<?php
namespace ProVM\Projects\Common\Controller\Web;
use Psr\Container\ContainerInterface as Container;
use Psr\Http\Message\RequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use ProVM\Common\Alias\View;
use ProVM\Common\Define\Controller\Redirect;
use ProVM\Projects\Common\Service\Projects;
use ProVM\Projects\Common\Factory\Project as Factory;
class Project {
use Redirect;
public function __invoke(Request $request, Response $response, Projects $service, View $view, $project): Response {
$p = $service->get($project);
$p->config = $this->reduceFiles($p->config, '/setup', '', '/');
$p->controllers = $this->reduceFiles($p->controllers, ['/common', 'ProVM/' . ucwords($project) . '/Common'], '.php', '/');
foreach ($p->routes as $space => $routes) {
$p->routes->$space = $this->reduceFiles($routes, '/resources/routes', '', '/');
}
$p->views = $this->reduceFiles($p->views, '/resources/views/', '.blade.php', '.');
return $view->render($response, 'projects.show', ['project' => $p]);
}
protected function reduceFiles($array, $prefix, $suffix, $glue) {
if (!is_array($prefix)) {
$prefix = [$prefix];
}
if (!is_array($suffix)) {
$suffix = [$suffix];
}
$arr = [];
$it = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($array), \RecursiveIteratorIterator::SELF_FIRST);
$pk = '';
foreach ($it as $k => $v) {
if (is_array($v)) {
$pk = str_replace($prefix[0], $prefix[1] ?? '', $k);
continue;
}
$arr []= str_replace($suffix[0], $suffix[1] ?? '', implode($glue, [$pk, $v]));
}
return $arr;
}
public function addView(Request $request, Response $response, Projects $service, View $view, $project): Response {
$folder = implode(DIRECTORY_SEPARATOR, [
$service->getFolder($project),
'resources',
'views'
]);
$files = new \DirectoryIterator($folder);
$subfolders = [];
foreach ($files as $file) {
if (!$file->isDir() or $file->isDot()) {
continue;
}
$subfolders []= $file->getBasename();
}
$factory = new Factory();
$p = $factory->find($service->getFolder($project))->getViews()->build();
$views = [];
$it = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($p->views), \RecursiveIteratorIterator::SELF_FIRST);
$pk = '';
foreach ($it as $k => $v) {
if (is_array($v)) {
$pk = str_replace('/resources/views/', '', $k);
continue;
}
$views []= str_replace('.blade.php', '', implode('.', [$pk, $v]));
}
$project = $p;
return $view->render($response, 'projects.views.add', compact('project', 'subfolders', 'views'));
}
public function doAddView(Request $request, Response $response, Container $container, Projects $service, $project): Response {
$post = $request->getParsedBody();
$options = [];
if (trim($post['extends']) != '') {
$options['extends'] = $post['extends'];
}
if (trim($post['seccion']) != '') {
$options['section'] = $post['seccion'];
}
$location = $post['location'];
$status = $service->addView($project, $post['name'], $location, $options);
return $this->withRedirect($response, implode('/', [
$container->get('urls')->base,
'project',
$project
]));
}
public function addController(Request $request, Response $response, Projects $service, View $view, $project): Response {
$folder = implode(DIRECTORY_SEPARATOR, [
$service->getFolder($project),
'common',
'Controller'
]);
$files = new \DirectoryIterator($folder);
$subfolders = [];
foreach ($files as $file) {
if (!$file->isDir() or $file->isDot()) {
continue;
}
$subfolders []= $file->getBasename();
}
$factory = new Factory();
$p = $factory->find($service->getFolder($project))->getViews()->build();
$views = [];
$it = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($p->views), \RecursiveIteratorIterator::SELF_FIRST);
$pk = '';
foreach ($it as $k => $v) {
if (is_array($v)) {
$pk = str_replace('/resources/views/', '', $k);
continue;
}
$views []= str_replace('.blade.php', '', implode('.', [$pk, $v]));
}
$project = $p;
return $view->render($response, 'projects.controllers.add', compact('project', 'subfolders', 'views'));
}
public function doAddController(Request $request, Response $response, Container $container, Projects $service, $project): Response {
$post = $request->getParsedBody();
$name = str_replace(' ', '', ucwords($post['name']));
$status = $service->addController($project, $post['space'], $name, $post['template']);
return $this->withRedirect($response, implode('/', [
$container->get('urls')->base,
'project',
$project
]));
}
public function addRoute(Request $request, Response $response, Projects $service, View $view, $project): Response {
$folder = implode(DIRECTORY_SEPARATOR, [
$service->getFolder($project),
'resources',
'routes'
]);
$files = new \DirectoryIterator($folder);
$subfolders = [];
foreach ($files as $file) {
if (!$file->isDir() or $file->isDot()) {
continue;
}
$subfolders []= $file->getBasename();
}
$factory = new Factory();
$p = $factory->find($service->getFolder($project))->getViews()->getControllers()->build();
$views = [];
$it = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($p->views), \RecursiveIteratorIterator::SELF_FIRST);
$pk = '';
foreach ($it as $k => $v) {
if (is_array($v)) {
$pk = str_replace('/resources/views/', '', $k);
continue;
}
$views []= str_replace('.blade.php', '', implode('.', [$pk, $v]));
}
$controllers = [];
$it = new \RecursiveIteratorIterator(new \RecursiveArrayIterator($p->controllers), \RecursiveIteratorIterator::SELF_FIRST);
$pk = '';
foreach ($it as $k => $v) {
if (is_array($v)) {
$pk = str_replace('/common', 'ProVM/Projects/Common', $k);
continue;
}
$controllers []= str_replace(['/', '.php'], ["\\", ''], implode('/', [$pk, $v]));
}
$project = $p;
return $view->render($response, 'projects.routes.add', compact('project', 'subfolders', 'views', 'controllers'));
}
public function doAddRoute(Request $request, Response $response, Container $container, Projects $service, $project): Response {
$post = $request->getParsedBody();
$space = $post['space'];
$name = $post['group'];
$route = $post['name'];
$callback = $post['controller'] . '::class';
$service->addRoute($project, $space, $name, $route, $callback);
return $this->withRedirect($response, implode('/', [
$container->get('urls')->base,
'project',
$project
]));
}
}

135
common/Factory/Project.php Normal file
View File

@ -0,0 +1,135 @@
<?php
namespace ProVM\Projects\Common\Factory;
use Cz\Git\GitRepository;
class Project {
protected $folder;
protected $data;
public function find(string $folder): Project {
if (!file_exists($folder)) {
throw new \Exception('Proyecto no existe. ' . $folder);
}
$this->folder = realpath($folder);
$name = array_pop(explode(DIRECTORY_SEPARATOR, $this->folder));
$this->data = [
'name' => implode('/', ['provm', $name]),
'base_name' => $name,
'folder' => $this->folder
];
return $this;
}
public function build() {
return json_decode(json_encode($this->data));
}
public function getAll(): Project {
return $this
->getGit()
->getComposer()
->getConfig()
->getControllers()
->getServices()
->getRoutes()
->getViews();
}
public function getGit(): Project {
$repo = new GitRepository($this->folder);
$status = $repo->execute('status');
$this->data['git'] = $status;
return $this;
}
public function getComposer(): Project {
$filename = implode(DIRECTORY_SEPARATOR, [$this->folder, 'composer.json']);
$this->data['composer'] = json_decode(trim(file_get_contents($filename)));
return $this;
}
protected function getFolderFiles(string $name, string $folder) {
if (!file_exists($folder)) {
return $this;
}
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folder));
$output = [];
foreach ($files as $file) {
if ($file->isDir()) {
continue;
}
$dir = rtrim(str_replace([$file->getBasename(), $this->folder, "\\"], ['', '', '/'], $file->getRealPath()), '/');
if (!isset($output[$dir])) {
$output[$dir] = [];
}
$output[$dir] []= $file->getBasename();
}
ksort($output);
$this->data[$name] = $output;
}
public function getConfig(): Project {
$folder = implode(DIRECTORY_SEPARATOR, [
$this->folder,
'setup'
]);
$this->getFolderFiles('config', $folder);
return $this;
}
public function getControllers(): Project {
$folder = implode(DIRECTORY_SEPARATOR, [$this->folder, 'common', 'Controller']);
$this->getFolderFiles('controllers', $folder);
return $this;
}
public function getServices(): Project {
$folder = implode(DIRECTORY_SEPARATOR, [$this->folder, 'common', 'Service']);
$this->getFolderFiles('services', $folder);
return $this;
}
public function getRoutes(): Project {
$folder = implode(DIRECTORY_SEPARATOR, [
$this->folder,
'resources',
'routes'
]);
$output = [];
$folders = new \DirectoryIterator($folder);
foreach ($folders as $folder) {
if (!$folder->isDir() or $folder->isDot()) {
continue;
}
$output[$folder->getBasename()] = $this->getSpaceRoutes($folder->getRealPath());
}
$this->data['routes'] = $output;
return $this;
}
protected function getSpaceRoutes(string $folder) {
if (!file_exists($folder)) {
return [];
}
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($folder));
$output = [];
foreach ($files as $file) {
if ($file->isDir()) {
continue;
}
$dir = rtrim(str_replace([$file->getBasename(), $this->folder, "\\"], ['', '', '/'], $file->getRealPath()), '/');
if (!isset($output[$dir])) {
$output[$dir] = [];
}
$output[$dir] []= $file->getBasename();
}
ksort($output);
return $output;
}
public function getViews(): Project {
$folder = implode(DIRECTORY_SEPARATOR, [
$this->folder,
'resources',
'views'
]);
$this->getFolderFiles('views', $folder);
/*array_walk($this->data['views'], function(&$item) {
if (is_array($item)) {
array_walk($item, function(&$i) {
$i = str_replace('.blade', '', $i);
});
}
});*/
return $this;
}
}

733
common/Service/Projects.php Normal file
View File

@ -0,0 +1,733 @@
<?php
namespace ProVM\Projects\Common\Service;
use Cz\Git\GitRepository;
use ProVM\Projects\Common\Factory\Project as Factory;
class Projects {
protected $folder;
public function __construct(string $projects_folder) {
$this->folder = $projects_folder;
}
public function getFolder(string $project = ''): string {
if (trim($project) == '') {
return $this->folder;
}
return implode(DIRECTORY_SEPARATOR, [
$this->folder,
$project
]);
}
protected $projects;
public function list(): array {
if ($this->projects === null) {
$folders = [];
$files = new \DirectoryIterator($this->folder);
foreach ($files as $file) {
if (!$file->isDir() or $file->isDot()) {
continue;
}
$folders []= (object) [
'name' => $file->getBasename(),
'folder' => $file->getRealPath()
];
}
$this->projects = $folders;
}
return $this->projects;
}
public function exists(string $project): bool {
$folder = $this->getFolder($project);
return file_exists($folder);
}
public function get(string $project) {
$folder = $this->getFolder($project);
$factory = new Factory();
return $factory
->find($folder)
->getAll()
->build();
}
public function create(string $project) {
$this->createFolder($project);
}
public function createFolder(string $project): bool {
if ($this->exists($project)) {
return false;
}
$folder = $this->getFolder($project);
$status = mkdir($folder);
$status &= file_exists($folder);
return $status;
}
public function createSubfolders(string $project): bool {
if (!$this->exists($project)) {
return false;
}
$folders = [
'cache',
'common',
'common/Controller',
'common/Controller/Web',
'public',
'resources',
'resources/routes',
'resources/routes/web',
'resources/views',
'resources/views/layout',
'setup',
'setup/env',
'setup/common',
'setup/web'
];
$status = false;
foreach ($folders as $folder) {
$f = implode(DIRECTORY_SEPARATOR, [
$this->folder,
$project,
$folder
]);
if (file_exists($f)) {
continue;
}
$status |= mkdir($f);
}
return $status;
}
public function gitInit(string $project): bool {
if (!$this->exists($project)) {
return false;
}
$content = [
'# Composer',
'/vendor/',
'composer.lock',
'',
'# Blade',
'/cache/',
'',
'# Env',
'/setup/env/'
];
$folder = implode(DIRECTORY_SEPARATOR, [
$this->folder,
$project
]);
$filename = implode(DIRECTORY_SEPARATOR, [
$folder,
'.gitignore'
]);
$status = (file_put_contents($filename, implode(PHP_EOL, $content)) !== false);
$repo = GitRepository::init($folder);
$repo->execute([
'config',
'--global',
'user.name',
'Aldarien'
]);
$repo->execute([
'config',
'--global',
'user.email',
'aldarien85@gmail.com'
]);
$repo->addFile('.gitignore');
$repo->commit('Inicio de Git');
$repo->createBranch('develop', true);
return $status;
}
public function addComposer(string $project, string $json): bool {
if (!$this->exists($project)) {
return false;
}
$folder = $this->getFolder($project);
$filename = implode(DIRECTORY_SEPARATOR, [
$folder,
'composer.json'
]);
$status = (file_put_contents($filename, $json) !== false);
$current = getcwd();
$s = chdir($folder);
if ($s) {
exec('composer install');
$status &= (file_exists(implode(DIRECTORY_SEPARATOR, [$folder, 'vendor'])));
chdir($current);
}
return $status;
}
public function addFiles(string $project): bool {
if (!$this->exists($project)) {
return false;
}
$folder = $this->getFolder($project);
$methods = [
'SetupApp',
'SetupComposer',
'SetupCommonConfig',
'SetupWebConfig',
'SetupWebSetup',
'PublicIndex',
'PublicHtaccess',
'RoutesRouter',
'RoutesWeb',
'LayoutBase',
'LayoutBody',
'LayoutFooter',
'LayoutHead',
'LayoutHeader',
'LayoutMenu',
'LayoutScripts',
'LayoutStyles'
];
$status = true;
foreach ($methods as $method) {
$m = 'add' . $method . 'File';
$status &= $this->$m($folder);
}
return $status;
}
protected function createFile(string $folder, string $file_name, array $content): bool {
$filename = implode(DIRECTORY_SEPARATOR, [
$folder,
$file_name
]);
$status = (file_put_contents($filename, implode(PHP_EOL, $content)) !== false);
$status &= file_exists($filename);
return $status;
}
protected function addSetupAppFile(string $folder): bool {
$content = [
"<?php",
"use DI\ContainerBuilder as Builder;",
"use DI\Bridge\Slim\Bridge;",
'',
"if (!isset(\$__environment)) {",
" throw new Exception('Missing __environment variable');",
"}",
'',
"include_once 'composer.php';",
'',
"\$builder = new Builder();",
'',
"\$files = [",
" 'config',",
" 'setup'",
"];",
"\$folders = [",
" 'common',",
" \$__environment",
"];",
'',
"foreach (\$files as \$file) {",
" foreach (\$folders as \$folder) {",
" \$filename = implode(DIRECTORY_SEPARATOR, [",
" __DIR__,",
" \$folder,",
" \$file . '.php'",
" ]);",
" if (file_exists(\$filename)) {",
" \$builder->addDefinitions(\$filename);",
" }",
" }",
"}",
'',
"\$container = \$builder->build();",
"\$app = Bridge::create(\$container);",
"try {",
" \$app->setBasePath(\$container->get('base_url'));",
"} catch (Exception \$e) {",
"}",
'',
"foreach (\$folders as \$folder) {",
" \$filename = implode(DIRECTORY_SEPARATOR, [",
" __DIR__,",
" \$folder,",
" 'middleware.php'",
" ]);",
" if (file_exists(\$filename)) {",
" include_once \$filename;",
" }",
"}",
'',
"\$filename = implode(DIRECTORY_SEPARATOR, [",
" \$container->get('folders')->routes,",
" 'router.php'",
"]);",
"if (!file_exists(\$filename)) {",
" throw new Exception('Missing router file.');",
"}",
"include_once \$filename;"
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'setup'
]);
return $this->createFile($folder, 'app.php', $content);
}
protected function addSetupComposerFile(string $folder): bool {
$content = [
'<?php',
"\$filename = implode(DIRECTORY_SEPARATOR, [",
" dirname(__DIR__)",
" 'vendor'",
" 'autoload.php'",
"])",
"if (!file_exists(\$filename)) {",
" throw new Exception('Missing composer install.');",
"}",
"include_once \$filename;"
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'setup'
]);
return $this->createFile($folder, 'composer.php', $content);
}
protected function addSetupCommonConfigFile(string $folder): bool {
$project = explode(DIRECTORY_SEPARATOR, $folder);
array_pop($project); // common
array_pop($project); // setup
$project = array_pop($project);
$content = [
'<?php',
'return [',
" 'base_url' => dirname(__DIR__),",
" 'urls' => function() {",
" \$arr = [];",
" \$arr['base'] = '/provm/demos/{$project}';",
" return (object) \$arr;",
" },",
" 'folders' => function() {",
" \$arr = [];",
" \$arr['base'] = dirname(__DIR__, 2);",
" \$arr['resources'] = implode(DIRECTORY_SEPARATOR, [",
" \$arr['base'],",
" 'resources'",
" ]);",
" \$arr['routes'] = implode(DIRECTORY_SEPARATOR, [",
" \$arr['resources'],",
" 'routes'",
" ]);",
" return (object) \$arr;",
" }",
'];'
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'setup',
'common'
]);
return $this->createFile($folder, 'config.php', $content);
}
protected function addSetupWebConfigFile(string $folder): bool {
$content = [
"<?php",
"use Psr\Container\ContainerInterface as Container;",
'',
"return [",
" 'folders' => DI\decorate(function(\$prev, Container \$c) {",
" \$arr = (array) \$prev;",
" \$arr['templates'] = implode(DIRECTORY_SEPARATOR, [",
" \$prev->resources,",
" 'views'",
" ]);",
" \$arr['cache'] = implode(DIRECTORY_SEPARATOR, [",
" \$prev->base,",
" 'cache'",
" ]);",
" return (object) \$arr;",
" }),",
" 'assets' => (object) [",
" 'styles' => [",
" 'https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.6/semantic.min.css'",
" ],",
" 'scripts' => [",
" 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js',",
" 'https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.6/semantic.min.js'",
" ],",
" 'fonts' => [",
" 'https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.6/themes/default/assets/fonts/brand-icons.woff',",
" 'https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.6/themes/default/assets/fonts/brand-icons.woff2',",
" 'https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.6/themes/default/assets/fonts/icons.woff',",
" 'https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.6/themes/default/assets/fonts/icons.woff2',",
" 'https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.6/themes/default/assets/fonts/outline-icons.woff',",
" 'https://cdnjs.cloudflare.com/ajax/libs/fomantic-ui/2.8.6/themes/default/assets/fonts/outline-icons.woff2'",
" ]",
" ]",
"];"
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'setup',
'web'
]);
return $this->createFile($folder, 'config.app', $content);
}
protected function addSetupWebSetupFile(string $folder): bool {
$content = [
"<?php",
"use Psr\Container\ContainerInterface as Container;",
'',
"return [",
" ProVM\Common\Alias\View::class => function(Container \$c) {",
" return new ProVM\Common\Define\View(",
" \$c->get('folders')->templates,",
" \$c->get('folders')->cache,",
" null,",
" [",
" 'urls' => \$c->get('urls'),",
" 'assets' => \$c->get('assets')",
" ]",
" );",
" }",
"];"
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'setup',
'web'
]);
return $this->createFile($folder, 'setup.php', $content);
}
protected function addPublicIndexFile(string $folder): bool {
$content = [
"<?php",
"\$__environment = 'web';",
"include_once implode(DIRECTORY_SEPARATOR, [",
" dirname(__DIR__),",
" 'setup',",
" 'app.php'",
"]);",
"\$app->run();",
""
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'public'
]);
return $this->createFile($folder, 'index.php', $content);
}
protected function addPublicHtaccessFile(string $folder): bool {
$content = [
"RewriteEngine On",
"RewriteCond %{REQUEST_FILENAME} !-f",
"RewriteCond %{REQUEST_FILENAME} !-d",
"RewriteRule ^ index.php [QSA,L]"
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'public'
]);
return $this->createFile($folder, '.htaccess', $content);
}
protected function addRoutesRouterFile(string $folder): bool {
$content = [
"<?php",
"include_once $__environment . '.php';",
""
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'resources',
'routes'
]);
return $this->createFile($folder, 'router.php', $content);
}
protected function addRoutesWebFile(string $folder): bool {
$content = [
"<?php",
"\$folder = implode(DIRECTORY_SEPARATOR, [",
" __DIR__,",
" 'web'",
"]);",
"if (file_exists(\$folder)) {",
" \$files = new DirectoryIterator(\$folder);",
" foreach (\$files as \$file) {",
" if (\$file->isDir()) {",
" continue;",
" }",
" include_once \$file->getRealPath();",
" }",
"}"
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'resources',
'routes'
]);
return $this->createFile($folder, 'web.php', $content);
}
protected function addLayoutBaseFile(string $folder): bool {
$content = [
"<!DOCTYPE html>",
"<html lang=\"es\">",
"@include('layout.head')",
"@include('layout.body')",
"</html>",
""
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'resources',
'views',
'layout'
]);
return $this->createFile($folder, 'base.blade.php', $content);
}
protected function addLayoutBodyFile(string $folder): bool {
$content = [
"<body>",
" @include('layout.header')",
" <div class=\"ui container\">",
" <div class=\"ui basic segment\">",
" @yield('page_content')",
" </div>",
" </div>",
" @include('layout.footer')",
"</body>",
""
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'resources',
'views',
'layout'
]);
return $this->createFile($folder, 'body.blade.php', $content);
}
protected function addLayoutFooterFile(string $folder): bool {
$content = ["@include('layout.scripts')"];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'resources',
'views',
'layout'
]);
return $this->createFile($folder, 'footer.blade.php', $content);
}
protected function addLayoutHeadFile(string $folder): bool {
$content = [
"<head>",
" <meta charset=\"utf8\" />",
" <title>@yield('page_title')</title>",
" @include('layout.styles')",
"</head>",
""
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'resources',
'views',
'layout'
]);
return $this->createFile($folder, 'head.blade.php', $content);
}
protected function addLayoutHeaderFile(string $folder): bool {
$content = [
"<header class=\"ui container\">",
" @include('layout.menu')",
"</header>",
""
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'resources',
'views',
'layout'
]);
return $this->createFile($folder, 'header.blade.php', $content);
}
protected function addLayoutMenuFile(string $folder): bool {
$content = [
"<nav class=\"ui menu\">",
" <a class=\"item\" href=\"{{$urls->base}}\">Inicio</a>",
" <a class=\"item\" href=\"{{$urls->base}}/create\">Crear</a>",
"</nav>",
""
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'resources',
'views',
'layout'
]);
return $this->createFile($folder, 'menu.blade.php', $content);
}
protected function addLayoutScriptsFile(string $folder): bool {
$content = [
"@if (isset(\$assets->scripts))",
" @foreach (\$assets->scripts as \$script)",
" <script type=\"text/javascript\" src=\"{{\$script}}\"></script>",
" @endforeach",
"@endif",
"",
"<script type=\"text/javascript\">",
" \$(document).ready(() => {",
" @stack('global_script')",
" })",
"</script>",
"",
"@stack('scripts')",
""
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'resources',
'views',
'layout'
]);
return $this->createFile($folder, 'scripts.blade.php', $content);
}
protected function addLayoutStylesFile(string $folder): bool {
$content = [
"@if (isset(\$assets->styles))",
" @foreach (\$assets->styles as \$style)",
" <link rel=\"stylesheet\" type=\"text/css\" href=\"{{\$style}}\" />",
" @endforeach",
"@endif",
"@if (isset(\$assets->fonts))",
" @foreach (\$assets->fonts as \$font)",
" <link href=\"{{\$font}}\" />",
" @endforeach",
"@endif",
"",
"@stack('styles')",
"",
"<style type=\"text/css\">",
" @stack('global_style')",
"</style>",
""
];
$folder = implode(DIRECTORY_SEPARATOR, [
$folder,
'resources',
'views',
'layout'
]);
return $this->createFile($folder, 'styles.blade.php', $content);
}
public function gitPush(string $project): bool {
if (!$this->exists($project)) {
return false;
}
$folder = implode(DIRECTORY_SEPARATOR, [
$this->folder,
$project
]);
$repo = new GitRepository($folder);
$repo->execute([
'config',
'--global',
'user.name',
'Aldarien'
]);
$repo->execute([
'config',
'--global',
'user.email',
'aldarien85@gmail.com'
]);
$repo->addAllChanges();
$repo->commit('Seteo inicial');
$repo->addRemote('provm', 'http://git.provm.cl/ProVM/' . $project . '.git');
$repo->push('provm', ['develop', '-u']);
return true;
}
public function addView(string $project, string $name, string $location = '', array $options = []): bool {
$content = [];
if (isset($options['extends'])) {
$content []= '@extends("' . $options['extends'] . '")';
}
if (isset($options['section'])) {
$content []= '@section("' . $options['section'] . '")';
$content []= '@endsection';
}
$folder = [
$this->folder,
$project,
'resources',
'views'
];
if (trim($location) != '') {
$folder []= trim($location);
}
$folder = implode(DIRECTORY_SEPARATOR, $folder);
if (!file_exists($folder)) {
mkdir($folder);
}
$filename = $name . '.blade.php';
return $this->createFile($folder, $filename, $content);
}
public function addRoute(string $project, string $space, string $file_name, string $route, $callback, string $method = 'get'): bool {
$folder = implode(DIRECTORY_SEPARATOR, [
$this->folder,
$project,
'resources',
'routes',
$space
]);
$content = [
'<?php'
];
$filename = implode(DIRECTORY_SEPARATOR, [$folder, $file_name . '.php']);
if (file_exists($filename)) {
$content = trim(file_get_contents($filename));
if (strpos($content, $route) !== false) {
return false;
}
$content = explode(PHP_EOL, $content);
}
$content []= "\$app->{$method}('{$route}', {$callback});";
return $this->createFile($folder, $file_name . '.php', $content);
}
public function addController(string $project, string $space, string $name, string $template): bool {
$name = str_replace(' ', '', ucwords($name));
$content = [
'<?php',
'namespace ' . implode("\\", [
'ProVM',
ucwords($project),
'Common',
'Controller',
ucwords($space)
]) . ';',
'',
'use ' . implode("\\", [
'Psr',
'Http',
'Message',
'RequestInterface'
]) . ' as Request;',
'use ' . implode("\\", [
'Psr',
'Http',
'Message',
'ResponseInterface'
]) . ' as Response;',
'use ' . implode("\\", [
'ProVM',
'Common',
'Define',
'View'
]) . ';',
'',
"class {$name} {",
" public function __invoke(Request \$request, Response \$response, View \$view): Response {",
" return \$view->render(\$response, '{$template}');",
' }',
'}',
''
];
$folder = implode(DIRECTORY_SEPARATOR, [
$this->folder,
$project,
'common',
'Controller',
ucwords($space)
]);
return $this->createFile($folder, $name . '.php', $content);
}
}