├── src └── devtools │ ├── project-files │ ├── app │ │ ├── .htaccess │ │ ├── views │ │ │ └── themes │ │ │ │ ├── model │ │ │ │ └── main │ │ │ │ │ ├── vFooter.html │ │ │ │ │ ├── vHeader.html │ │ │ │ │ └── vMenu.html │ │ │ │ ├── semantic │ │ │ │ └── main │ │ │ │ │ ├── vFooter.html │ │ │ │ │ ├── vMenu.html │ │ │ │ │ └── vHeader.html │ │ │ │ ├── foundation │ │ │ │ └── main │ │ │ │ │ ├── vFooter.html │ │ │ │ │ ├── vMenu.html │ │ │ │ │ └── vHeader.html │ │ │ │ └── bootstrap │ │ │ │ └── main │ │ │ │ ├── vFooter.html │ │ │ │ ├── vMenu.html │ │ │ │ └── vHeader.html │ │ └── controllers │ │ │ ├── Admin.php │ │ │ ├── ControllerBase.php │ │ │ └── IndexController.php │ ├── public │ │ └── themes │ │ │ ├── model │ │ │ ├── js │ │ │ │ └── .gitkeep │ │ │ ├── img │ │ │ │ └── .gitkeep │ │ │ └── css │ │ │ │ └── style.css │ │ │ ├── bootstrap │ │ │ ├── img │ │ │ │ └── .gitkeep │ │ │ └── scss │ │ │ │ └── app.scss │ │ │ ├── semantic │ │ │ ├── img │ │ │ │ └── .gitkeep │ │ │ └── css │ │ │ │ └── style.css │ │ │ └── foundation │ │ │ ├── img │ │ │ └── .gitkeep │ │ │ ├── scss │ │ │ ├── _myVariables.scss │ │ │ └── app.scss │ │ │ └── css │ │ │ └── style.css.map │ ├── templates │ │ ├── view.tpl │ │ ├── .env.tpl │ │ ├── indexThemes.tpl │ │ ├── controller.tpl │ │ ├── services.tpl │ │ ├── preloader.config.tpl │ │ ├── preloader.script.tpl │ │ ├── vFooter.tpl │ │ ├── indexNoTheme.tpl │ │ ├── vHeader.tpl │ │ ├── config.tpl │ │ └── bootstrap.tpl │ ├── .htaccess │ ├── index.php │ └── README.md │ ├── cmd │ └── commands │ │ ├── AbstractThemeCmd.php │ │ ├── InitCacheCmd.php │ │ ├── RestApiCmd.php │ │ ├── AuthCmd.php │ │ ├── InfoValidationCmd.php │ │ ├── InfoModelCmd.php │ │ ├── traits │ │ └── DbCheckTrait.php │ │ ├── RestCmd.php │ │ ├── ConfigCmd.php │ │ ├── NewMailCmd.php │ │ ├── NewClassCmd.php │ │ ├── InfoModelsCmd.php │ │ ├── AbstractCmdModel.php │ │ ├── CrudCmd.php │ │ ├── HelpCmd.php │ │ ├── LiveReloadCmd.php │ │ ├── CreateCommandCmd.php │ │ ├── SendMailQueueCmd.php │ │ ├── InfoMigrationsCmd.php │ │ ├── IndexCrudCmd.php │ │ ├── EncryptNewKey.php │ │ ├── NewActionCmd.php │ │ ├── InfoRoutesCmd.php │ │ ├── NewDomainCmd.php │ │ ├── InfoMailerCmd.php │ │ ├── NewThemeCmd.php │ │ ├── DisplayAclsCmd.php │ │ ├── InitAclsCmd.php │ │ ├── TemplateParserCmd.php │ │ ├── ConfigSetCmd.php │ │ ├── InstallThemeCmd.php │ │ ├── DAOCmd.php │ │ ├── MigrationsCmd.php │ │ ├── popo │ │ └── NewModel.php │ │ └── NewModelCmd.php │ ├── server │ ├── _ngx.php │ ├── .htrouter.php │ ├── _react.php │ ├── _swow.php │ ├── _swoole.php │ ├── _workerman.php │ └── _index.php │ ├── core │ ├── themesConfig.php │ ├── toolsConfig.php │ └── ConsoleScaffoldController.php │ └── utils │ └── FrameworkParts.php ├── .gitignore ├── .github ├── images │ ├── db-conf.png │ ├── devtools.png │ └── devtools-version.png └── ISSUE_TEMPLATE │ └── bug_report.md ├── .gitattributes ├── composer.json ├── LICENSE └── CHANGELOG.md /src/devtools/project-files/app/.htaccess: -------------------------------------------------------------------------------- 1 | deny from all -------------------------------------------------------------------------------- /src/devtools/project-files/public/themes/model/js/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/devtools/project-files/public/themes/bootstrap/img/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/devtools/project-files/public/themes/model/img/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/devtools/project-files/public/themes/semantic/img/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/devtools/project-files/public/themes/foundation/img/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .buildpath 2 | .project 3 | .settings 4 | vendor/ 5 | composer.lock 6 | .idea/ 7 | -------------------------------------------------------------------------------- /src/devtools/project-files/public/themes/model/css/style.css: -------------------------------------------------------------------------------- 1 | //Empty css file for theme 2 | body{} -------------------------------------------------------------------------------- /src/devtools/project-files/templates/view.tpl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/devtools/project-files/templates/.env.tpl: -------------------------------------------------------------------------------- 1 | DB_NAME=%dbName% 2 | DB_USER=%user% 3 | DB_PASS=%password% 4 | -------------------------------------------------------------------------------- /.github/images/db-conf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpMv/ubiquity-devtools/HEAD/.github/images/db-conf.png -------------------------------------------------------------------------------- /.github/images/devtools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpMv/ubiquity-devtools/HEAD/.github/images/devtools.png -------------------------------------------------------------------------------- /.github/images/devtools-version.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phpMv/ubiquity-devtools/HEAD/.github/images/devtools-version.png -------------------------------------------------------------------------------- /src/devtools/project-files/app/views/themes/model/main/vFooter.html: -------------------------------------------------------------------------------- 1 | {% block footer %} 2 | 3 | {% endblock %} 4 | {% block scripts %} 5 | 6 | {% endblock %} 7 | 8 | -------------------------------------------------------------------------------- /src/devtools/project-files/templates/indexThemes.tpl: -------------------------------------------------------------------------------- 1 | {% extends "@activeTheme/main.html"%} 2 | {%block body%} 3 | {% include [defaultPage,'@framework/index/index.html'] %} 4 | {% endblock %} -------------------------------------------------------------------------------- /src/devtools/project-files/app/controllers/Admin.php: -------------------------------------------------------------------------------- 1 | 4 | RewriteEngine On 5 | RewriteBase /%rewriteBase%/ 6 | 7 | RewriteCond %{REQUEST_FILENAME} !-f 8 | RewriteCond %{HTTP_ACCEPT} !(.*images.*) 9 | RewriteRule ^(.*)$ index.php?c=$1 [L,QSA] 10 | 11 | -------------------------------------------------------------------------------- /src/devtools/project-files/templates/services.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% block header %} 5 | 6 | 7 | Custom theme 8 | {% endblock %} 9 | {% block css %} 10 | 11 | {% endblock %} 12 | 13 | 14 | {% block head %} 15 | 16 | {% endblock %} -------------------------------------------------------------------------------- /src/devtools/project-files/templates/preloader.config.tpl: -------------------------------------------------------------------------------- 1 | array(), 4 | "classes" => array(), 5 | "paths" => array(), 6 | "excludeds" => array(), 7 | "libraries-parts" => array(), 8 | "callback" => function (\Ubiquity\cache\Preloader $preloader) { 9 | $preloader->addUbiquityBasics(%hasDatabase%); 10 | } 11 | ); -------------------------------------------------------------------------------- /src/devtools/project-files/app/views/themes/semantic/main/vFooter.html: -------------------------------------------------------------------------------- 1 | {% block footer %} 2 | {% endblock %} 3 | {% block scripts %} 4 | 5 | 6 | {{script_foot | raw }} 7 | {% endblock %} 8 | 9 | -------------------------------------------------------------------------------- /src/devtools/project-files/templates/preloader.script.tpl: -------------------------------------------------------------------------------- 1 | 3 | 4 | 10 | 11 | {% endblock %} 12 | {% block scripts %} 13 | %jsFiles% 14 | {% endblock %} 15 | 16 | -------------------------------------------------------------------------------- /src/devtools/project-files/app/views/themes/semantic/main/vMenu.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 13 |
14 |
-------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /src/devtools/project-files/app/views/themes/model/main/vMenu.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 12 |
13 |
14 |
-------------------------------------------------------------------------------- /src/devtools/project-files/app/views/themes/foundation/main/vFooter.html: -------------------------------------------------------------------------------- 1 | {% block footer %} 2 | 3 | {% endblock %} 4 | {% block scripts %} 5 | {{js('https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js',{nonce: nonce})}} 6 | {{js('https://cdn.jsdelivr.net/npm/foundation-sites@6.5.3/dist/js/foundation.min.js',{nonce: nonce})}} 7 | 10 | {% endblock %} 11 | 12 | -------------------------------------------------------------------------------- /src/devtools/project-files/app/views/themes/foundation/main/vMenu.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 12 |
13 |
14 |
-------------------------------------------------------------------------------- /src/devtools/project-files/templates/indexNoTheme.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% block header %} 5 | 6 | 7 | %projectName% 8 | {% endblock %} 9 | {% block css %} 10 | %cssFiles% 11 | {% endblock %} 12 | 13 | 14 | {% block body %} 15 |
16 |
17 | {% endblock %} 18 | {% block scripts %} 19 | %jsFiles% 20 | {% endblock %} 21 | 22 | -------------------------------------------------------------------------------- /src/devtools/project-files/app/views/themes/bootstrap/main/vFooter.html: -------------------------------------------------------------------------------- 1 | {% block footer %} 2 | {% endblock %} 3 | {% block scripts %} 4 | 5 | 6 | 7 | {% endblock %} 8 | 9 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/AbstractThemeCmd.php: -------------------------------------------------------------------------------- 1 | 2 |
3 | Themes 4 | 13 |
14 | -------------------------------------------------------------------------------- /src/devtools/project-files/app/views/themes/foundation/main/vHeader.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% block header %} 5 | 6 | 7 | ubi-projects Foundation 8 | {% endblock %} 9 | {% block css %} 10 | {{css('@activeTheme/css/style.css',{nonce: nonce})}} 11 | {{css('https://cdnjs.cloudflare.com/ajax/libs/foundicons/3.0.0/foundation-icons.min.css',{nonce: nonce})}} 12 | {% endblock %} 13 | 14 | 15 | {% block head %} 16 | 17 | {% endblock %} -------------------------------------------------------------------------------- /src/devtools/project-files/app/views/themes/semantic/main/vHeader.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% block header %} 5 | 6 | 7 | ubi-projects semantic-UI 8 | {% endblock %} 9 | {% block css %} 10 | 11 | {{css('@activeTheme/css/style.css',{nonce:nonce}) | raw}} 12 | {% endblock %} 13 | 14 | 15 | {% block head %} 16 | {% endblock %} -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[command] Element should do X" 5 | labels: '' 6 | assignees: jcheron 7 | 8 | --- 9 | 10 | 17 | ### Steps 18 | 19 | ### Expected Result 20 | 21 | ### Actual Result 22 | 23 | ### Versions 24 | - Ubiquity framework x.y.z 25 | - Ubiquity devtools x.y.z 26 | - php x.y.z 27 | - OS 28 | -------------------------------------------------------------------------------- /src/devtools/project-files/app/views/themes/bootstrap/main/vHeader.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% block header %} 5 | 6 | 7 | ubi-projects Bootstrap 8 | {% endblock %} 9 | {% block css %} 10 | {{css('@activeTheme/css/style.css',{nonce: nonce})}} 11 | {{css('@activeTheme/css/all.min.css',{nonce: nonce})}} 12 | 13 | {% endblock %} 14 | 15 | 16 | {% block head %} 17 | {% endblock %} 18 | -------------------------------------------------------------------------------- /src/devtools/project-files/public/themes/bootstrap/scss/app.scss: -------------------------------------------------------------------------------- 1 | //For compilation, run from the project root folder 2 | //ssass public/assets/bootstrap/scss/app.scss public/assets/bootstrap/css/style.css --load-path=vendor 3 | 4 | @import "twitter/bootstrap/scss/functions"; 5 | @import '_myVariables'; 6 | @import "twitter/bootstrap/scss/bootstrap"; 7 | .version{ 8 | background-color: #D39D38!important; 9 | color: white; 10 | font-weight: 600; 11 | font-size: 70%; 12 | } 13 | 14 | .inverted{ 15 | background: #545454 linear-gradient(transparent,rgba(0,0,0,.05))!important; 16 | color: #fff!important; 17 | } 18 | -------------------------------------------------------------------------------- /src/devtools/server/_ngx.php: -------------------------------------------------------------------------------- 1 | loadView($this->headerView); 19 | } 20 | } 21 | 22 | public function finalize() { 23 | if (! URequest::isAjax()) { 24 | $this->loadView($this->footerView); 25 | } 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /src/devtools/server/.htrouter.php: -------------------------------------------------------------------------------- 1 | 'application/x-javascript', 7 | 'css' => 'text/css' 8 | ]; 9 | $pathInfo = \pathinfo($uri); 10 | \header("Content-Type: " . $fileExts[$pathInfo['extension']]); 11 | \readfile(__DIR__ . '/../' . $uri); 12 | } elseif ($uri !== 'favicon.ico' && ($uri == null || ! \file_exists(__DIR__ . '/../public/' . $uri))) { 13 | $_GET['c'] = $uri; 14 | include_once '_index.php'; 15 | return true; 16 | } else { 17 | $_GET['c'] = ''; 18 | return false; 19 | } 20 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/RestApiCmd.php: -------------------------------------------------------------------------------- 1 | addJsonRestController($what, $routePath); 17 | } else { 18 | $scaffold->addRestApiController($what, $routePath); 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/devtools/server/_react.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | init($config, realpath(__DIR__.\DS.'..'.\DS.'public'.\DS)); 17 | require ROOT.'config/services.php'; 18 | $reactServer->run($address); 19 | -------------------------------------------------------------------------------- /src/devtools/project-files/templates/vHeader.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% block header %} 5 | 6 | 7 | 8 | %projectName% 9 | {% endblock %} 10 | {% block css %} 11 | %cssFiles% 12 | {{css('css/style.css', {nonce: nonce})}} 13 | {% endblock %} 14 | 15 | 16 | {% block head %} 17 |
18 |
19 |
20 | 24 |
25 |
26 |
27 |
28 | {% endblock %} 29 | -------------------------------------------------------------------------------- /src/devtools/server/_swow.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | init($config, realpath(__DIR__.\DS.'..'.\DS.'public'.\DS)); 17 | require ROOT.'config/services.php'; 18 | $swowServer->run($sConfig['host'],$sConfig['port'],$sConfig['socket']??[]); 19 | -------------------------------------------------------------------------------- /src/devtools/server/_swoole.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | init($config, realpath(__DIR__.\DS.'..'.\DS.'public'.\DS)); 17 | require ROOT.'config/services.php'; 18 | $swooleServer->run($sConfig['host'],$sConfig['port'],$sConfig['options']??[]); 19 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/AuthCmd.php: -------------------------------------------------------------------------------- 1 | addAuthController($what, $baseClass, $authView, $routePath); 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /src/devtools/server/_workerman.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | init($config, realpath(__DIR__.\DS.'..'.\DS.'public'.\DS)); 17 | $workerServer->setDefaultCount(); 18 | require ROOT.'config/services.php'; 19 | $workerServer->run($sConfig['host'],$sConfig['port'],$sConfig['socket']??[]); 20 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phpmv/ubiquity-devtools", 3 | "description": "Command line tools for ubiquity-framework", 4 | "type": "installer", 5 | "keywords": [ 6 | "php", 7 | "framework" 8 | ], 9 | "require": { 10 | "php": ">=7.4", 11 | "phpmv/ubiquity-commands":"^0.0", 12 | "symfony/process": "^5.2", 13 | "vlucas/phpdotenv": "^5.5" 14 | }, 15 | "license": "Apache-2.0", 16 | "authors": [ 17 | { 18 | "name": "Jean-Christophe HERON", 19 | "email": "myaddressmail@gmail.com", 20 | "role": "Lead developer" 21 | } 22 | ], 23 | "bin": [ 24 | "src/Ubiquity" 25 | ], 26 | "autoload" : { 27 | "psr-4" : { 28 | "Ubiquity\\" : "src/" 29 | } 30 | }, 31 | "extra": { 32 | "branch-alias": { 33 | "dev-master": "1.3.x-dev" 34 | } 35 | }, 36 | "minimum-stability": "dev", 37 | "prefer-stable": true 38 | } 39 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/InfoValidationCmd.php: -------------------------------------------------------------------------------- 1 | {$model} does not exists!", 'error', 'info:model'); 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/devtools/core/themesConfig.php: -------------------------------------------------------------------------------- 1 | [ 4 | 'composer'=>['twitter/bootstrap'=>'^4.3','fortawesome/font-awesome'=>'^5.7'], 5 | 'vendor-copy'=>[ 6 | '/vendor/fortawesome/font-awesome/css/all.min.css'=>'/public/assets/%theme%/css/all.min.css', 7 | '/vendor/fortawesome/font-awesome/webfonts'=>'/public/assets/%theme%/webfonts', 8 | ] 9 | ], 10 | 'foundation'=>[ 11 | 'composer'=>['zurb/foundation'=>'^6.5'] 12 | ], 13 | 'semantic'=>[ 14 | 'composer'=>['fomantic/ui'=>'^2.9','frameworks/jquery'=> '~3.7'], 15 | 'vendor-copy'=>[ 16 | '/vendor/fomantic/ui/dist/semantic.min.css'=>'/public/assets/%theme%/css/semantic.min.css', 17 | '/vendor/fomantic/ui/dist/semantic.min.js'=>'/public/assets/%theme%/js/semantic.min.js', 18 | '/vendor/frameworks/jquery/jquery.min.js'=>'/public/assets/%theme%/js/jquery.min.js' 19 | ] 20 | ] 21 | ]; 22 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/InfoModelCmd.php: -------------------------------------------------------------------------------- 1 | {$model} does not exists!", 'error', 'info:model'); 22 | } 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /src/devtools/project-files/templates/config.tpl: -------------------------------------------------------------------------------- 1 | "%siteUrl%", 4 | "database"=>[ 5 | "type"=>"%dbType%", 6 | "wrapper"=>"%dbWrapper%", 7 | "dbName"=>getenv('DB_NAME'), 8 | "serverName"=>"%serverName%", 9 | "port"=>"%port%", 10 | "user"=>getenv('DB_USER'), 11 | "password"=>getenv('DB_PASS'), 12 | "options"=>[], 13 | "cache"=>false 14 | ], 15 | "sessionName"=>"%sessionName%", 16 | "namespaces"=>[], 17 | "templateEngine"=>'%templateEngine%', 18 | "templateEngineOptions"=>array("cache"=>false%activeTheme%), 19 | "test"=>false, 20 | "debug"=>false, 21 | "logger"=>function(){return new \Ubiquity\log\libraries\UMonolog("%projectName%",\Monolog\Logger::INFO);}, 22 | "di"=>[%injections%], 23 | "cache"=>["directory"=>"cache/","system"=>"Ubiquity\\cache\\system\\ArrayCache","params"=>[]], 24 | "mvcNS"=>["models"=>"models","controllers"=>"controllers","rest"=>""] 25 | ); 26 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/traits/DbCheckTrait.php: -------------------------------------------------------------------------------- 1 | 0) { 21 | ob_start(); 22 | CacheManager::initCache($config, 'models'); 23 | $res = ob_get_clean(); 24 | echo ConsoleFormatter::showMessage($res, 'success', 'init-cache: models'); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/RestCmd.php: -------------------------------------------------------------------------------- 1 | addRestController($what, RestResourceController::class, $resource, $routePath); 19 | } else { 20 | echo ConsoleFormatter::showMessage("The models class {$resource} does not exists!", 'error', 'rest-controller'); 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /src/devtools/project-files/templates/bootstrap.tpl: -------------------------------------------------------------------------------- 1 | run('composer','optimize'); 23 | } 24 | 25 | //Executed before all modes 26 | function bs_before($devtools,$config){ 27 | 28 | } 29 | 30 | //Executed after all modes 31 | function bs_after($devtools,$config){ 32 | //Initialize all caches 33 | $devtools->run('init-cache'); 34 | } -------------------------------------------------------------------------------- /src/devtools/cmd/commands/ConfigCmd.php: -------------------------------------------------------------------------------- 1 | app/config/config.php file'); 12 | $datas=$config; 13 | $fields=self::getOption($options, 'f', 'fields'); 14 | if($fields!=null){ 15 | $fields=explode(",", $fields); 16 | } 17 | if($what!=null && isset($config[$what])){ 18 | $datas=$config[$what]; 19 | } 20 | $tbl=new ConsoleTable(); 21 | $tbl->setIndent(5); 22 | $rArray=new ClassicArray($datas,$what); 23 | if(is_array($fields) && sizeof($fields)>0){ 24 | $rArray->setFields($fields); 25 | } 26 | $tbl->setDatas($rArray->parse()); 27 | if($what!=null){ 28 | echo ConsoleFormatter::showInfo($what); 29 | } 30 | echo $tbl->getTable(); 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/devtools/server/_index.php: -------------------------------------------------------------------------------- 1 | [ 4 | "jquery" => "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js", 5 | "bootstrap" => [ 6 | "css" => "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css", 7 | "js" => "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" 8 | ], 9 | "semantic" => [ 10 | "css" => "https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.4/dist/semantic.min.css", 11 | "js" => "https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.4/dist/semantic.min.js" 12 | ], 13 | "diff2html" => [ 14 | "css" => "https://cdnjs.cloudflare.com/ajax/libs/diff2html/2.12.2/diff2html.min.css" 15 | ] 16 | ], 17 | "composer" => [ 18 | "require" => [ 19 | "php" => ">=8.1", 20 | "twig/twig" => "^3.0", 21 | "phpmv/ubiquity" => "^2.5" 22 | ], 23 | "require-dev" => [ 24 | "monolog/monolog" => "^2.2", 25 | "phpmv/ubiquity-dev" => "^0.1", 26 | "phpmv/ubiquity-debug" => "^0.0" 27 | ], 28 | "autoload" => [ 29 | "psr-4" => [ 30 | "" => "app/" 31 | ] 32 | ] 33 | ] 34 | ]; 35 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/NewMailCmd.php: -------------------------------------------------------------------------------- 1 | setConfig($config); 19 | $msg = $scaffold->_createClass('mailer.tpl', $classname, $ns, 'use Ubiquity\\mailer\\MailerManager;', $parent, ''); 20 | if ($hasView) { 21 | $vName = $scaffold->_createViewOp('mailer', $classname); 22 | } 23 | echo ConsoleFormatter::showMessage("Mailer class {$classname} created!", 'success', 'new-mailer-class'); 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/NewClassCmd.php: -------------------------------------------------------------------------------- 1 | setConfig($config); 22 | $msg = $scaffold->_createClass('class.tpl', $classname, $ns, '', $parent, ''); 23 | echo ConsoleFormatter::showMessage("Class {$classname} created!", 'success', 'new-class'); 24 | } else { 25 | echo ConsoleFormatter::showMessage("Class namespace must not be empty!", 'error', 'new-class'); 26 | } 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/InfoModelsCmd.php: -------------------------------------------------------------------------------- 1 | " . $model . "\n"); 24 | self::displayModelInfo($fields, $infos, null, false); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/devtools/project-files/app/controllers/IndexController.php: -------------------------------------------------------------------------------- 1 | 0) { 21 | $this->loadView('@activeTheme/main/vMenu.html', \compact('themes', 'activeTheme')); 22 | } 23 | $this->loadView($defaultPage, \compact('defaultPage', 'links', 'infos', 'activeTheme')); 24 | } 25 | 26 | public function ct($theme) { 27 | $themes = Display::getThemes(); 28 | if ($theme != null && \array_search($theme, $themes) !== false) { 29 | $config = ThemesManager::saveActiveTheme($theme); 30 | \header('Location: ' . $config['siteUrl']); 31 | } else { 32 | Logger::warn('Themes', \sprintf('The theme %s does not exists!', $theme), 'changeTheme(ct)'); 33 | $this->forward(IndexController::class); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/AbstractCmdModel.php: -------------------------------------------------------------------------------- 1 | setIndent(5); 26 | $rArray=new ClassicArray($infos,$what); 27 | if(is_array($aFields) && sizeof($aFields)>0){ 28 | $rArray->setFields($aFields); 29 | } 30 | $tbl->setDatas($rArray->parse()); 31 | if($what!=null){ 32 | echo ConsoleFormatter::showInfo($what); 33 | } 34 | echo $tbl->getTable(); 35 | if($rArray->hasMessages()){ 36 | echo ConsoleFormatter::showMessage(implode("\n", $rArray->getMessages()),'error'); 37 | } 38 | } 39 | } 40 | 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/CrudCmd.php: -------------------------------------------------------------------------------- 1 | addCrudController($what, $resource, $crudDatas, $crudViewer, $crudEvents, $crudViews, $routePath); 23 | } else { 24 | echo ConsoleFormatter::showMessage("The models class {$resource} does not exists!", 'error', 'crud-controller'); 25 | } 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/HelpCmd.php: -------------------------------------------------------------------------------- 1 | longString()); 33 | } 34 | $command = $info['cmd']; 35 | echo "\n"; 36 | } 37 | } 38 | 39 | private static function info($caller) { 40 | echo $caller::getAppVersion() . "\n"; 41 | $commands = Command::getCommands(); 42 | foreach ($commands as $command) { 43 | echo ConsoleFormatter::formatHtml($command->longString()); 44 | echo "\n"; 45 | } 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/LiveReloadCmd.php: -------------------------------------------------------------------------------- 1 | npm install -g livereload.\n", 'warning', 'live-reload'); 24 | echo ConsoleFormatter::showInfo("Trying to install livereload\n"); 25 | system('npm install -g livereload'); 26 | } 27 | echo ConsoleFormatter::showInfo($msg . "Press Ctrl+C to stop it!\n"); 28 | system($cmd . ' &'); 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/CreateCommandCmd.php: -------------------------------------------------------------------------------- 1 | create($pattern, $cmdPath)) { 19 | echo ConsoleFormatter::showMessage(sprintf('Command %s created in %s!', $what, $cmdPath), 'success', 'Command creation'); 20 | Command::reloadCustomCommands($devtoolsConfig); 21 | HelpCmd::run($caller, $what); 22 | } else { 23 | echo ConsoleFormatter::showMessage(sprintf('Error during the creation of %s!', $what), 'error', 'Command creation'); 24 | } 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /src/devtools/project-files/README.md: -------------------------------------------------------------------------------- 1 | # %projectName% 2 | 3 | This README outlines the details of collaborating on this Ubiquity application. 4 | A short introduction of this app could easily go here. 5 | 6 | ## Prerequisites 7 | 8 | You will need the following things properly installed on your computer. 9 | 10 | * php >=7.4 11 | * [Git](https://git-scm.com/) 12 | * [Composer](https://getcomposer.org) 13 | * [Ubiquity devtools](https://ubiquity.kobject.net/) 14 | 15 | ## Installation 16 | 17 | * `git clone ` this repository 18 | * `cd %projectName%` 19 | * `composer install` 20 | 21 | ## Running / Development 22 | 23 | * `Ubiquity serve` 24 | * Visit your app at [http://127.0.0.1:8090](http://127.0.0.1:8090). 25 | 26 | ### devtools 27 | 28 | Make use of the many generators for code, try `Ubiquity help` for more details 29 | 30 | ### Optimization for production 31 | 32 | Run: 33 | `composer install --optimize --no-dev --classmap-authoritative` 34 | 35 | ### Deploying 36 | 37 | Specify what it takes to deploy your app. 38 | 39 | ## Further Reading / Useful Links 40 | 41 | * [Ubiquity website](https://ubiquity.kobject.net/) 42 | * [Guide](http://micro-framework.readthedocs.io/en/latest/?badge=latest) 43 | * [Doc API](https://api.kobject.net/ubiquity/) 44 | * [Twig documentation](https://twig.symfony.com) 45 | * [Semantic-UI](https://semantic-ui.com) 46 | -------------------------------------------------------------------------------- /src/devtools/project-files/public/themes/foundation/scss/_myVariables.scss: -------------------------------------------------------------------------------- 1 | $global-radius: 3px; 2 | $body-font-family: "Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif; 3 | $header-font-weight: 650; 4 | $header-styles: ( 5 | small: ( 6 | 'h1': ('font-size': 24), 7 | 'h2': ('font-size': 20), 8 | 'h3': ('font-size': 19), 9 | 'h4': ('font-size': 18), 10 | 'h5': ('font-size': 17), 11 | 'h6': ('font-size': 16), 12 | ), 13 | medium: ( 14 | 'h1': ('font-size': 40), 15 | 'h2': ('font-size': 31), 16 | 'h3': ('font-size': 25), 17 | 'h4': ('font-size': 20), 18 | 'h5': ('font-size': 16), 19 | 'h6': ('font-size': 14), 20 | ), 21 | ) !default; 22 | 23 | i.large { 24 | font-size: 3rem!important; 25 | } 26 | 27 | .top-bar, .top-bar .menu{ 28 | background-color: #343a40!important; 29 | } 30 | 31 | .top-bar .menu .menu-text{ 32 | color: #fff!important; 33 | } 34 | 35 | .top-bar .menu{ 36 | min-width: 1170px!important; 37 | } 38 | 39 | .menu.links{ 40 | background-color: #f8f9fa!important; 41 | padding: 10px 0; 42 | } 43 | 44 | .version{ 45 | background-color: #D39D38!important; 46 | } 47 | 48 | .infos .value{ 49 | color: #1779ba; 50 | font-weight: 500; 51 | } 52 | .inverted{ 53 | background: #545454 linear-gradient(transparent,rgba(0,0,0,.05))!important; 54 | color: #fff!important; 55 | } -------------------------------------------------------------------------------- /src/devtools/cmd/commands/SendMailQueueCmd.php: -------------------------------------------------------------------------------- 1 | 0) { 22 | MailerManager::saveQueue(); 23 | echo ConsoleFormatter::showMessage($count . ' email(s) sent with success!', 'success', 'Send mails from Queue'); 24 | } else { 25 | echo ConsoleFormatter::showMessage('No mail sent!', 'info', 'Send mails from Queue'); 26 | } 27 | } 28 | } 29 | 30 | private static function _sendMailQueue($index) { 31 | if (MailerManager::sendQueuedMail(-- $index)) { 32 | MailerManager::saveQueue(); 33 | echo ConsoleFormatter::showMessage('Email sent with success!', 'success', 'Send mail from Queue'); 34 | } else { 35 | echo ConsoleFormatter::showMessage(MailerManager::getErrorInfo(), 'error', 'Send mail from Queue'); 36 | } 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/InfoMigrationsCmd.php: -------------------------------------------------------------------------------- 1 | $domain"; 22 | } 23 | 24 | $checker = new DatabaseChecker($dbOffset); 25 | $checker->checkAll(); 26 | 27 | if ($checker->hasErrors()) { 28 | echo ConsoleFormatter::showMessage("Migrations to operate for db at offset $dbOffset$domainStr:", 'info', 'Migrations'); 29 | $messages = []; 30 | $checker->displayAll(function ($type, $icons, $content) use (&$messages) { 31 | $messages[$icons][] = $content; 32 | }); 33 | foreach ($messages as $title => $msgs) { 34 | $content = \implode(PHP_EOL, $msgs); 35 | echo ConsoleFormatter::showMessage($content, 'warning', $title); 36 | } 37 | } else { 38 | echo ConsoleFormatter::showMessage("No migrations to operate for db at offset $dbOffset$domainStr!", 'info', 'Migrations'); 39 | } 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/IndexCrudCmd.php: -------------------------------------------------------------------------------- 1 | 1) { 25 | $dbOffset = Console::question('Please select a valid database offset', $dbs); 26 | } else { 27 | $dbOffset = \current($dbs); 28 | } 29 | $scaffold->setActiveDb($dbOffset); 30 | } 31 | if (\strpos($routePath, '{resource') === false) { 32 | echo ConsoleFormatter::showMessage("The path variable {$routePath} does not contain the {resource} part!", 'error', 'index-crud-controller'); 33 | } else { 34 | $scaffold->addIndexCrudController($what, $crudDatas, $crudViewer, $crudEvents, $crudViews, $routePath); 35 | } 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/EncryptNewKey.php: -------------------------------------------------------------------------------- 1 | setConfig($config); 14 | @list ($controller, $action) = explode('.', $what); 15 | $domain = self::getOption($options, 'o', 'domain', ''); 16 | if ($domain != '') { 17 | DDDManager::setDomain($domain); 18 | } 19 | if ($controller != null && $action != null) { 20 | $controller = self::getCompleteClassname($config, $controller, 'controllers'); 21 | if (\class_exists($controller)) { 22 | $parameters = self::getOption($options, 'p', 'params'); 23 | $routePath = self::getOption($options, 'r', 'route'); 24 | $createView = self::getOption($options, 'v', 'create-view', false); 25 | $theme = self::getOption($options, 't', 'theme'); 26 | $routeInfo = null; 27 | if ($routePath != null) { 28 | $routeInfo = [ 29 | "path" => $routePath, 30 | "methods" => null 31 | ]; 32 | } 33 | CacheManager::start($config); 34 | $scaffold->_newAction($controller, $action, $parameters, '', $routeInfo, $createView, $theme); 35 | } else { 36 | echo ConsoleFormatter::showMessage("The controller class {$controller} does not exists!", 'error', 'new-action'); 37 | } 38 | } else { 39 | echo ConsoleFormatter::showMessage("You must use controller.action notation!", 'error', 'new-action'); 40 | } 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/InfoRoutesCmd.php: -------------------------------------------------------------------------------- 1 | setProperties(explode(",", $fields)); 35 | $rArray->setObjects($routes); 36 | $tbl->setDatas($rArray->parse()); 37 | echo $tbl->getTable(); 38 | if ($rArray->hasMessages()) { 39 | echo ConsoleFormatter::showMessage(implode("\n", $rArray->getMessages()), 'error'); 40 | } 41 | echo ConsoleFormatter::showInfo(sizeof($routes) . " routes ({$type})\n"); 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/NewDomainCmd.php: -------------------------------------------------------------------------------- 1 | $originalBase, which is different from $base.\nWould you like to rename the base to $base?"), [ 18 | 'y', 19 | 'n' 20 | ]); 21 | if (Console::isYes($rep)) { 22 | if (! DDDManager::setBase($base)) { 23 | echo ConsoleFormatter::showMessage("There was a problem during the base renaming to {$base}!", 'error', 'new-domain'); 24 | } else { 25 | echo ConsoleFormatter::showMessage("Domains base was renamed to {$base}!", 'success', 'new-domain'); 26 | } 27 | } 28 | } 29 | 30 | $domain = UString::cleanAttribute($what, '_'); 31 | if (! DDDManager::domainExists($domain)) { 32 | if (DDDManager::createDomain($domain)) { 33 | $domainBase = DDDManager::getDomainBase($domain); 34 | echo ConsoleFormatter::showMessage("The domain {$domain} was successfully created in $domainBase!", 'success', 'new-domain'); 35 | } else { 36 | echo ConsoleFormatter::showMessage("There was a problem during the creation of the domain {$domain}!", 'error', 'new-domain'); 37 | } 38 | } else { 39 | echo ConsoleFormatter::showMessage("The domain {$domain} already exists!", 'error', 'new-domain'); 40 | } 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/InfoMailerCmd.php: -------------------------------------------------------------------------------- 1 | setProperties(explode(",", $fields)); 41 | $rArray->setObjects($mails); 42 | $tbl->setDatas($rArray->parse()); 43 | echo $tbl->getTable(); 44 | if ($rArray->hasMessages()) { 45 | echo ConsoleFormatter::showMessage(implode("\n", $rArray->getMessages()), 'error'); 46 | } 47 | echo ConsoleFormatter::showInfo(sizeof($mails) . " mails in {$what}\n"); 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/devtools/utils/FrameworkParts.php: -------------------------------------------------------------------------------- 1 | create($this, $reInit); 37 | } 38 | 39 | public function addRestApiController($restControllerName, $routePath = "", $reInit = true) { 40 | $this->addRestController($restControllerName, JsonApiRestController::class, '', $routePath, $reInit); 41 | } 42 | 43 | public function addJsonRestController($restControllerName, $routePath = "", $reInit = true) { 44 | $this->addRestController($restControllerName, JsonRestController::class, '', $routePath, $reInit); 45 | } 46 | 47 | public function initRestCache($refresh = true) { 48 | $config = Startup::getConfig(); 49 | \ob_start(); 50 | CacheManager::initCache($config, "rest"); 51 | CacheManager::initCache($config, "controllers"); 52 | $message = \ob_get_clean(); 53 | echo $this->showSimpleMessage($message, "info", "Rest", "info cache re-init"); 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/NewThemeCmd.php: -------------------------------------------------------------------------------- 1 | %s from %s', $what, $extend)); 21 | InstallThemeCmd::addTheme($what, $extend, $themesConfig[$extend], $activeDir, true); 22 | } else { 23 | echo ConsoleFormatter::showMessage(sprintf('The theme %s does not exists!', $extend), 'error', 'Theme creation'); 24 | } 25 | } 26 | } else { 27 | echo ConsoleFormatter::showMessage(sprintf('The theme %s is a reserved theme name!', $what), 'error', 'Theme creation'); 28 | } 29 | } 30 | 31 | public static function addNew($what, $activeDir) { 32 | $msg = ""; 33 | $baseDir = getcwd(); 34 | $dest = $baseDir . '/public/assets/' . $what; 35 | if (! file_exists($dest)) { 36 | $sourceAssets = $activeDir . '/devtools/project-files/public/themes/model/'; 37 | echo ConsoleFormatter::showInfo("Assets creation..."); 38 | FileUtils::xcopy($sourceAssets, $dest); 39 | } else { 40 | $msg = sprintf("Assets creation failed : %s directory exists!\n", $dest); 41 | } 42 | $sourceView = $activeDir . '/devtools/project-files/app/views/themes/model/'; 43 | $dest = DDDManager::getActiveViewFolder() . "themes/" . $what; 44 | if (! file_exists($dest)) { 45 | echo ConsoleFormatter::showInfo("Views creation..."); 46 | FileUtils::xcopy($sourceView, $dest); 47 | } else { 48 | $msg = sprintf("Views creation failed : %s directory exists!\n", $dest); 49 | } 50 | if ($msg !== "") { 51 | echo ConsoleFormatter::showMessage($msg, "error", "Theme creation"); 52 | } else { 53 | self::saveActiveTheme($what); 54 | echo ConsoleFormatter::showMessage(sprintf('Theme %s created with success!', $what), "success", "Theme creation"); 55 | } 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/DisplayAclsCmd.php: -------------------------------------------------------------------------------- 1 | getMap(), [ 66 | 'controller.action', 67 | 'resource', 68 | 'permission' 69 | ]); 70 | break; 71 | } 72 | } 73 | } 74 | 75 | private static function displayPart($title, $datas, $fields) { 76 | $count = \count($datas); 77 | $tbl = new ConsoleTable(); 78 | $rArray = new ReflectArray(); 79 | $rArray->setProperties($fields); 80 | $rArray->setObjects($datas); 81 | $tbl->setDatas($rArray->parse()); 82 | echo ConsoleFormatter::showInfo("$count $title(s)\n"); 83 | echo $tbl->getTable(); 84 | if ($rArray->hasMessages()) { 85 | echo ConsoleFormatter::showMessage(\implode("\n", $rArray->getMessages()), 'error'); 86 | } 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/InitAclsCmd.php: -------------------------------------------------------------------------------- 1 | createModels($dbOffset); 48 | $classes=$dao->getModelClasses(); 49 | echo ConsoleFormatter::showMessage("ACLs models created", 'success', 'init-cache: models'); 50 | $tbl=new ConsoleTable(); 51 | $tbl->setIndent(5); 52 | $rArray=new ClassicArray($classes); 53 | $tbl->setDatas($rArray->parse()); 54 | echo $tbl->getTable(); 55 | ob_start(); 56 | CacheManager::initCache($config, 'models'); 57 | $res = ob_get_clean(); 58 | echo ConsoleFormatter::showMessage($res, 'success', 'init-cache: models'); 59 | } 60 | } 61 | 62 | 63 | CacheManager::start($config); 64 | AclManager::start(); 65 | AclManager::initFromProviders([ 66 | new AclCacheProvider() 67 | ]); 68 | ob_start(); 69 | AclManager::initCache($config); 70 | $res = ob_get_clean(); 71 | echo ConsoleFormatter::showMessage($res, 'success', 'init-acls'); 72 | } 73 | } 74 | 75 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/TemplateParserCmd.php: -------------------------------------------------------------------------------- 1 | generateTemplateSource($fileContent); 33 | $dDest = $destination . $ds . $realPath . $ds; 34 | UFileSystem::safeMkdir($dDest); 35 | \file_put_contents($dDest . $filename, $code); 36 | echo ConsoleFormatter::showInfo("$filename parsed to $destEngine in $destination"); 37 | } 38 | } else { 39 | echo ConsoleFormatter::showMessage("Invalid template $destEngine", 'error', 'Template parser'); 40 | } 41 | } 42 | 43 | private static function runComposer(array $commands, string $name) { 44 | if (isset($commands['repositories'])) { 45 | $repositories = $commands['repositories']; 46 | foreach ($repositories as $index => $repository) { 47 | $type = $repository['type']; 48 | $url = $repository['url']; 49 | \system("composer config repositories.{$name}{$index} $type $url"); 50 | } 51 | } 52 | if (isset($commands['require'])) { 53 | $requires = $commands['require']; 54 | foreach ($requires as $require => $version) { 55 | \system('composer require ' . $require . ':' . $version); 56 | } 57 | } 58 | if (isset($commands['require-dev'])) { 59 | $requires = $commands['require-dev']; 60 | foreach ($requires as $require => $version) { 61 | \system('composer require ' . $require . ':' . $version . ' --dev'); 62 | } 63 | } 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/ConfigSetCmd.php: -------------------------------------------------------------------------------- 1 | $value){ 15 | if(is_string($option)){ 16 | $optionParts=explode(".", $option); 17 | $oldValue=self::getConfigOption($config, $optionParts); 18 | if(isset($oldValue)){ 19 | if(UString::isValid($oldValue)){ 20 | if($value!==$oldValue){ 21 | self::setConfigOption($config, $optionParts, $value); 22 | echo ConsoleFormatter::showMessage($option." : ".var_export($oldValue,true)." -> ".var_export($value,true)."","info"); 23 | $modified=true; 24 | } 25 | }else{ 26 | echo ConsoleFormatter::showMessage($option." : Unable to change a value of type object","error"); 27 | } 28 | }else{ 29 | self::setConfigOption($config, $optionParts, $value); 30 | echo ConsoleFormatter::showMessage($option." : inserted -> ".var_export($value,true)."","info"); 31 | $modified=true; 32 | } 33 | } 34 | } 35 | if($modified){ 36 | $content="1){ 68 | self::setConfigOption($config[$options[0]], array_slice($options, 1), $value); 69 | } 70 | } 71 | 72 | private static function setConfigOption_(&$config,$option,$value){ 73 | $optionParts=explode(".", $option); 74 | $c=$config; 75 | $nb=sizeof($optionParts); 76 | for ($i=0;$i<$nb-1;$i++){ 77 | $opt=$optionParts[$i]; 78 | if(!isset($c[$opt])){ 79 | $c[$opt]=[]; 80 | } 81 | $c=$c[$opt]; 82 | } 83 | $c[$optionParts[$nb-1]]=$value; 84 | } 85 | } 86 | 87 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/InstallThemeCmd.php: -------------------------------------------------------------------------------- 1 | ' . $what . ' does not exists!', 'warning', 'Themes installation'); 19 | $answer = Console::question('Would-you like to create a new one ?', [ 20 | 'y', 21 | 'n' 22 | ]); 23 | if (Console::isYes($answer)) { 24 | NewThemeCmd::run($config, $options, $what, $activeDir); 25 | } 26 | } 27 | } 28 | 29 | public static function addTheme($name, $baseTheme, $themeConfig, $activeDir, $standalone = false, &$composer = []) { 30 | $baseDir = getcwd(); 31 | $dest = $baseDir . '/public/assets/' . $name; 32 | if (! file_exists($dest)) { 33 | echo ConsoleFormatter::showMessage('Files copy...', 'Info', 'Adding theme ' . $name); 34 | FileUtils::safeMkdir($dest); 35 | $source = $activeDir . '/devtools/project-files/public/themes/' . $baseTheme; 36 | FileUtils::xcopy($source, $dest); 37 | 38 | if (\class_exists(\Ubiquity\domains\DDDManager::class)) { 39 | $dest = DDDManager::getActiveViewFolder() . 'themes/' . $name; 40 | } else { 41 | $dest = $baseDir . '/app/views/themes/' . $name; 42 | } 43 | FileUtils::safeMkdir($dest); 44 | $source = $activeDir . '/devtools/project-files/app/views/themes/' . $baseTheme; 45 | FileUtils::xcopy($source, $dest); 46 | 47 | $composerRequires = $themeConfig['composer']; 48 | foreach ($composerRequires as $composerRequire => $version) { 49 | if ($standalone) { 50 | system('composer require ' . $composerRequire); 51 | } else { 52 | $composer['require'][$composerRequire] = $version; 53 | } 54 | } 55 | $vendorCopies = $themeConfig['vendor-copy'] ?? []; 56 | if ($standalone) { 57 | self::copyVendorFiles($name, $vendorCopies, $baseDir); 58 | self::saveActiveTheme($name); 59 | } 60 | return $vendorCopies; 61 | } 62 | 63 | echo ConsoleFormatter::showMessage(\sprintf('This theme seems to be already installed in %s!', $dest), 'warning', 'Theme installation'); 64 | return []; 65 | } 66 | 67 | public static function copyVendorFiles($theme, $vendorCopies, $baseDir) { 68 | foreach ($vendorCopies as $src => $dest) { 69 | $dest = \str_replace('%theme%', $theme, $dest); 70 | FileUtils::xcopy($baseDir . $src, $baseDir . $dest); 71 | echo ConsoleFormatter::showInfo("Copy from " . $src . " to " . $dest . "..."); 72 | } 73 | } 74 | } 75 | 76 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/DAOCmd.php: -------------------------------------------------------------------------------- 1 | getDatas($objects); 40 | break; 41 | case 'getOne': 42 | $object = DAO::getOne($resource, $condition, $included, $parameters); 43 | $rf = new ResponseFormatter(); 44 | $datas = $rf->cleanRestObject($object); 45 | break; 46 | case 'uGetAll': 47 | $objects = DAO::uGetAll($resource, $condition, $included, $parameters); 48 | $rf = new ResponseFormatter(); 49 | $datas = $rf->getDatas($objects); 50 | break; 51 | case 'uGetOne': 52 | $object = DAO::uGetOne($resource, $condition, $included, $parameters); 53 | $rf = new ResponseFormatter(); 54 | $datas = $rf->cleanRestObject($object); 55 | break; 56 | case 'count': 57 | $nb = DAO::count($resource, $condition, $parameters); 58 | echo ConsoleFormatter::showInfo($nb . " instances of " . $resource); 59 | break; 60 | case 'uCount': 61 | $nb = DAO::uCount($resource, $condition, $parameters); 62 | echo ConsoleFormatter::showInfo($nb . " instances of " . $resource); 63 | break; 64 | default: 65 | echo ConsoleFormatter::showMessage("Unknown command for dao : " . $what, 'error', 'dao'); 66 | break; 67 | } 68 | if (\is_array($datas)) { 69 | $tbl = new ConsoleTable(); 70 | $tbl->setIndent(5); 71 | $rArray = new ClassicArray($datas, $what); 72 | if (\is_array($fields) && \count($fields) > 0) { 73 | if (\is_array($objects)) { 74 | $rArray->setIFields($fields); 75 | } else { 76 | $rArray->setFields($fields); 77 | } 78 | } 79 | $tbl->setDatas($rArray->parse()); 80 | if ($what != null) { 81 | echo ConsoleFormatter::showInfo($what); 82 | } 83 | echo $tbl->getTable(); 84 | if (\is_array($objects)) { 85 | echo ConsoleFormatter::showInfo(\count($datas) . " instances of " . $resource); 86 | } 87 | echo ConsoleFormatter::showInfo(sprintf("Query executed in %.3f seconds", (float) microtime(true) - $start)); 88 | } else { 89 | echo ConsoleFormatter::showInfo('Nothing to display'); 90 | } 91 | } else { 92 | echo ConsoleFormatter::showMessage("The models class {$resource} does not exists!", 'error', 'dao'); 93 | } 94 | } 95 | } 96 | 97 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/MigrationsCmd.php: -------------------------------------------------------------------------------- 1 | $domain"; 30 | } 31 | 32 | $generator = new DatabaseReversor(new DbGenerator(), $dbOffset); 33 | $generator->migrate(); 34 | $script = $generator->getScript(); 35 | if (\count($script) === 0) { 36 | echo ConsoleFormatter::showMessage("No migrations to operate for db at offset $dbOffset$domainStr!", 'info', 'Migrations'); 37 | } else { 38 | echo ConsoleFormatter::showMessage("Migrations to operate for db at offset $dbOffset$domainStr:", 'info', 'Migrations'); 39 | do { 40 | self::displayScript(self::scriptToLineArray($script)); 41 | $rep = Console::question('Select your choices:', [ 42 | 'Execute all commands', 43 | 'Delete a row', 44 | 'Quit' 45 | ]); 46 | switch ($rep) { 47 | case 'Delete a row': 48 | $count = \count($script); 49 | $row = Console::question("Enter a valid row between 1 and $count:"); 50 | $delete = self::deleteScriptRow($row, $script); 51 | if ($delete !== false) { 52 | $script = $delete; 53 | } 54 | break; 55 | case 'Execute all commands': 56 | self::executeSQLTransaction($dbOffset, implode(';', $script), 'Database migrations'); 57 | $rep = 'Quit'; 58 | break; 59 | default: 60 | echo ConsoleFormatter::showInfo('Operation terminated, Bye!'); 61 | } 62 | } while ($rep !== 'Quit'); 63 | } 64 | } 65 | 66 | private static function deleteScriptRow(int $rowNum, array $script) { 67 | $rowNum --; 68 | if ($rowNum >= 0 && $rowNum < \count($script)) { 69 | unset($script[$rowNum]); 70 | return array_values($script); 71 | } 72 | return false; 73 | } 74 | 75 | private static function displayScript(array $script) { 76 | $tbl = new ConsoleTable(); 77 | $tbl->setIndent(5); 78 | $tbl->setPadding(1); 79 | $tbl->setDatas($script); 80 | echo $tbl->getTable(); 81 | } 82 | 83 | private static function scriptToLineArray(array $script): array { 84 | $result = []; 85 | $line = 1; 86 | $width = Screen::getWidth() - 20; 87 | foreach ($script as $sql) { 88 | $result[] = [ 89 | 'line' => $line ++, 90 | 'sql' => \wordwrap($sql, $width, PHP_EOL) 91 | ]; 92 | } 93 | return $result; 94 | } 95 | 96 | private static function executeSQLTransaction(string $activeDbOffset, string $sql, string $title) { 97 | $isValid = true; 98 | if (isset($sql)) { 99 | $db = DAO::getDatabase($activeDbOffset ?? 'default'); 100 | if (! $db->isConnected()) { 101 | $db->setDbName(''); 102 | try { 103 | $db->connect(); 104 | } catch (\Exception $e) { 105 | $isValid = false; 106 | echo ConsoleFormatter::showMessage($e->getMessage(), 'error', $title); 107 | } 108 | } 109 | if ($isValid) { 110 | if ($db->beginTransaction()) { 111 | try { 112 | $db->execute($sql); 113 | if ($db->inTransaction()) { 114 | $db->commit(); 115 | } 116 | echo ConsoleFormatter::showMessage("Database created/updated with success at offset $activeDbOffset!", 'success', $title); 117 | } catch (\Error $e) { 118 | if ($db->inTransaction()) { 119 | $db->rollBack(); 120 | } 121 | echo ConsoleFormatter::showMessage($e->getMessage(), 'error', $title); 122 | } 123 | } else { 124 | $db->execute($sql); 125 | echo ConsoleFormatter::showMessage("Database created/updated with success at offset $activeDbOffset!", 'success', $title); 126 | } 127 | } 128 | } 129 | } 130 | } 131 | 132 | -------------------------------------------------------------------------------- /src/devtools/project-files/public/themes/semantic/css/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&family=JetBrains+Mono:wght@500&display=swap'); 2 | 3 | :root { 4 | --primary: #4fa0ae; 5 | --primary-dark: rgba(79,160,174,1); 6 | --secondary: #d29d38; 7 | --dark: #1a202c; 8 | --darker: #0f1419; 9 | --light: #f7fafc; 10 | --gradient: linear-gradient(135deg, rgba(79,160,174,1) 0%, rgba(210,157,56,1) 100%); 11 | } 12 | 13 | body { 14 | font-family: 'Inter', sans-serif; 15 | background: linear-gradient(180deg, #0f1419 0%, #1a202c 100%); 16 | min-height: 100vh; 17 | } 18 | 19 | /* Header & Footer styles */ 20 | .main-container { 21 | display: flex; 22 | flex-direction: column; 23 | min-height: 100vh; 24 | } 25 | 26 | header { 27 | background: rgba(255,255,255,0.03); 28 | backdrop-filter: blur(10px); 29 | border-bottom: 1px solid rgba(255,255,255,0.1); 30 | padding: 1rem 0; 31 | } 32 | 33 | header .ui.menu { 34 | background: transparent; 35 | border: none; 36 | box-shadow: none; 37 | } 38 | 39 | header .ui.menu .item { 40 | color: white; 41 | transition: all 0.3s; 42 | } 43 | 44 | header .ui.menu .item:hover, 45 | header .ui.menu .item.active { 46 | background: var(--gradient); 47 | color: white; 48 | } 49 | 50 | main { 51 | flex: 1; 52 | } 53 | 54 | main > .ui.container { 55 | max-width: 1200px; 56 | padding: 1.5rem 1rem; 57 | } 58 | 59 | footer { 60 | background: rgba(255,255,255,0.03); 61 | backdrop-filter: blur(10px); 62 | border-top: 1px solid rgba(255,255,255,0.1); 63 | padding: 2rem 0; 64 | margin-top: 2rem; 65 | color: rgba(255,255,255,0.7); 66 | text-align: center; 67 | } 68 | 69 | footer a { 70 | color: var(--primary); 71 | text-decoration: none; 72 | font-weight: 600; 73 | transition: all 0.3s; 74 | } 75 | 76 | footer a:hover { 77 | color: white; 78 | } 79 | 80 | /* Styles existants pour la page d'accueil */ 81 | .modern-container { 82 | max-width: 1200px; 83 | margin: 0 auto; 84 | padding: 1.5rem 1rem; 85 | } 86 | 87 | .hero-section { 88 | background: var(--gradient); 89 | border-radius: 20px; 90 | padding: 2rem 1.5rem; 91 | margin-bottom: 2rem; 92 | box-shadow: 0 20px 60px rgba(0, 212, 170, 0.3); 93 | position: relative; 94 | overflow: hidden; 95 | } 96 | 97 | .hero-section::before { 98 | content: ''; 99 | position: absolute; 100 | top: 0; 101 | left: 0; 102 | right: 0; 103 | bottom: 0; 104 | background: url('data:image/svg+xml,'); 105 | opacity: 0.3; 106 | } 107 | 108 | .hero-content { 109 | position: relative; 110 | z-index: 1; 111 | display: flex; 112 | align-items: center; 113 | gap: 2rem; 114 | } 115 | 116 | .hero-logo { 117 | width: 80px; 118 | height: 80px; 119 | background: white; 120 | border-radius: 20px; 121 | padding: 0.8rem; 122 | box-shadow: 0 10px 30px rgba(0,0,0,0.2); 123 | flex-shrink: 0; 124 | } 125 | 126 | .hero-text h1 { 127 | color: white; 128 | font-size: 2rem; 129 | font-weight: 700; 130 | margin: 0 0 0.5rem 0; 131 | text-shadow: 0 2px 10px rgba(0,0,0,0.2); 132 | } 133 | 134 | .version-badge { 135 | display: inline-flex; 136 | align-items: center; 137 | background: rgba(255,255,255,0.2); 138 | backdrop-filter: blur(10px); 139 | padding: 0.4rem 0.9rem; 140 | border-radius: 50px; 141 | color: white; 142 | font-family: 'JetBrains Mono', monospace; 143 | font-size: 0.9rem; 144 | font-weight: 500; 145 | } 146 | 147 | .status-card { 148 | background: rgba(255,255,255,0.05); 149 | backdrop-filter: blur(10px); 150 | border: 1px solid rgba(255,255,255,0.1); 151 | border-radius: 16px; 152 | padding: 1.2rem; 153 | margin-bottom: 1.5rem; 154 | color: white; 155 | } 156 | 157 | .status-card.success { 158 | border-left: 4px solid var(--primary); 159 | } 160 | 161 | .status-card h3 { 162 | display: flex; 163 | align-items: center; 164 | gap: 0.5rem; 165 | margin: 0 0 1rem 0; 166 | color: var(--primary); 167 | } 168 | 169 | .status-card p { 170 | margin: 0; 171 | line-height: 1.6; 172 | opacity: 0.9; 173 | } 174 | 175 | .status-card a { 176 | color: var(--primary); 177 | text-decoration: none; 178 | font-weight: 600; 179 | transition: all 0.3s; 180 | } 181 | 182 | .status-card a:hover { 183 | color: white; 184 | text-decoration: underline; 185 | } 186 | 187 | .info-grid { 188 | display: grid; 189 | grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); 190 | gap: 1.2rem; 191 | margin-bottom: 1.5rem; 192 | } 193 | 194 | .info-card { 195 | background: rgba(255,255,255,0.05); 196 | backdrop-filter: blur(10px); 197 | border: 1px solid rgba(255,255,255,0.1); 198 | border-radius: 16px; 199 | padding: 1.2rem; 200 | transition: all 0.3s; 201 | } 202 | 203 | .info-card:hover { 204 | transform: translateY(-5px); 205 | box-shadow: 0 10px 30px rgba(0, 212, 170, 0.2); 206 | border-color: var(--primary); 207 | } 208 | 209 | .info-item { 210 | margin-bottom: 1rem; 211 | } 212 | 213 | .info-item:last-child { 214 | margin-bottom: 0; 215 | } 216 | 217 | .info-label { 218 | color: var(--primary); 219 | font-size: 0.85rem; 220 | font-weight: 600; 221 | text-transform: uppercase; 222 | letter-spacing: 0.5px; 223 | margin-bottom: 0.3rem; 224 | } 225 | 226 | .info-value { 227 | color: white; 228 | font-family: 'JetBrains Mono', monospace; 229 | font-size: 0.95rem; 230 | word-break: break-all; 231 | } 232 | 233 | .links-section { 234 | background: rgba(255,255,255,0.05); 235 | backdrop-filter: blur(10px); 236 | border: 1px solid rgba(255,255,255,0.1); 237 | border-radius: 16px; 238 | padding: 1.5rem; 239 | } 240 | 241 | .links-section h3 { 242 | color: white; 243 | margin: 0 0 1.5rem 0; 244 | font-size: 1.2rem; 245 | } 246 | 247 | .links-grid { 248 | display: grid; 249 | grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); 250 | gap: 1rem; 251 | } 252 | 253 | .link-card { 254 | background: rgba(255,255,255,0.03); 255 | border: 1px solid rgba(255,255,255,0.1); 256 | border-radius: 10px; 257 | padding: 0.8rem 1.2rem; 258 | text-align: center; 259 | text-decoration: none; 260 | color: white; 261 | font-weight: 600; 262 | transition: all 0.3s; 263 | } 264 | 265 | .link-card:hover { 266 | background: var(--gradient); 267 | border-color: transparent; 268 | transform: scale(1.05); 269 | box-shadow: 0 5px 20px rgba(0, 212, 170, 0.3); 270 | } 271 | 272 | @media (max-width: 768px) { 273 | .hero-content { 274 | flex-direction: column; 275 | text-align: center; 276 | } 277 | 278 | .hero-text h1 { 279 | font-size: 2rem; 280 | } 281 | 282 | .info-grid { 283 | grid-template-columns: 1fr; 284 | } 285 | } 286 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/popo/NewModel.php: -------------------------------------------------------------------------------- 1 | originalModelName = $modelName; 34 | } 35 | 36 | /** 37 | * 38 | * @return string 39 | */ 40 | public function getOriginalModelName(): string { 41 | return $this->originalModelName; 42 | } 43 | 44 | /** 45 | * 46 | * @param string $originalModelName 47 | */ 48 | public function setOriginalModelName(string $originalModelName): void { 49 | $this->originalModelName = $originalModelName; 50 | } 51 | 52 | /** 53 | * 54 | * @return string 55 | */ 56 | public function getTableName(): string { 57 | return $this->tableName ?? (\lcfirst($this->originalModelName)); 58 | } 59 | 60 | /** 61 | * 62 | * @param string|null $tableName 63 | */ 64 | public function setTableName(?string $tableName): void { 65 | $this->tableName = $tableName; 66 | } 67 | 68 | /** 69 | * 70 | * @return string|null 71 | */ 72 | public function getDefaultPk(): ?string { 73 | return $this->defaultPk; 74 | } 75 | 76 | public function getDefaultFk(): string { 77 | return 'id' . \ucfirst($this->originalModelName); 78 | } 79 | 80 | public function hasDefaultPk(): bool { 81 | return isset($this->defaultPk) && $this->defaultPk != ''; 82 | } 83 | 84 | /** 85 | * 86 | * @param string|null $defaultPk 87 | */ 88 | public function setDefaultPk(?string $defaultPk): void { 89 | $this->defaultPk = $defaultPk; 90 | } 91 | 92 | /** 93 | * 94 | * @return array 95 | */ 96 | public function getPks(): array { 97 | return $this->pks; 98 | } 99 | 100 | public function resetPks() { 101 | $this->pks = []; 102 | } 103 | 104 | /** 105 | * 106 | * @param array $pks 107 | */ 108 | public function setPks(array $pks): void { 109 | $this->pks = $pks; 110 | } 111 | 112 | public function addPk(string $pk): bool { 113 | if (! \in_array($pk, $this->pks)) { 114 | $this->pks[] = $pk; 115 | return true; 116 | } 117 | return false; 118 | } 119 | 120 | /** 121 | * 122 | * @return array 123 | */ 124 | public function getFields(): array { 125 | return $this->fields; 126 | } 127 | 128 | /** 129 | * 130 | * @param array $fields 131 | */ 132 | public function setFields(array $fields): void { 133 | $this->fields = $fields; 134 | } 135 | 136 | public function addField(string $name, array $fieldInfos) { 137 | $this->fields[$name] = $fieldInfos; 138 | } 139 | 140 | public function hasField(string $name): bool { 141 | return isset($this->fields[$name]); 142 | } 143 | 144 | public function getFieldNames(): array { 145 | if (\is_array($this->fields)) { 146 | return \array_keys($this->fields); 147 | } 148 | return []; 149 | } 150 | 151 | public function updateFirstPk() { 152 | if ($this->hasDefaultPk()) { 153 | $this->addField($this->defaultPk, [ 154 | 'Type' => 'int', 155 | 'Nullable' => 'false' 156 | ]); 157 | $this->addPk($this->defaultPk); 158 | } 159 | } 160 | 161 | public function getFirstPk(): ?string { 162 | return $this->defaultPk ?? ($this->pks[0] ?? null); 163 | } 164 | 165 | public function updatePks($pks) { 166 | $pks = \explode(',', $pks); 167 | $this->pks = []; 168 | $this->updateFirstPk(); 169 | foreach ($pks as $pk) { 170 | $this->addPk($pk); 171 | } 172 | } 173 | 174 | public function setFieldsOrder() { 175 | $result = []; 176 | $fields = $this->fields; 177 | $pks = $this->getPks(); 178 | foreach ($pks as $pk) { 179 | $result[$pk] = $fields[$pk]; 180 | unset($fields[$pk]); 181 | } 182 | foreach ($fields as $field => $fieldInfos) { 183 | $result[$field] = $fieldInfos; 184 | } 185 | $this->fields = $result; 186 | } 187 | 188 | public function getSimpleMembers() { 189 | $members = []; 190 | foreach ($this->fields as $name => $fieldInfos) { 191 | if ($fieldInfos['Type'] !== 'mixed') { 192 | $members[] = $name; 193 | } 194 | } 195 | return $members; 196 | } 197 | 198 | public function generateClass($className, $namespace, $dbOffset): Model { 199 | $memberAccess = 'private'; 200 | $this->updateFirstPk(); 201 | $this->setFieldsOrder(); 202 | $engine = CacheManager::getAnnotationsEngineInstance(); 203 | $class = new Model($engine, \lcfirst($className), $namespace, $memberAccess); 204 | $class->setTable($this->getTableName()); 205 | $class->setDatabase($dbOffset); 206 | $fieldsInfos = $this->selectFieldsForGeneration(); 207 | $class->setSimpleMembers($this->getSimpleMembers()); 208 | $keys = $this->pks; 209 | foreach ($fieldsInfos as $field => $info) { 210 | $member = new Member($class, $engine, $field, $memberAccess); 211 | if (\in_array($field, $keys)) { 212 | $member->setPrimary(); 213 | } 214 | $member->setDbType($info); 215 | $member->addValidators(); 216 | $member->setTransformer(); 217 | $class->addMember($member); 218 | } 219 | $class->addMainAnnots(); 220 | return $class; 221 | } 222 | 223 | private function selectFieldsForGeneration() { 224 | $fieldsInRelation = $this->getFieldsInRelations(); 225 | $result = []; 226 | foreach ($this->fields as $f => $infos) { 227 | if (! in_array($f, $fieldsInRelation)) { 228 | $result[$f] = $infos; 229 | } 230 | } 231 | return $result; 232 | } 233 | 234 | private function getFieldsInRelations() { 235 | $result = []; 236 | foreach ($this->manyToOne as $f => $_) { 237 | $result[] = $f; 238 | } 239 | foreach ($this->oneToMany as $f => $_) { 240 | $result[] = $f; 241 | } 242 | foreach ($this->manyToMany as $f => $_) { 243 | $result[] = $f; 244 | } 245 | return $result; 246 | } 247 | 248 | public function addManyToOne($member, $fkField, $className) { 249 | $this->manyToOne[$member] = \compact('fkField', 'className'); 250 | } 251 | 252 | public function addOneToMany($member, $mappedBy, $className) { 253 | $this->oneToMany[$member] = \compact('mappedBy', 'className'); 254 | } 255 | 256 | public function addManyToMany($member, $otherClassName, $otherMember, $joinTable, $joinColumn, $otherJoinColumn) { 257 | $this->manyToMany[$member] = compact('otherClassName', 'otherMember', 'joinTable', 'joinColumn', 'otherJoinColumn'); 258 | } 259 | 260 | /** 261 | * 262 | * @return array 263 | */ 264 | public function getManyToOne(): array { 265 | return $this->manyToOne; 266 | } 267 | 268 | /** 269 | * 270 | * @return array 271 | */ 272 | public function getOneToMany(): array { 273 | return $this->oneToMany; 274 | } 275 | 276 | /** 277 | * 278 | * @return array 279 | */ 280 | public function getManyToMany(): array { 281 | return $this->manyToMany; 282 | } 283 | 284 | /** 285 | * 286 | * @return bool 287 | */ 288 | public function isLoaded(): bool { 289 | return $this->loaded; 290 | } 291 | 292 | /** 293 | * 294 | * @param bool $loaded 295 | */ 296 | public function setLoaded(bool $loaded): void { 297 | $this->loaded = $loaded; 298 | } 299 | 300 | /** 301 | * 302 | * @return bool 303 | */ 304 | public function isUpdated(): bool { 305 | return $this->updated; 306 | } 307 | 308 | /** 309 | * 310 | * @param bool $updated 311 | */ 312 | public function setUpdated(bool $updated): void { 313 | $this->updated = $updated; 314 | } 315 | 316 | /** 317 | * 318 | * @param array $manyToOne 319 | */ 320 | public function setManyToOne(array $manyToOne): void { 321 | $this->manyToOne = $manyToOne; 322 | } 323 | 324 | /** 325 | * 326 | * @param array $oneToMany 327 | */ 328 | public function setOneToMany(array $oneToMany): void { 329 | $this->oneToMany = $oneToMany; 330 | } 331 | 332 | /** 333 | * 334 | * @param array $manyToMany 335 | */ 336 | public function setManyToMany(array $manyToMany): void { 337 | $this->manyToMany = $manyToMany; 338 | } 339 | 340 | public function getRelationsAsString() { 341 | $result = ''; 342 | if (\count($this->manyToOne) > 0) { 343 | $result .= ' (1)=>(' . \implode(',', \array_keys($this->manyToOne)) . ')'; 344 | } 345 | if (\count($this->oneToMany) > 0) { 346 | $result .= ' (1-*)=>(' . \implode(',', \array_keys($this->oneToMany)) . ')'; 347 | } 348 | if (\count($this->manyToMany) > 0) { 349 | $result .= ' (*-*)=>(' . \implode(',', \array_keys($this->manyToMany)) . ')'; 350 | } 351 | return $result; 352 | } 353 | 354 | /** 355 | * 356 | * @return bool 357 | */ 358 | public function isLoadedFromCache(): bool { 359 | return $this->loadedFromCache; 360 | } 361 | 362 | /** 363 | * 364 | * @param bool $loadedFromCache 365 | */ 366 | public function setLoadedFromCache(bool $loadedFromCache): void { 367 | $this->loadedFromCache = $loadedFromCache; 368 | } 369 | } 370 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [unreleased] 8 | - nothing 9 | 10 | ## [1.4.8] - 2023-02-05 11 | ### Added 12 | - **v(view)** option with **create-project(new)** command 13 | 14 | ## [1.4.3] - 2022-12-31 15 | ### Updated 16 | - `aclInit` command (add table and models creation) 17 | - `new project` (add init-cache after creation) 18 | 19 | ## [1.4.2] - 2022-12-19 20 | ### Fixed 21 | - add `vlucas/phpdotenv` in composer.json 22 | 23 | ## [1.4.1] - 2022-12-18 24 | ### Fixed 25 | - config cache first initialization 26 | 27 | ## [1.4.0] - 2022-12-18 28 | ### Updated 29 | - Compatibility with Ubiquity 2.5.0 30 | ### Added 31 | - env vars support 32 | ## [1.3.11] - 2022-05-06 33 | ### Updated 34 | - Change root directory to `public` for async platforms 35 | 36 | ## [1.3.10] - 2022-02-15 37 | ### Fixed 38 | - `InstallThemeCmd` pb with `DDDManager` 39 | 40 | ## [1.3.9] - 2022-02-13 41 | 42 | ### Updated 43 | - Default vHeader and vFooter templates 44 | - Add create and 2FA views for Auth controllers 45 | 46 | 47 | ## [1.3.8] - 2022-01-01 48 | ### Fixed 49 | - cache initialization pb with `new-model` command 50 | 51 | ### Changed 52 | - `str_pad` usage for questions in commands 53 | - relocate livereload starting (after nonce creation) 54 | - add nonce in template files 55 | - add default nonce 56 | 57 | ## [1.3.7] - 2021-12-02 58 | ### Fixed 59 | - Other models loading +cache re-init in `new-model` command 60 | - Re-init cache before migrations commands 61 | - typo in `addRelation`: `$namepsace` 62 | 63 | ## [1.3.6] - 2021-12-01 64 | 65 | ### Added 66 | #### Migrations commands: 67 | 68 | ``` 69 | ■ info-migrations [] => 70 | · Returns the migration infos. 71 | · Aliases : info_migrations,info:migrations,infoMigrations 72 | · Parameters : 73 | -d shortcut of --database 74 | The database offset. 75 | Default : [default] 76 | 77 | -o shortcut of --domain 78 | The domain in which the database models are. 79 | 80 | × Samples : 81 | Display all migrations for the default database 82 | · Ubiquity info:migrations 83 | ``` 84 | 85 | ``` 86 | ■ migrations [] => 87 | · Display and execute the database migrations. 88 | · Aliases : migrations,migrate 89 | · Parameters : 90 | -d shortcut of --database 91 | The database offset. 92 | Default : [default] 93 | 94 | -o shortcut of --domain 95 | The domain in which the database models are. 96 | 97 | × Samples : 98 | Display and execute all migrations for the default database 99 | · Ubiquity migrations 100 | ``` 101 | #### Models creation 102 | 103 | ``` 104 | ■ model [modelName] => 105 | · Generates models from scratch. 106 | · Aliases : create_model,create:model,create-model,createModel,new_model,new:model,new-model,newModel 107 | · Parameters : 108 | -d shortcut of --database 109 | The database connection to use 110 | Default : [default] 111 | 112 | -o shortcut of --domain 113 | The domain in which to create the model. 114 | 115 | -k shortcut of --autoincPk 116 | The default primary key defined as autoinc. 117 | Default : [id] 118 | 119 | × Samples : 120 | · Ubiquity model User 121 | · Ubiquity model Author -d=projects 122 | · Ubiquity model Group,User -o=orga 123 | ``` 124 | 125 | ## [1.3.5] - 2021-11-01 126 | 127 | ### Added 128 | - Adds Domain option (`-o` or `--domain`) for commands: `controller, action, auth, crud-index, model, all-models, dao, rest, rest-api, info-model, info-models, info-validation` 129 | 130 | ### Updated 131 | - Command names parsing: 132 | For all commands with multiple parts in the name, the following syntaxes can be used: 133 | ex: for `Ubiquity all-models` 134 | - `Ubiquity all_models` 135 | - `Ubiquity all:models` 136 | - `Ubiquity allModels` 137 | 138 | ## [1.3.4] - 2021-10-07 139 | ### Fixed 140 | - assets folder location with Ubiquity server 141 | 142 | ## [1.3.3] - 2021-09-06 143 | ### Updated 144 | - Default index page 145 | - ui libraries 146 | 147 | ## [1.3.2] - 2021-07-11 148 | #### Added 149 | - `index-crud` command 150 | 151 | ## [1.3.1] - 2021-07-06 152 | #### Fixed 153 | - Application root pb (public folder) with embedded web server 154 | 155 | ## [1.3.0] - 2021-06-15 156 | #### Models generation 157 | - The regeneration of models preserves the code implemented on the existing models. 158 | 159 | #### Application root (breaking change) 160 | - For apache and nginX, root folder is set to public folder (for new projects since Ubiquity 2.4.5) 161 | 162 | For an old project (created with a version prior to 2.4.5), you have to modify ``index.php`` and move the ``index.php`` and ``.htaccess`` files to the ``public`` folder. 163 | 164 | ```php 165 | no routes displayed 182 | 183 | ## [1.2.26] - 2021-03-10 184 | ### Fixed 185 | - crud & rest commands bug 186 | >Call to a member function asAnnotation on null 187 | >BaseControllerCreator line 58 188 | 189 | ## [1.2.25] - 2021-02-15 190 | ### Fixed 191 | - Bug on new class command with parent class (inheritance) 192 | 193 | ## [1.2.24] - 2021-02-08 194 | ### Added 195 | - `newClass` command for creating a new class 196 | 197 | ## [1.2.23] - 2021-02-06 198 | ### Updated 199 | - replace `livereloadx` with `livereload` 200 | >livereloadx has not been updated for 2 years, and does not manage file operations (add, delete). 201 | 202 | - add livereload with default php server 203 | 204 | Starts php web server and livereload (on 35729 port) 205 | ```bash 206 | Ubiquity serve 207 | ``` 208 | 209 | Starts php web server without livereload 210 | ```bash 211 | Ubiquity serve -n 212 | ``` 213 | 214 | ## [1.2.22] - 2021-02-05 215 | ### Added 216 | - `live-reload` command for dev server 217 | 218 | ## [1.2.21] - 2021-01-17 219 | ### Added 220 | - `newKey` command for generating the encryption key with Ubiquity-security 221 | 222 | ## [1.2.20] - 2020-12-31 223 | ### Fixed 224 | - new action problem 225 | >Call to a member function asAnnotation() on null 226 | 227 | ## [1.2.19] - 2020-12-31 228 | 229 | ### Updated 230 | - Add attributes or annotations fix 231 | 232 | ## [1.2.18] - 2020-12-11 233 | 234 | ### Added 235 | - `display-acls` command 236 | 237 | ### Updated 238 | - composer for php 8 239 | 240 | ## [1.2.17] - 2020-09-30 241 | ### Updated 242 | - add access option (member access) to all-models & create-model cmd 243 | - add db offset param to info:models command 244 | - add OS in version command 245 | 246 | ## [1.2.16] - 2020-07-28 247 | ### Updated 248 | - Update client libraries for new projects (Fomantic 2.8.6) 249 | - Fix session name generation pb (only alphanumeric chars) 250 | 251 | ## [1.2.15] - 2020-06-27 252 | ### Added 253 | - Add `create:command`command 254 | - support for custom commands 255 | ### Updated 256 | - move utility classes to `ubiquity-commands` repo 257 | - Update client libraries for new projects (Fomantic 2.8.5) 258 | 259 | ## [1.2.14] - 2020-05-06 260 | #### Updated 261 | - Update client libraries for new projects (Fomantic 2.8.4, jQuery 3.5.1) 262 | - Add port checking for `Ubiquity serve` command 263 | ## [1.2.13] - 2020-03-23 264 | #### Added 265 | - roadrunner server command (Thanks @Lapinskas) 266 | 267 | `Ubiquity serve -t=roadrunner` 268 | #### Added 269 | 270 | ## [1.2.12] - 2020-01-25 271 | #### Added 272 | - Mailer commands (mailer, newMail, sendMail) 273 | - opcache preloading in project creation 274 | #### Changed 275 | - set `help` as default command 276 | - require php 7.4 277 | 278 | ## [1.2.11] - 2019-11-18 279 | #### Changed 280 | - Update client libraries for new projects (Fomantic 2.8, jQuery 3.4.1, phpMv-ui 2.3) 281 | - require php 7.2 282 | 283 | ## [1.2.10] - 2019-10-28 284 | #### Added 285 | - Composer create-project 286 | ``` 287 | composer create-project phpmv/ubiquity-project {projectName} 288 | ``` 289 | 290 | ## [1.2.9] - 2019-09-25 291 | ### Fixed 292 | - [Cannot set database](https://github.com/phpMv/ubiquity/issues/74) 293 | - https://github.com/phpMv/ubiquity/issues/72 294 | - Fix https://github.com/phpMv/ubiquity-devtools/commit/c06b6704126a4bf56b2a6a52c60aa1d40edcfcdb 295 | ### Added 296 | #### Commands 297 | - `composer` [cmd] 298 | 299 | Samples: 300 | ``` 301 | Ubiquity composer update 302 | Ubiquity composer nodev 303 | Ubiquity composer optimize 304 | ``` 305 | - `bootstrap` [cmd] 306 | 307 | Execute the `cmd` method from the `.ubiquity/_bootstrap.php` file to prepare an environment. 308 | 309 | Sample: 310 | ``` 311 | Ubiquity bootstrap prod 312 | Ubiquity bootstrap dev 313 | ``` 314 | ## [1.2.8] - 2019-08-01 315 | ### Changed 316 | - `model` (`create-model`) command 317 | - added parameter `d`(`database`): the database connection name defined in config file (use default connection if absent) 318 | 319 | Samples: 320 | ``` 321 | Ubiquity model Author -d=projects 322 | Ubiquity model Author --database=projects 323 | ``` 324 | 325 | - `all-models` (`create-all-models`) command 326 | - added parameter `d`(`database`): the database connection name defined in config file (use default connection if absent) 327 | - removed parameter `b`(`dbName`): the database name defined in config file 328 | 329 | Samples: 330 | ``` 331 | Ubiquity all-models -d=projects 332 | Ubiquity create-all-models --database=projects 333 | ``` 334 | ## [1.2.7] - 2019-07-03 335 | ### Changed 336 | - Checks if devtools are globally installed in ``sefUpdate`` op 337 | - Integrates ubiquity-webtools ``2.2.0`` (in a separate repository) 338 | 339 | ### Fixed 340 | - Remove warning for ``\DS`` constant redefinition (thanks @TakeMeNL) 341 | 342 | ## [1.2.6] - 2019-06-13 343 | ### Added 344 | - Ubiquity Swoole server: ``Ubiquity serve -t=swoole`` 345 | - Parameters for `new` command see [#45](https://github.com/phpMv/ubiquity/issues/45) 346 | - `siteUrl (i)` : Sets the site base URL. 347 | - `rewriteBase (e)` : Sets .htaccess file rewriteBase. 348 | 349 | Use 350 | ``` 351 | Ubiquity new fooProject -i=http://foo.local -w=foo 352 | ``` 353 | or 354 | ``` 355 | Ubiquity new fooProject --siteUrl=http://foo.local --rewriteBase=foo 356 | ``` 357 | ## [1.2.5] - 2019-05-10 358 | ### Fixed 359 | - Warning in pages with php Web server Fix: [#5](https://github.com/phpMv/ubiquity-devtools/issues/5) 360 | 361 | ## [1.2.4] - 2019-05-09 362 | ### Added 363 | - **README.md** file for new projects 364 | - ReactPHP server: ```Ubiquity serve t=react``` 365 | 366 | ### Fixed 367 | - Change of theme without control in the ``ct`` action of ``IndexController`` for new projects : see Ubiquity issue [#38](https://github.com/phpMv/ubiquity/issues/38) 368 | 369 | ## [1.2.3] - 2019-04-03 370 | - relooking of the messages for clarity 371 | 372 | ## [1.2.2] - 2019-04-02 373 | - Fix issue [#22](https://github.com/phpMv/ubiquity/issues/22) (install without -a option bug) 374 | 375 | ## [1.2.0] - 2019-04-01 376 | ### Added 377 | - Commands 378 | - `install-theme` for installing Bootstrap, Semantic-UI or Foundation 379 | - `create-theme` for creating a new theme (eventually based on a ref theme) 380 | ### Changed 381 | - `services.tpl file` 382 | ### Fixed 383 | - An exception is thrown In case of problem with the Database connection (in `DataBase::connect` method) see https://github.com/phpMv/ubiquity/issues/12 384 | >The connection to the database must be protected by a `try/catch` in `app/config/services.php` 385 | ``` 386 | try{ 387 | \Ubiquity\orm\DAO::startDatabase($config); 388 | }catch(Exception $e){ 389 | echo $e->getMessage(); 390 | } 391 | ``` 392 | 393 | ## [1.1.6] - 2019-03-14 394 | ### Added 395 | - New commands 396 | - ``Ubiquity restapi`` -> create a REST API controller (based on JsonApi) 397 | - ``Ubiquity rest`` -> create a REST controller associated to a model 398 | - ``Ubiquity dao`` -> query the database 399 | - getOne 400 | - getAll 401 | - uGetOne 402 | - uGetAll 403 | - count 404 | - uCount 405 | 406 | ### Fixed 407 | - [New project template has invalid link to Admin page](https://github.com/phpMv/ubiquity/issues/8) 408 | 409 | ## [1.1.5] - 2019-02-22 410 | ### Added 411 | - New commands 412 | - ``Ubiquity config`` -> display config file variables 413 | - ``Ubiquity config:set --database.dbName=blog`` -> modify/add and save config variables 414 | - ``Ubiquity info:models`` -> display all models metadatas 415 | - ``Ubiquity info:model -m=User`` -> display metadatas for the selected model 416 | - ``Ubiquity info:validation`` -> display validation infos for all models or the selected one 417 | 418 | ### Changed 419 | - Project structure (commands are in separate classes). 420 | - services.tpl template for new project creation 421 | 422 | ## [1.1.4] - 2019-02-18 423 | ### Added 424 | - New commands 425 | - ``Ubiquity info:routes`` -> display the router informations/test the routes resolution (with -s parameter) 426 | 427 | ### Changed 428 | - Project structure (src folder). 429 | 430 | ## [1.1.3] - 2019-02-13 431 | ### Added 432 | - New commands 433 | - ``Ubiquity serve`` -> php internal web server for dev 434 | -------------------------------------------------------------------------------- /src/devtools/cmd/commands/NewModelCmd.php: -------------------------------------------------------------------------------- 1 | $model) { 71 | $oName = $name; 72 | if ($model->isUpdated()) { 73 | $name .= '*'; 74 | } 75 | if (\strtolower($oName) === \strtolower(self::$currentModelName)) { 76 | $result[] = "$name"; 77 | } else { 78 | $result[] = $name; 79 | } 80 | } 81 | return \implode(',', $result); 82 | } 83 | 84 | private static function addPk($pk) { 85 | $class = self::$currentModel; 86 | $class->addPk($pk); 87 | 88 | if (! $class->hasField($pk)) { 89 | echo ConsoleFormatter::showMessage("$pk is not in field list", 'warning', 'Add primary keys'); 90 | $q = Console::yesNoQuestion("Would you like to add $pk in field list?", [ 91 | 'yes', 92 | 'no' 93 | ]); 94 | if (Console::isYes($q)) { 95 | $fieldType = Console::question("Enter field type : "); 96 | self::addFields($pk, $fieldType, ''); 97 | } 98 | } 99 | } 100 | 101 | private static function getFieldNames() { 102 | return self::$currentModel->getFieldNames(); 103 | } 104 | 105 | private static function addFields($fields, $fieldTypes, $nullables) { 106 | $fields = Console::explodeResponse($fields); 107 | $fieldTypes = Console::explodeResponse($fieldTypes); 108 | $nullables = Console::explodeResponse($nullables); 109 | $newModel = self::$currentModel; 110 | foreach ($fields as $index => $field) { 111 | $field = \trim($field); 112 | if ($field != '') { 113 | $nullable = \array_search($field, $nullables) !== false; 114 | $newModel->addField($field, [ 115 | 'Type' => $fieldTypes[$index] ?? DbTypes::DEFAULT_TYPE, 116 | 'Nullable' => $nullable ? 'true' : 'false' 117 | ]); 118 | } 119 | } 120 | } 121 | 122 | private static function generateClasses(string $namespace, string $dbOffset) { 123 | $messages = []; 124 | $classes = []; 125 | foreach (self::$allModels as $name => $newModel) { 126 | $class = $newModel->generateClass($name, $namespace, $dbOffset); 127 | $classes[$name] = $class; 128 | } 129 | 130 | self::createRelations($classes, $namespace); 131 | 132 | foreach (self::$allModels as $name => $newModel) { 133 | if ($newModel->isUpdated()) { 134 | $class = $classes[$name]; 135 | $msg = self::createClass($class, $newModel, $name, $namespace); 136 | if ($msg['type'] === 'success') { 137 | $messages['success'][] = $msg['message']; 138 | } else { 139 | $messages['error'][] = $msg['message']; 140 | } 141 | } 142 | } 143 | self::showMessages('success', $messages); 144 | self::showMessages('error', $messages); 145 | $rep = Console::yesNoQuestion('Do you want to re-init models cache?', [ 146 | 'yes', 147 | 'no' 148 | ]); 149 | if (Console::isYes($rep)) { 150 | global $argv; 151 | echo shell_exec($argv[0] . ' init-cache -t=models'); 152 | } 153 | self::saveModelsInCache(); 154 | die(); 155 | } 156 | 157 | private static function createRelations($classes, $namespace) { 158 | foreach (self::$allModels as $name => $newModel) { 159 | $manyToOnes = $newModel->getManyToOne(); 160 | $oneToManys = $newModel->getOneToMany(); 161 | $manyToManys = $newModel->getManyToMany(); 162 | $class = $classes[$name]; 163 | foreach ($manyToOnes as $member => $manyToOne) { 164 | $class->addManyToOne($member, $manyToOne['fkField'], $namespace . $manyToOne['className'], $member); 165 | } 166 | foreach ($oneToManys as $member => $oneToMany) { 167 | $class->addOneToMany($member, $oneToMany['mappedBy'], $namespace . $oneToMany['className'], $member); 168 | } 169 | 170 | foreach ($manyToManys as $member => $manyToMany) { 171 | $class->addManyToMany($member, $namespace . $manyToMany['otherClassName'], $manyToMany['otherMember'], $manyToMany['joinTable'], $manyToMany['joinColumn'], $manyToMany['otherJoinColumn']); 172 | } 173 | } 174 | } 175 | 176 | private static function showMessages(string $type, array $messages): void { 177 | if (isset($messages[$type])) { 178 | echo ConsoleFormatter::showMessage(\implode(PHP_EOL, $messages[$type]), $type, 'Classes creation'); 179 | } 180 | } 181 | 182 | private static function store(string $className, NewModel $newModel): void { 183 | $content = [ 184 | 'defaultPk' => ($newModel->getDefaultPk() ?? ''), 185 | 'pks' => $newModel->getPks(), 186 | 'fields' => $newModel->getFields(), 187 | 'manyToOne' => $newModel->getManyToOne(), 188 | 'oneToMany' => $newModel->getOneToMany(), 189 | 'manyToMany' => $newModel->getManyToMany() 190 | ]; 191 | CacheManager::$cache->store(self::CACHE_KEY . $className, $content); 192 | } 193 | 194 | private static function loadFromCache(string $className, ?NewModel $newModel = null): void { 195 | $result = CacheManager::$cache->fetch(self::CACHE_KEY . $className); 196 | $newModel ??= self::$currentModel; 197 | $newModel->setFields($result['fields']); 198 | $newModel->setDefaultPk($result['defaultPk']); 199 | $newModel->setPks($result['pks']); 200 | $newModel->setManyToOne($result['manyToOne'] ?? []); 201 | $newModel->setOneToMany($result['oneToMany'] ?? []); 202 | $newModel->setManyToMany($result['manyToMany'] ?? []); 203 | $newModel->setLoadedFromCache(true); 204 | } 205 | 206 | private static function reloadFromExistingClass(string $completeClassName): bool { 207 | if (CacheManager::modelCacheExists($completeClassName)) { 208 | $newModel = self::$currentModel; 209 | $metaDatas = CacheManager::getOrmModelCache($completeClassName); 210 | self::checkAutoInc($newModel, $completeClassName); 211 | $newModel->setPks(\array_keys($metaDatas['#primaryKeys'])); 212 | $memberNames = \array_keys($metaDatas['#fieldNames']); 213 | $types = $metaDatas['#fieldTypes']; 214 | $nullables = $metaDatas['#nullable']; 215 | $fields = []; 216 | foreach ($memberNames as $memberName) { 217 | $fields[$memberName] = [ 218 | 'Type' => $types[$memberName] ?? 'mixed', 219 | 'Nullable' => in_array($memberName, $nullables) ? 'true' : 'false' 220 | ]; 221 | } 222 | $newModel->setFields($fields); 223 | $newModel->setTableName($metaDatas['#tableName']); 224 | self::reloadFromExistingClassRelations($newModel, $metaDatas); 225 | $newModel->setLoadedFromCache(true); 226 | $newModel->setLoaded(true); 227 | return true; 228 | } 229 | return false; 230 | } 231 | 232 | private static function reloadFromExistingClassRelations(NewModel $newModel, array $metaDatas) { 233 | $manyToOnes = $metaDatas['#manyToOne'] ?? []; 234 | $joinColumns = $metaDatas['#joinColumn'] ?? []; 235 | foreach ($manyToOnes as $manyToOne) { 236 | $joinColumn = $joinColumns[$manyToOne]; 237 | $newModel->addManyToOne($manyToOne, $joinColumn['name'], ClassUtils::getClassSimpleName($joinColumn['className'])); 238 | } 239 | 240 | $oneToManys = $metaDatas['#oneToMany'] ?? []; 241 | foreach ($oneToManys as $member => $oneToMany) { 242 | $newModel->addOneToMany($member, $oneToMany['mappedBy'], ClassUtils::getClassSimpleName($oneToMany['className'])); 243 | } 244 | 245 | $manyToManys = $metaDatas['#manyToMany'] ?? []; 246 | $joinTables = $metaDatas['#joinTable'] ?? []; 247 | foreach ($manyToManys as $member => $manyToMany) { 248 | $jointable = $joinTables[$member]; 249 | $joinColumn = $jointable['joinColumns'] ?? []; 250 | $inverseJoinColumn = $jointable['inverseJoinColumns'] ?? []; 251 | $newModel->addManyToMany($member, ClassUtils::getClassSimpleName($manyToMany['targetEntity']), $manyToMany['inversedBy'], $jointable['name'], $joinColumn, $inverseJoinColumn); 252 | } 253 | } 254 | 255 | private static function checkAutoInc(NewModel $newModel, string $completeClassName) { 256 | $validationMetas = ValidatorsManager::getCacheInfo($completeClassName); 257 | foreach ($validationMetas as $member => $validators) { 258 | foreach ($validators as $infos) { 259 | if ($infos['type'] === 'id') { 260 | if (($infos['constraints']['autoinc'] ?? false) === true) { 261 | $newModel->setDefaultPk($member); 262 | return; 263 | } 264 | } 265 | } 266 | } 267 | } 268 | 269 | private static function createClass(Model $model, NewModel $newModel, string $modelName, string $namespace): array { 270 | $className = $model->getName(); 271 | $modelsDir = UFileSystem::getDirFromNamespace($namespace); 272 | echo ConsoleFormatter::showInfo("Creating the {$className} class"); 273 | $classContent = $model->__toString(); 274 | if (UFileSystem::save($modelsDir . \DS . $model->getSimpleName() . '.php', $classContent)) { 275 | return [ 276 | 'type' => 'success', 277 | 'message' => "Class $className created with success!" 278 | ]; 279 | } 280 | return [ 281 | 'type' => 'error', 282 | 'message' => "Class $className not generated!" 283 | ]; 284 | } 285 | 286 | private static function loadModel(NewModel $newModel, string $modelName, string $namespace): bool { 287 | $modelCompleteName = $namespace . $modelName; 288 | 289 | if (self::$loadCurrentModels && ! $newModel->isLoadedFromCache()) { 290 | self::reloadFromExistingClass($modelCompleteName); 291 | return false; 292 | } 293 | $restrict = false; 294 | if (! $newModel->isLoaded()) { 295 | if (CacheManager::$cache->exists(self::CACHE_KEY . $modelName) && ! \class_exists($modelCompleteName)) { 296 | $rep = Console::yesNoQuestion("A model with the name $modelName was already created.\nWould you like to reload it from cache?", [ 297 | 'yes', 298 | 'no' 299 | ]); 300 | if (Console::isYes($rep)) { 301 | self::loadFromCache($modelName); 302 | } 303 | } 304 | if (\class_exists($modelCompleteName)) { 305 | echo ConsoleFormatter::showMessage("The class $modelCompleteName already exists!", 'warning', 'Update model'); 306 | $rep = Console::yesNoQuestion('Would you like to modify the existing class?', [ 307 | 'yes', 308 | 'no' 309 | ]); 310 | if (Console::isYes($rep)) { 311 | if (self::reloadFromExistingClass($modelCompleteName)) { 312 | echo ConsoleFormatter::showMessage("Loading infos for class $modelCompleteName from DAO cache.", 'info', 'Update model'); 313 | } else { 314 | echo ConsoleFormatter::showMessage("No cache infos for $modelCompleteName.", 'error', 'Update model'); 315 | die(); 316 | } 317 | } else { 318 | $restrict = true; 319 | } 320 | } 321 | $newModel->setLoaded(true); 322 | 323 | if (! $newModel->isLoadedFromCache() && isset(self::$defaultPkValue)) { 324 | $newModel->setDefaultPk(self::$defaultPkValue); 325 | } 326 | } 327 | 328 | return $restrict; 329 | } 330 | 331 | private static function firstLoadAllModels(array $models) { 332 | foreach ($models as $index => $modelName) { 333 | self::getNewModel($modelName, $index === 0); 334 | } 335 | } 336 | 337 | private static function loadModelsFrom(array $config, string $dbOffset = 'default'): array { 338 | $models = CacheManager::getModels($config, true, $dbOffset); 339 | if (\count($models) > 0) { 340 | return \array_map(function ($model) { 341 | return ClassUtils::getClassSimpleName($model); 342 | }, $models); 343 | } 344 | return []; 345 | } 346 | 347 | public static function run(&$config, $options, $what) { 348 | $domain = self::updateDomain($options); 349 | $dbOffset = self::getOption($options, 'd', 'database', 'default'); 350 | self::$defaultPkValue = self::getOption($options, 'k', 'autoincPk', 'id'); 351 | self::checkDbOffset($config, $dbOffset); 352 | 353 | CacheManager::start($config); 354 | 355 | $models = Console::explodeResponse($what ?? '', function ($item) { 356 | return \ucfirst(\trim($item)); 357 | }); 358 | 359 | if (\count($models) === 0) { 360 | $models = self::loadModelsFrom($config, $dbOffset); 361 | if (count($models) > 0) { 362 | $rep = Console::yesNoQuestion("Would you like to load the current classes [" . \implode(',', $models) . "]?"); 363 | if (Console::isNo($rep)) { 364 | $models = []; 365 | } else { 366 | self::$loadCurrentModels = true; 367 | } 368 | } 369 | } 370 | if (\count($models) > 0) { 371 | self::firstLoadAllModels($models); 372 | 373 | $modelName = self::$currentModelName; 374 | $newModel = self::$currentModel; 375 | } else { 376 | $modelName = Console::question("Enter a model name: "); 377 | $newModel = self::getNewModel($modelName); 378 | } 379 | 380 | $fields = ''; 381 | $checkExisting = []; 382 | do { 383 | $namespace = self::getModelNamespace($domain, $dbOffset); 384 | $modelCompleteName = $namespace . $modelName; 385 | 386 | $restrict = self::loadModel($newModel, $modelName, $namespace); 387 | $tableName = $newModel->getTableName(); 388 | 389 | echo ConsoleFormatter::showMessage("Model: $modelCompleteName", 'info', 'Model add/update'); 390 | 391 | $caseChangeDbOffset = "Change dbOffset [$dbOffset]"; 392 | $caseChangeActiveDomain = "Change active Domain [$domain]"; 393 | $caseSwitchModel = "Add/switch to model [" . self::getAllModelsAsString() . "]"; 394 | 395 | $fields = \implode(',', $newModel->getFieldNames()); 396 | $caseAddFields = "Add fields [$fields]"; 397 | $caseAddDefaultPk = "Add default auto-inc primary key [" . ($newModel->getDefaultPk() ?? '') . "]"; 398 | $caseChangeTableName = "Change table name [$tableName]"; 399 | $caseAddRelations = "Add relations [" . $newModel->getRelationsAsString() . "]"; 400 | 401 | if (! $restrict) { 402 | $choices = [ 403 | $caseAddFields, 404 | $caseAddDefaultPk, 405 | 'Add primary keys', 406 | $caseAddRelations, 407 | $caseChangeTableName, 408 | $caseChangeDbOffset, 409 | $caseChangeActiveDomain, 410 | $caseSwitchModel, 411 | 'Generate classes', 412 | 'Quit' 413 | ]; 414 | } else { 415 | $choices = [ 416 | 'Change class name', 417 | $caseChangeDbOffset, 418 | $caseChangeActiveDomain, 419 | 'Quit' 420 | ]; 421 | } 422 | $rep = Console::question('Select your choices:', $choices); 423 | 424 | switch ($rep) { 425 | 426 | case 'Change class name': 427 | $modelName = Console::question("Enter model name: "); 428 | $modelName = \ucfirst($modelName); 429 | unset(self::$allModels[self::$currentModelName]); 430 | self::$allModels[$modelName] = self::$currentModel; 431 | self::$currentModelName = $modelName; 432 | $newModel->setUpdated(true); 433 | break; 434 | 435 | case $caseChangeTableName: 436 | $tbl = Console::question('Enter table name:'); 437 | $newModel->setTableName(($tbl == '') ? null : $tbl); 438 | $newModel->setUpdated(true); 439 | break; 440 | 441 | case $caseAddFields: 442 | $field = Console::question("Enter field names: "); 443 | if ($field != '') { 444 | $fieldTypes = Console::question("Enter field types: "); 445 | $nullables = Console::question("Nullable fields: "); 446 | self::addFields($field, $fieldTypes, $nullables); 447 | $newModel->setUpdated(true); 448 | } 449 | break; 450 | 451 | case $caseSwitchModel: 452 | $modelName = Console::question('Enter an existing or a new model name:'); 453 | $modelName = \ucfirst($modelName); 454 | $newModel = self::getNewModel($modelName); 455 | break; 456 | 457 | case 'Add primary keys': 458 | $pks = Console::question('Enter primary keys: '); 459 | $newModel->updatePks($pks); 460 | $newModel->setUpdated(true); 461 | break; 462 | 463 | case $caseAddRelations: 464 | $rType = Console::question('Type: ', [ 465 | 'manyToOne', 466 | 'oneToMany', 467 | 'manyToMany' 468 | ]); 469 | self::addRelation($rType, $newModel, $namespace); 470 | break; 471 | 472 | case $caseAddDefaultPk: 473 | $newModel->setDefaultPk(Console::question('Primary key name: ')); 474 | $newModel->setUpdated(true); 475 | break; 476 | 477 | case $caseChangeDbOffset: 478 | $dbOffset = Console::question('Database offset: '); 479 | self::checkDbOffset($config, $dbOffset); 480 | break; 481 | 482 | case $caseChangeActiveDomain: 483 | $newDomain = Console::question('Domain: '); 484 | $domain = self::updateDomain([ 485 | 'o' => $newDomain 486 | ]); 487 | if ($domain == '') { 488 | DDDManager::resetActiveDomain(); 489 | } 490 | break; 491 | 492 | case 'Generate classes': 493 | self::generateClasses(self::getModelNamespace($domain, $dbOffset), $dbOffset); 494 | break; 495 | 496 | default: 497 | self::saveModelsInCache(); 498 | echo ConsoleFormatter::showInfo('Operation terminated, Bye!'); 499 | } 500 | } while ($rep !== 'Quit'); 501 | } 502 | 503 | private static function saveModelsInCache() { 504 | $cached = []; 505 | foreach (self::$allModels as $modelName => $newModel) { 506 | if ($newModel->isUpdated()) { 507 | self::store($modelName, $newModel); 508 | $cached[] = $modelName; 509 | } 510 | } 511 | if (\count($cached) > 0) { 512 | echo ConsoleFormatter::showInfo("Data caching for the models: " . \implode(',', $cached)); 513 | } 514 | } 515 | 516 | private static function addRelation(string $rType, NewModel $newModel, string $namespace) { 517 | $modelName = $newModel->getOriginalModelName(); 518 | 519 | switch ($rType) { 520 | case 'manyToOne': 521 | $fkClass = Console::question('Foreign member className:', \array_keys(self::$allModels), [ 522 | 'ignoreCase' => true 523 | ]); 524 | $otherModel = self::getNewModel($fkClass, false); 525 | $otherModelName = $otherModel->getOriginalModelName(); 526 | 527 | $padmax = \strlen("OneToMany member name in $otherModelName:"); 528 | 529 | $fkField = Console::question(\str_pad('Foreign key name:', $padmax), null, [ 530 | 'default' => 'id' . \ucfirst($otherModelName) 531 | ]); 532 | $member = Console::question(\str_pad('Member name:', $padmax), null, [ 533 | 'default' => \lcfirst($otherModelName) 534 | ]); 535 | 536 | $manyMember = Console::question(\str_pad("OneToMany member name in $otherModelName:", $padmax), null, [ 537 | 'default' => \lcfirst($modelName) . 's' 538 | ]); 539 | 540 | $newModel->addManyToOne($member, $fkField, $otherModelName); 541 | if (! $otherModel->isLoaded()) { 542 | self::loadModel($otherModel, $otherModelName, $namespace); 543 | } 544 | $otherModel->addOneToMany($manyMember, $member, $modelName); 545 | 546 | $newModel->setUpdated(true); 547 | $otherModel->setUpdated(true); 548 | break; 549 | case 'manyToMany': 550 | $padmax = 45; 551 | $fkClass = Console::question(\str_pad('Associated className:', $padmax), \array_keys(self::$allModels), [ 552 | 'ignoreCase' => true 553 | ]); 554 | $otherModel = self::getNewModel($fkClass, false); 555 | $otherModelName = $otherModel->getOriginalModelName(); 556 | 557 | $member = Console::question(\str_pad("Associated member name in $modelName:", $padmax), null, [ 558 | 'default' => \lcfirst($otherModelName) . 's' 559 | ]); 560 | $otherAssociatedFk = Console::question(\str_pad("Associated fk name for $otherModelName:", $padmax), null, [ 561 | 'default' => 'id' . \ucfirst($otherModelName) 562 | ]); 563 | 564 | $otherMember = Console::question(\str_pad("Associated member name in $otherModelName:", $padmax), null, [ 565 | 'default' => \lcfirst($modelName) . 's' 566 | ]); 567 | $associatedFk = Console::question(\str_pad("Associated fk name for $modelName:", $padmax), null, [ 568 | 'default' => 'id' . \ucfirst($modelName) 569 | ]); 570 | $jointable = Console::question(\str_pad('Jointable:', $padmax), null, [ 571 | 'default' => \lcfirst($modelName) . '_' . \lcfirst($otherModelName) . 's' 572 | ]); 573 | 574 | $joinColumn = ($associatedFk !== $newModel->getDefaultFk()) ? [ 575 | 'name' => $associatedFk, 576 | 'referencedColumnName' => $newModel->getFirstPk() 577 | ] : []; 578 | $otherJoinColumn = ($otherAssociatedFk !== $otherModel->getDefaultFk()) ? [ 579 | 'name' => $otherAssociatedFk, 580 | 'referencedColumnName' => $otherModel->getFirstPk() 581 | ] : []; 582 | 583 | $newModel->addManyToMany($member, $otherModelName, $otherMember, $jointable, $joinColumn, $otherJoinColumn); 584 | if (! $otherModel->isLoaded()) { 585 | self::loadModel($otherModel, $otherModelName, $namespace); 586 | } 587 | $otherModel->addManyToMany($otherMember, $modelName, $member, $jointable, $otherJoinColumn, $joinColumn); 588 | $newModel->setUpdated(true); 589 | $otherModel->setUpdated(true); 590 | 591 | break; 592 | case 'oneToMany': 593 | $padmax = 45; 594 | $fkClass = Console::question(\str_pad('Associated member className:', $padmax), \array_keys(self::$allModels), [ 595 | 'ignoreCase' => true 596 | ]); 597 | $otherModel = self::getNewModel($fkClass, false); 598 | $otherModelName = $otherModel->getOriginalModelName(); 599 | 600 | $fkField = Console::question(\str_pad('Foreign key name:', $padmax), null, [ 601 | 'default' => 'id' . \ucfirst($modelName) 602 | ]); 603 | $member = Console::question(\str_pad('Member name:', $padmax), null, [ 604 | 'default' => \lcfirst($otherModelName) . 's' 605 | ]); 606 | $mappedBy = Console::question(\str_pad("MappedBy member name in $otherModelName:", $padmax), null, [ 607 | 'default' => \lcfirst($modelName) 608 | ]); 609 | 610 | $newModel->addOneToMany($member, $mappedBy, $otherModelName); 611 | if (! $otherModel->isLoaded()) { 612 | self::loadModel($otherModel, $otherModelName, $namespace); 613 | } 614 | $otherModel->addManyToOne($mappedBy, $fkField, $modelName); 615 | $newModel->setUpdated(true); 616 | $otherModel->setUpdated(true); 617 | break; 618 | } 619 | } 620 | } 621 | -------------------------------------------------------------------------------- /src/devtools/project-files/public/themes/foundation/css/style.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sourceRoot":"","sources":["../scss/_myVariables.scss","../../../../vendor/zurb/foundation/scss/foundation.scss","../../../../vendor/zurb/foundation/scss/util/_breakpoint.scss","../../../../vendor/zurb/foundation/scss/components/_reveal.scss","../../../../vendor/zurb/foundation/scss/vendor/normalize.scss","../../../../vendor/zurb/foundation/scss/_global.scss","../../../../vendor/zurb/foundation/scss/util/_unit.scss","../../../../vendor/zurb/foundation/scss/util/_mixins.scss","../../../../vendor/zurb/foundation/scss/forms/_text.scss","../../../../vendor/zurb/foundation/scss/forms/_checkbox.scss","../../../../vendor/zurb/foundation/scss/forms/_forms.scss","../../../../vendor/zurb/foundation/scss/forms/_label.scss","../../../../vendor/zurb/foundation/scss/forms/_help-text.scss","../../../../vendor/zurb/foundation/scss/forms/_input-group.scss","../../../../vendor/zurb/foundation/scss/forms/_fieldset.scss","../../../../vendor/zurb/foundation/scss/forms/_select.scss","../../../../vendor/zurb/foundation/scss/forms/_error.scss","../../../../vendor/zurb/foundation/scss/typography/_base.scss","../../../../vendor/zurb/foundation/scss/util/_color.scss","../../../../vendor/zurb/foundation/scss/typography/_helpers.scss","../../../../vendor/zurb/foundation/scss/typography/_alignment.scss","../../../../vendor/zurb/foundation/scss/typography/_print.scss","../../../../vendor/zurb/foundation/scss/xy-grid/_classes.scss","../../../../vendor/zurb/foundation/scss/xy-grid/_gutters.scss","../../../../vendor/zurb/foundation/scss/xy-grid/_grid.scss","../../../../vendor/zurb/foundation/scss/xy-grid/_cell.scss","../../../../vendor/zurb/foundation/scss/xy-grid/_layout.scss","../../../../vendor/zurb/foundation/scss/xy-grid/_collapse.scss","../../../../vendor/zurb/foundation/scss/xy-grid/_position.scss","../../../../vendor/zurb/foundation/scss/xy-grid/_frame.scss","../../../../vendor/zurb/foundation/scss/components/_button.scss","../../../../vendor/zurb/foundation/scss/components/_button-group.scss","../../../../vendor/zurb/foundation/scss/components/_close-button.scss","../../../../vendor/zurb/foundation/scss/components/_label.scss","../../../../vendor/zurb/foundation/scss/components/_progress-bar.scss","../../../../vendor/zurb/foundation/scss/forms/_progress.scss","../../../../vendor/zurb/foundation/scss/components/_slider.scss","../../../../vendor/zurb/foundation/scss/forms/_range.scss","../../../../vendor/zurb/foundation/scss/components/_switch.scss","../../../../vendor/zurb/foundation/scss/components/_table.scss","../../../../vendor/zurb/foundation/scss/components/_badge.scss","../../../../vendor/zurb/foundation/scss/components/_breadcrumbs.scss","../../../../vendor/zurb/foundation/scss/components/_callout.scss","../../../../vendor/zurb/foundation/scss/components/_card.scss","../../../../vendor/zurb/foundation/scss/components/_dropdown.scss","../../../../vendor/zurb/foundation/scss/components/_pagination.scss","../../../../vendor/zurb/foundation/scss/components/_tooltip.scss","../../../../vendor/zurb/foundation/scss/components/_accordion.scss","../../../../vendor/zurb/foundation/scss/components/_media-object.scss","../../../../vendor/zurb/foundation/scss/components/_orbit.scss","../../../../vendor/zurb/foundation/scss/components/_responsive-embed.scss","../../../../vendor/zurb/foundation/scss/components/_tabs.scss","../../../../vendor/zurb/foundation/scss/components/_thumbnail.scss","../../../../vendor/zurb/foundation/scss/components/_menu.scss","../../../../vendor/zurb/foundation/scss/components/_menu-icon.scss","../../../../vendor/zurb/foundation/scss/components/_accordion-menu.scss","../../../../vendor/zurb/foundation/scss/components/_drilldown.scss","../../../../vendor/zurb/foundation/scss/components/_dropdown-menu.scss","../../../../vendor/zurb/foundation/scss/components/_off-canvas.scss","../../../../vendor/zurb/foundation/scss/components/_sticky.scss","../../../../vendor/zurb/foundation/scss/components/_title-bar.scss","../../../../vendor/zurb/foundation/scss/components/_top-bar.scss","../../../../vendor/zurb/foundation/scss/components/_float.scss","../../../../vendor/zurb/foundation/scss/components/_visibility.scss"],"names":[],"mappings":";AAsBA;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAED;EACC;EACA;;;ACrDD;AAAA;AAAA;AAAA;AAAA;AAAA;ACsKM;ECzHJ;IACE;IACA;IACA;;;AC/CF;AAQA;EACE;EACA;;;AAQF;EACE;;;AAMF;EACE;EACA;;;AASF;EACE;EACA;EACA;;;AAMF;EACE;EACA;;;AAQF;EACE;;;AAMF;EACE;EACA;EACA;;;AAKF;AAAA;EAEE;;;AAMF;AAAA;AAAA;EAGE;EACA;;;AAKF;EACE;;;AAMF;AAAA;EAEE;EACA;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAQF;EACE;;;AASF;AAAA;AAAA;AAAA;AAAA;EAKE;EACA;EACA;EACA;;;AAMF;AAAA;EAEE;;;AAMF;AAAA;EAEE;;;AAKF;AAAA;AAAA;AAAA;EAIE;;;AAKF;AAAA;AAAA;AAAA;EAIE;EACA;;;AAKF;AAAA;AAAA;AAAA;EAIE;;;AAKF;EACE;;;AAQF;EACE;EACA;EACA;EACA;EACA;EACA;;;AAKF;EACE;;;AAKF;EACE;;;AAMF;AAAA;EAEE;EACA;;;AAKF;AAAA;EAEE;;;AAMF;EACE;EACA;;;AAKF;EACE;;;AAMF;EACE;EACA;;;AAQF;EACE;;;AAKF;EACE;;;AAQF;EACE;;;AAKF;EACE;;;AC3IF;EACE;;;AAGF;EACE;EACA,WCzIe;;;AD6IjB;AAAA;AAAA;EAGE;;;AAIF;EACE;EACA;EAEA,YA5GI;EA8GJ,aLjKe;EKkKf,aA/EmB;EAgFnB,aA9IgB;EA+IhB,OArHI;EAwHF;EACA;;;AAIJ;EAEE;EACA;EAGA;EACA;EACA;;;AAIF;EACE;EACA;EACA,eL5LY;;;AKgMd;EACE;EACA;EACA,eLnMY;;;AK0MZ;AAAA;AAAA;AAAA;AAAA;AAAA;EAGE;;;AAKJ;EAEE;EACA;EACA;EACA,eLvNY;EKwNZ;EACA;EACA,QAvGmB;;AEsFrB;EACE;;;AFoBF;EACE;;;AAIF;AAAA;AAAA;AAAA;AAAA;EAKE;;;AAIF;EACE;;;AAGF;EACE;;;AGrHF;AAAA;EArCA;EACA;EACA;EACA,QALS;EAMT;EACA,SAtCc;EAwCd,QAhDa;EAiDb,eR/Fc;EQgGd,kBH5CM;EG6CN,YAvCa;EAyCb,aAjFkB;EAkFlB,WA9EgB;EA+EhB,aHjBqB;EGkBrB,aHhFkB;EGiFlB,OHvDM;EG0DJ,YApCe;EAyDf;;AAjBF;AAAA;EACE;EACA,QA9DiB;EA+DjB,kBH7DI;EG8DJ,YApDiB;EAuDf,YA/Ca;;;AA6DjB;EACE;;AAEA;EACE;;;AAOF;AAAA;AAAA;EAEE,kBH5GO;EG6GP,QA/EkB;;;AAoFtB;AAAA;EAEE;EACA,eRzJY;;;AQ6Jd;EACE;;;AAiBF;EACE,OHxIU;;;AI/BZ;AAAA;AAAA;EAGE;;;AAIF;AAAA;EAEE;EACA;EAEA;EACA,cCZW;EDaX;;AAEA;AAAA;EACE;;;AAKJ;AAAA;EAEE;;;AAIF;EACE;;;AEIF;EAjBA;EACA;EAEA,WAdqB;EAerB,aNuDqB;EMtDrB,aARuB;EASvB,ONiBM;;AMHJ;EARF;EACA;;;ACjBA;EAGE,YAFa;EAGb,WAXiB;EAYjB,YARkB;EASlB,OPqBI;;;AQtBN;EACE;EACA;EACA,eHnBW;EGsBT;;AAIA;EACE;;AAKF;EACE;;;AAKN;AAAA;AAAA;AAAA;EACE;EACA;;;AAQF;EAEE;EACA,QA3CkB;EA4ClB,YR1BS;EQ4BT,ORhBI;EQiBJ;EACA;EAGE;EACA;EACA;;AAQA;EACE;;AAGF;EACE;;;AAKN;EAEE;EAGE;EACA;;;AAIJ;EAEE;EACA;EACA;EAGE;EACA;;AAOF;AAAA;AAAA;AAAA;EAOI;EACA;EAKF;EACA;EACA,WL3GY;;;AMgBhB;EACE;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EAxBA,QAPgB;EAQhB,SAZiB;EAajB,QAjBgB;;AAmBhB;EAEE;EACA;EACA,SAXa;;;AC4Df;EA3DA,QAFS;EAGT;EACA,SP6Bc;EO3Bd;EACA,QPkBa;EOjBb,ef7Bc;Ee8Bd,kBVsBM;EUpBN,aPdkB;EOelB,WPXgB;EOYhB,aVkDqB;EUjDrB,aVbkB;EUclB,OVYM;EEsGN;EQ9GE;EACA;EACA;EACA;EAEA;EAIA,YPqBe;;ADkFjB;EQtEA;IRyEI;;;AQtGJ;EACE;EACA,QPLiB;EOMjB,kBVJI;EUKJ,YPKiB;EOFf,YPUa;;AOLjB;EACE,kBV9BS;EU+BT,QPDoB;;AOKtB;EACE;;AAGF;EACE;EACA;;;ACjCF;EACE,cA3BuB;EA4BvB;;AAEA;EACE,OA/BqB;;;AAyDvB;EACE,OAtDqB;;;AA2DzB;EAzBA;EACA;EACA,eNhDa;EMkDb,WA9BsB;EA+BtB,aX2BmB;EW1BnB,OApCkB;;AA0DhB;EACE;;;AC0KJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAmBE;EACA;;;AAIF;EACE,eAzKsB;EA2KtB;EACA,aAhLmB;EAiLnB,gBAzKuB;;;AA6KzB;AAAA;EAEE;EACA;;;AAIF;AAAA;EAEE,aZjNiB;EYkNjB;;;AAIF;EACE,WA5Mc;EA6Md;;;AAIF;AAAA;AAAA;AAAA;AAAA;AAAA;EAME,ajBzTe;EiB0Tf,YAzRgB;EA0RhB,ajB1TiB;EiB2TjB,OAnRW;EAoRX,gBA/NoB;;AAiOpB;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;EACA,OZ1RQ;;;AYmSN;EAII,WADiB;EAajB;EAQA;EAOA;;;AA/BJ;EAII,WADiB;EAajB;EAQA;EAOA;;;AA/BJ;EAII,WADiB;EAajB;EAQA;EAOA;;;AA/BJ;EAII,WADiB;EAajB;EAQA;EAOA;;;AA/BJ;EAII,WADiB;EAajB;EAQA;EAOA;;;AA/BJ;EAII,WADiB;EAajB;EAQA;EAOA;;;AfpMN;EeqKE;IAII,WADiB;;;EAHrB;IAII,WADiB;;;EAHrB;IAII,WADiB;;;EAHrB;IAII,WADiB;;;EAHrB;IAII,WADiB;;;EAHrB;IAII,WADiB;;;AAoC3B;EACE;EACA,OClQgB;EDmQhB,iBA9NqB;EAgOrB;;AAEA;EAEE,OAxOe;;AA8OjB;EACE;;;AAKJ;EACE;EAEA,WZxXW;EYyXX;EACA,QArOQ;EAuOR;EACA;EACA,eA7OQ;EA8OR;;;AAIF;AAAA;AAAA;EAGE,eAzSsB;EA0StB,qBAlOkB;EAmOlB,aA/SmB;;;AAmTrB;EACE;;;AAIF;EACE,aAzOe;EA0Of,iBAlPc;;;AAsPhB;EACE,aA/Oe;;;AAoPf;EACE,aAjPoB;EAkPpB;;;AAKJ;EACE,eApPqB;;AAsPrB;EACE,eA/OwB;EAgPxB,aZnWe;;;AYwWnB;EACE;EACA,SA/OiB;EAgPjB,aA5OgB;;AA8OhB;EACE,aA3ViB;EA4VjB,OZ3ZM;;;AYgaV;EACE;EACA,WAnPa;EAoPb,OZnaQ;;AYqaR;EACE,SA/OgB;;;AAoPpB;EACE,eA7Na;EA8Nb;EACA;;;AAIF;EACE;;;AAIF;EACE,SAzVW;EA2VX,QA/VU;EAgWV,kBZncS;EYqcT,aAncoB;EAocpB,aZtZmB;EYuZnB,OZ3bI;;;AY+bN;EACE;EACA,SA9PgB;EAgQhB,kBZ/cS;EYidT,aA/coB;EAgdpB,OZtcI;EYycF,ejBzfU;;;AmB+Cd;EACE,YAlBmB;EAmBnB,eAfsB;EAiBtB,adiCmB;EchCnB,aAlCmB;EAmCnB,OdTQ;;;AcaV;EACE,WAhDa;EAiDb,aA7Cc;;;AAiDhB;EACE,WA1Ba;EA2Bb;;AAEA;EACE;;;AAMF;EACE;EACA;;;AC9DI;EACE,YARU;;;AAOZ;EACE,YARU;;;AAOZ;EACE,YARU;;;AAOZ;EACE,YARU;;;AlB+JhB;EkB7JI;IACE,YAHU;;;EAEZ;IACE,YAHU;;;EAEZ;IACE,YAHU;;;EAEZ;IACE,YAHU;;;AlB+JhB;EkB7JI;IACE,YAHU;;;EAEZ;IACE,YAHU;;;EAEZ;IACE,YAHU;;;EAEZ;IACE,YAHU;;;ACUpB;EAAkB;;;AAElB;EACE;IAEI;IAGF;IAEA;IACA;;;EAGF;IAAkB;;;EAClB;IAAkB;;;EAElB;IAAuB;;;EACvB;IAAuB;;;EACvB;IAAuB;;;EACvB;IAAoB;;;EACpB;IAAoB;;;EACpB;IAAoB;;;EAGpB;AAAA;IACY;;;EAEV;IAAgB;;;EAIlB;AAAA;AAAA;IAEqB;;;EAGrB;IAAoB;;;EAGpB;AAAA;IAEE;IACA;;;EAIF;IAAQ;;;EAER;AAAA;IACM;;;EAEN;IAAM;;;EAEN;IAAQ;;EAER;AAAA;AAAA;IAGE;IACA;;;EAIF;AAAA;IACK;;;EAGL;IACE;;;AC1EJ;ECoBM;EAAA;ECdN;EACA;EACA;;AtBkJI;EoB1JJ;ICoBM;IAAA;;;ADjBJ;ECiBI;EAAA;ECdN,WFF+B;EEG/B;EACA;;AtBkJI;EoBvJF;ICiBI;IAAA;;;ADbJ;ECsBE;EAAA;ECvBJ,WFE+B;EED/B;EACA;;;AFKA;EESA;EACA;;;AFNA;EGqBE;EACA;EACA;EAsCA,OADM;;AHxDN;EGsBA;;AHlBA;EGqBA;;;AHfA;EGuCA;;AHnCA;EGuCA;;;AHvBE;EACE;;;ApBsGF;EoBvGA;IACE;;;ApBsGF;EoBvGA;IACE;;;AAcJ;EGpBA;;;AHmCE;EGHF,OADM;;;AHIJ;EGHF,OADM;;;AHIJ;EGHF,OADM;;;AHIJ;EGHF,OADM;;;AHIJ;EGHF,OADM;;;AHIJ;EGHF,OADM;;;AHIJ;EGHF,OADM;;;AHIJ;EGHF,OADM;;;AHIJ;EGHF,OADM;;;AHIJ;EGHF,OADM;;;AHIJ;EGHF,OADM;;;AHIJ;EGHF,OADM;;;AvB6EJ;EoB9FA;IGjBF;IA2BA;;;EHJA;IGpBA;;;EH0BE;IGEF;;;EHOE;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;AvB6EJ;EoB9FA;IGjBF;IA2BA;;;EHJA;IGpBA;;;EH0BE;IGEF;;;EHOE;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;EHIJ;IGHF,OADM;;;AHYR;EACE;;;AAIF;EACE;;;AA8BF;ECzGM;EAAA;;ArBsIF;EoB7BJ;ICzGM;IAAA;;;AD6GJ;EG9DA,OADM;EFrCJ;EAAA;;ArB6HA;EoBlBE;IGrEJ,OADM;IFrCJ;IAAA;;;ADwEJ;EG/BE;;AHmCF;EG/BE;;AHuCA;EGnCA,OADM;;AHoCN;EGnCA,OADM;;AHoCN;EGnCA,OADM;;AHoCN;EGnCA,OADM;;AHoCN;EGnCA,OADM;;AHoCN;EGnCA,OADM;;AHoCN;EGnCA,OADM;;AHoCN;EGnCA,OADM;;AHoCN;EGnCA,OADM;;AHoCN;EGnCA,OADM;;AHoCN;EGnCA,OADM;;AHoCN;EGnCA,OADM;;AvB6EJ;EoBrDJ;IG/BE;;EHmCF;IG/BE;;EHuCA;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHwBR;IG/BE;;EHmCF;IG/BE;;EHuCA;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;;AvB6EJ;EoBrDJ;IG/BE;;EHmCF;IG/BE;;EHuCA;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;EHoCN;IGnCA,OADM;;;;AHuFN;EChJI;EAAA;;ArBsIF;EoBUF;IChJI;IAAA;;;ADsJJ;ECtJI;EAAA;;ArBsIF;EoBgBF;ICtJI;IAAA;;;AD2JJ;EC3JI;EAAA;;ArBsIF;EoBqBF;IC3JI;IAAA;;;;AGFN;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AvB6EJ;EwBxIJ;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;AvB6EJ;EwBxIJ;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AC3DR;ED4DE,OADM;;;AvB6EJ;EwBxIJ;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;AvB6EJ;EwBxIJ;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;EC3DR;ID4DE,OADM;;;AHgJJ;EKhNE;EAAA;;AAGF;EAEI;EAAA;;AAsBE;EFsCR,OADM;;AErCE;EFsCR,OADM;;AErCE;EFsCR,OADM;;AErCE;EFsCR,OADM;;AErCE;EFsCR,OADM;;AErCE;EFsCR,OADM;;AErCE;EFsCR,OADM;;AErCE;EFsCR,OADM;;AErCE;EFsCR,OADM;;AErCE;EFsCR,OADM;;AErCE;EFsCR,OADM;;AErCE;EFsCR,OADM;;AvB6EJ;EyBlHM;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;;AvB6EJ;EyBlHM;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;;;AHsJJ;EK/KE;EAAA;;AAGF;EAEI;EAAA;;;AzBiGJ;EoBmEA;IKhNE;IAAA;;EAGF;IAEI;IAAA;;;AzBwIJ;EyB3HM;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;;AvB6EJ;EyBlHM;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;;AvB6EJ;EyBlHM;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;;;AvB6EJ;EoByEA;IK/KE;IAAA;;EAGF;IAEI;IAAA;;;;AzBiGJ;EoBmEA;IKhNE;IAAA;;EAGF;IAEI;IAAA;;;AzBwIJ;EyB3HM;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;;AvB6EJ;EyB3HM;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;EE9CE;IF+CR,OADM;;;AvB6EJ;EyBlHM;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;EErCE;IFsCR,OADM;;;;AvB6EJ;EoByEA;IK/KE;IAAA;;EAGF;IAEI;IAAA;;;;ALwLJ;EMhOF;;;ANoOE;EMpOF;;;ANgOE;EMhOF;;;ANoOE;EMpOF;;;ANgOE;EMhOF;;;ANoOE;EMpOF;;;ANgOE;EMhOF;;;ANoOE;EMpOF;;;ANgOE;EMhOF;;;ANoOE;EMpOF;;;ANgOE;EMhOF;;;ANoOE;EMpOF;;;ANgOE;EMhOF;;;ANoOE;EMpOF;;;ANgOE;EMhOF;;;ANoOE;EMpOF;;;ANgOE;EMhOF;;;ANoOE;EMpOF;;;ANgOE;EMhOF;;;ANoOE;EMpOF;;;ANgOE;EMhOF;;;ANoOE;EMpOF;;;ANgOE;EMhOF;;;ANoOE;EMpOF;;;A1ByIE;EoBuFA;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;A1ByIE;EoBuFA;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ENgOE;IMhOF;;;ENoOE;IMpOF;;;ANsPF;EEjPA;EACA;;AFoPE;EGjNF;EACA;;AHoNE;EGzMA;;AH6MA;EGzMA;;AHuNE;EACE;;ApBxIF;EoBuIA;IACE;;;ApBxIF;EoBuIA;IACE;;;AAaF;EGjQF;;AHgRI;EGhPJ,QADM;;AHiPF;EGhPJ,QADM;;AHiPF;EGhPJ,QADM;;AHiPF;EGhPJ,QADM;;AHiPF;EGhPJ,QADM;;AHiPF;EGhPJ,QADM;;AHiPF;EGhPJ,QADM;;AHiPF;EGhPJ,QADM;;AHiPF;EGhPJ,QADM;;AHiPF;EGhPJ,QADM;;AHiPF;EGhPJ,QADM;;AHiPF;EGhPJ,QADM;;AvB6EJ;EoB+IE;IG9PJ;IA2BA;;EHyOE;IGjQF;;EHuQI;IG3OJ;;EHoPI;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;;AvB6EJ;EoB+IE;IG9PJ;IA2BA;;EHyOE;IGjQF;;EHuQI;IG3OJ;;EHoPI;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;EHiPF;IGhPJ,QADM;;;;AH6PJ;ECtTE;EAAA;;ArBsIF;EoBgLA;ICtTE;IAAA;;;AD2TF;EC3TE;EAAA;;ArBsIF;EoBqLA;IC3TE;IAAA;;;;ADyGN;ECzGM;EAAA;;ArBsIF;EoB7BJ;ICzGM;IAAA;;;AD6GJ;EG9DA,QADM;EFrCJ;EAAA;;ArB6HA;EoBlBE;IGrEJ,QADM;IFrCJ;IAAA;;;ADwEJ;EG/BE;;AHmCF;EG/BE;;AHuCA;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AvB6EJ;EoBrDJ;IG/BE;;EHmCF;IG/BE;;EHuCA;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHwBR;IG/BE;;EHmCF;IG/BE;;EHuCA;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;;AvB6EJ;EoBrDJ;IG/BE;;EHmCF;IG/BE;;EHuCA;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;;;AHgRR;EOzVE;EACA;EACA;EACA;EA2BI;;;AP+TN;EACE;;;AAGF;EOhTE;EACA;EAGF;EACA;;;AP+SA;EOxTE;EACA;EACA;EAMF;EACA;;;APoTA;EO7SA;EACA;EACA;;AAEA;EACE;EACA;;;A3BmFE;EoB2NF;IOjXA;IACA;IACA;IACA;IA2BI;;;EPuVJ;IACE;;;EAGF;IOxUA;IACA;IAGF;IACA;;;EPuUE;IOhUF;IACA;IACA;;EAEA;IACE;IACA;;;EP8TA;IOpVA;IACA;IACA;IAMF;IACA;;;A3BgGI;EoB2NF;IOjXA;IACA;IACA;IACA;IA2BI;;;EPuVJ;IACE;;;EAGF;IOxUA;IACA;IAGF;IACA;;;EPuUE;IOhUF;IACA;IACA;;EAEA;IACE;IACA;;;EP8TA;IOpVA;IACA;IACA;IAMF;IACA;;;APkVI;EACE;EOzYJ;EACA;EACA;EACA;EAyBI;;A3B0HF;EoBwPE;IACE;IO/YN;IACA;IACA;IACA;IAyBI;;;A3B0HF;EoBwPE;IACE;IO/YN;IACA;IACA;IACA;IAyBI;;;;AP0XF;EACE;;ApBjQF;EoBoQE;IACE;;;ApBrQJ;EoBoQE;IACE;;;;AAlSR;ECzGM;EAAA;;ArBsIF;EoB7BJ;ICzGM;IAAA;;;AD6GJ;EG9DA,QADM;EFrCJ;EAAA;;ArB6HA;EoBlBE;IGrEJ,QADM;IFrCJ;IAAA;;;ADwEJ;EG/BE;;AHmCF;EG/BE;;AHuCA;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AHoCN;EGnCA,QADM;;AvB6EJ;EoBrDJ;IG/BE;;EHmCF;IG/BE;;EHuCA;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHwBR;IG/BE;;EHmCF;IG/BE;;EHuCA;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;;AvB6EJ;EoBrDJ;IG/BE;;EHmCF;IG/BE;;EHuCA;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;EHoCN;IGnCA,QADM;;;;AHyVN;EO/YI;;A3BmIF;EoB4QF;IO/YI;;;A3BmIF;EoB4QF;IO/YI;;;;A3BmIF;EoBgRA;IOnZE;;;A3BmIF;EoBgRA;IOnZE;;;ACsON;EAhLA;EACA;EACA,QAzEc;EAmFZ,SAvFa;EA0Ff;EACA,e9BzGc;E8B0Gd,YA1BkB;EA2BlB,aAjGmB;EAkGnB;EACA;EACA;EACA;E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","file":"style.css"} --------------------------------------------------------------------------------