From 851eb1bc57466f7eb43c6c364bf792bbb15f94e3 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Wed, 15 Feb 2023 12:36:45 +0300 Subject: [PATCH 01/15] Create webfiori.bat --- webfiori.bat | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 webfiori.bat diff --git a/webfiori.bat b/webfiori.bat new file mode 100644 index 0000000..dbbb4a6 --- /dev/null +++ b/webfiori.bat @@ -0,0 +1,2 @@ +@echo OFF +php "%~dp0webfiori" %* \ No newline at end of file From df879d20faf246c348806dbd2d71ab44230203de Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Fri, 17 Feb 2023 21:09:20 +0300 Subject: [PATCH 02/15] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index dbd89c0..fa04c7e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ app/storage/* vendor/* app/sto +.idea/* From 07712c11880ed7a02d39fbb633f0d048492083fe Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Sun, 2 Apr 2023 17:23:12 +0300 Subject: [PATCH 03/15] Update index.php --- public/index.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/public/index.php b/public/index.php index d7e3e48..5084264 100644 --- a/public/index.php +++ b/public/index.php @@ -5,7 +5,7 @@ use Exception; use webfiori\framework\router\Router; use webfiori\framework\session\SessionsManager; -use webfiori\framework\WebFioriApp; +use webfiori\framework\App; use webfiori\http\Request; use webfiori\http\Response; /** @@ -46,10 +46,10 @@ private function __construct() { * * Planting application seed into the ground and make your work bloom. */ - WebFioriApp::start(); + App::start(); - if (WebFioriApp::getRunner()->isCLI() === true) { - WebFioriApp::getRunner()->start(); + if (App::getRunner()->isCLI() === true) { + App::getRunner()->start(); } else { //route user request. SessionsManager::start('wf-session'); @@ -58,7 +58,7 @@ private function __construct() { } } /** - * Try to load the class 'WebFioriApp'. + * Try to load the class 'App'. * * @throws Exception */ @@ -66,13 +66,13 @@ private function loadAppClass() { $DS = DIRECTORY_SEPARATOR; $frameworkPath = ROOT_PATH.$DS.'vendor'.$DS.'webfiori'.$DS.'framework'; $corePath = $frameworkPath.$DS.'webfiori'.$DS.'framework'; - $rootClass = $DS.'WebFioriApp.php'; + $rootClass = $DS.'App.php'; if (file_exists($corePath.$rootClass)) { define('WF_CORE_PATH', $corePath); require_once $corePath.$rootClass; } else { - throw new Exception('Unable to locate the class "WebFioriApp".'); + throw new Exception('Unable to locate the class "App".'); } } /** From af70eb8f295fd27b982c6373fa1a44f2407e4549 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Sun, 2 Apr 2023 17:23:34 +0300 Subject: [PATCH 04/15] Update AppConfig.php --- app/config/AppConfig.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/app/config/AppConfig.php b/app/config/AppConfig.php index 7fa6c1e..1ba8c07 100644 --- a/app/config/AppConfig.php +++ b/app/config/AppConfig.php @@ -47,7 +47,7 @@ class AppConfig implements Config { * * @since 1.0 */ - private $appVestion; + private $appVersion; /** * The name of base website UI Theme. * @@ -57,7 +57,7 @@ class AppConfig implements Config { */ private $baseThemeName; /** - * The base URL that is used by all web site pages to fetch resource files. + * The base URL that is used by all website pages to fetch resource files. * * @var string * @@ -73,13 +73,13 @@ class AppConfig implements Config { */ private $configVision; /** - * Password hash of CRON sub-system. + * Password hash of scheduler sub-system. * * @var string * * @since 1.0 */ - private $cronPass; + private $schedulerPass; /** * An associative array that will contain database connections. * @@ -129,7 +129,7 @@ class AppConfig implements Config { */ private $primaryLang; /** - * The character which is used to saperate site name from page title. + * The character which is used to separate site name from page title. * * @var string * @@ -155,7 +155,7 @@ public function __construct() { $this->initSiteInfo(); $this->initDbConnections(); $this->initSmtpConnections(); - $this->cronPass = 'NO_PASSWORD'; + $this->schedulerPass = 'NO_PASSWORD'; } /** * Adds SMTP account. @@ -217,7 +217,7 @@ public function getAdminThemeName() : string { /** * Returns the name of base theme that is used in website pages. * - * Usually, this theme is used for the normally visitors of the web site. + * Usually, this theme is used for the normally visitors of the website. * * @return string The name of base theme that is used in website pages. */ @@ -228,7 +228,7 @@ public function getBaseThemeName() : string { * Returns the base URL that is used to fetch resources. * * The return value of this method is usually used by the tag 'base' - * of web site pages. + * of website pages. * * @return string The base URL. */ @@ -246,12 +246,12 @@ public function getConfigVersion() : string { return $this->configVision; } /** - * Returns sha256 hash of the password which is used to prevent unauthorized access to run the jobs or access CRON web interface. + * Returns sha256 hash of the password which is used to prevent unauthorized access to run the tasks or access scheduler web interface. * * @return string Password hash or the string 'NO_PASSWORD' if there is no password. */ - public function getCRONPassword() : string { - return $this->cronPass; + public function getSchedulerPassword() : string { + return $this->schedulerPass; } /** * Returns database connection information given connection name. @@ -282,7 +282,7 @@ public function getDBConnections() : array { return $this->dbConnections; } /** - * Returns the global title of the web site that will be used as default page title. + * Returns the global title of the website that will be used as default page title. * * @param string $langCode Language code such as 'AR' or 'EN'. * @@ -299,7 +299,7 @@ public function getDefaultTitle(string $langCode) { } } /** - * Returns the global description of the web site that will be used as default page description. + * Returns the global description of the website that will be used as default page description. * * @param string $langCode Language code such as 'AR' or 'EN'. * @@ -376,7 +376,7 @@ public function getTitleSep() : string { * form 'x.x.x.x'. */ public function getVersion() : string { - return $this->appVestion; + return $this->appVersion; } /** * Returns a string that represents application release type. @@ -465,7 +465,7 @@ private function initSmtpConnections() { * @since 1.0 */ private function initVersionInfo() { - $this->appVestion = '1.0'; + $this->appVersion = '1.0'; $this->appVersionType = 'Stable'; $this->appReleaseDate = '2021-01-10'; } From df775bad45dacac08f7ac3630adba29d3d4eee70 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Sun, 2 Apr 2023 17:23:57 +0300 Subject: [PATCH 05/15] Update Env.php --- app/config/Env.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/config/Env.php b/app/config/Env.php index 628aec8..7b8cdbb 100644 --- a/app/config/Env.php +++ b/app/config/Env.php @@ -67,7 +67,7 @@ public static function defineEnvVars() { * The value of this constant is passed to the function 'date_default_timezone_set()'. * This one is used to fix some date and time related issues when the * application is deployed in multiple servers. - * See http://php.net/manual/en/timezones.php for supported time zones. + * See https://php.net/manual/en/timezones.php for supported time zones. * Change this as needed. * * @var string @@ -103,20 +103,20 @@ public static function defineEnvVars() { */ define('LOAD_COMPOSER_PACKAGES', true); } - if (!defined('CRON_THROUGH_HTTP')){ + if (!defined('SCHEDULER_THROUGH_HTTP')){ /** - * A constant which is used to enable or disable HTTP access to cron. + * A constant which is used to enable or disable HTTP access to background tasks control panel. * * If the constant value is set to true, the framework will add routes to the - * components which is used to allow access to cron control panel. The control - * panel is used to execute jobs and check execution status. Default value is false. + * components which is used to allow access to tasks control panel. The control + * panel is used to execute tasks and check execution status. Default value is false. * * @var boolean * * @since 1.0 * */ - define('CRON_THROUGH_HTTP', false); + define('SCHEDULER_THROUGH_HTTP', false); } if (!defined('WF_VERBOSE')){ /** @@ -160,7 +160,7 @@ public static function defineEnvVars() { /** * Host name to use in case the system is executed through CLI. * - * When the application is running throgh CLI, there is no actual + * When the application is running through CLI, there is no actual * host name. For this reason, the host is set to 127.0.0.1 by default. * If this constant is defined, the host will be changed to the value of * the constant. Default value of the constant is 'example.com'. From e52a9b7cf363a40a5b7ce984cc58447699bec01b Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Sun, 2 Apr 2023 17:24:08 +0300 Subject: [PATCH 06/15] Delete InitCron.php --- app/ini/InitCron.php | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 app/ini/InitCron.php diff --git a/app/ini/InitCron.php b/app/ini/InitCron.php deleted file mode 100644 index 59a0963..0000000 --- a/app/ini/InitCron.php +++ /dev/null @@ -1,14 +0,0 @@ - Date: Sun, 2 Apr 2023 17:24:15 +0300 Subject: [PATCH 07/15] Create InitTasks.php --- app/ini/InitTasks.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 app/ini/InitTasks.php diff --git a/app/ini/InitTasks.php b/app/ini/InitTasks.php new file mode 100644 index 0000000..560dc79 --- /dev/null +++ b/app/ini/InitTasks.php @@ -0,0 +1,14 @@ + Date: Thu, 6 Apr 2023 04:21:58 +0300 Subject: [PATCH 08/15] Update scheduler-logic.js --- public/assets/js/cron.js | 283 ---------------------------- public/assets/js/scheduler-logic.js | 208 ++++++++++++++++++++ 2 files changed, 208 insertions(+), 283 deletions(-) delete mode 100644 public/assets/js/cron.js create mode 100644 public/assets/js/scheduler-logic.js diff --git a/public/assets/js/cron.js b/public/assets/js/cron.js deleted file mode 100644 index 972d5ef..0000000 --- a/public/assets/js/cron.js +++ /dev/null @@ -1,283 +0,0 @@ -var app = new Vue({ - el:'#app', - vuetify: new Vuetify(), - data: { - password:'', - search:'', - loading:false, - jobs:[], - expanded:[], - jobs_table_headers:[ - {value:'info', text:''}, - {value:'name', text:'Job Name'}, - {value:'expression', text:'CRON Expression'}, - {value:'time.is_minute', text:'Is Minute'}, - {value:'time.is_hour', text:'Is Hour'}, - {value:'time.is_day_of_week', text:'Is Day of Week'}, - {value:'time.is_day_of_month', text:'Is Day of Month'}, - {value:'time.is_month', text:'Is Month'}, - {value:'actions', text:'Actions'}, - ], - dialog:{ - show:false, - message:'' - }, - output_dialog:{ - show:false, - output:'', - failed:false - } - }, - computed:{ - login_btn_disabled:function() { - var pass = this.password+''; - return pass.trim().length === 0; - } - }, - mounted:function () { - if (data.title === 'Scheduled CRON Tasks') { - this.loadTasks(); - } - }, - methods:{ - forceExec:function (job) { - console.log(job); - var vue = this; - var params = { - 'job-name':job.name - }; - for(var x = 0 ; x < job.args.length ; x++) { - var argVal = job.args[x].value; - if (argVal !== undefined && argVal !== null && argVal.length !== 0) { - params[job.args[x].name] = argVal; - } - } - new AJAXRequest({ - method:'post', - url:data.base+'/cron/apis/force-execution', - params:params, - beforeAjax:function() { - vue.loading = true; - job.executing = true; - }, - afterAjax:function() { - vue.loading = false; - job.executing = false; - - if (this.status === 200 && this.jsonResponse) { - var output = ''; - var info = this.jsonResponse['more-info']; - - if (info === undefined) { - info = this.jsonResponse['more_info']; - } - - if (info === undefined) { - info = this.jsonResponse['moreInfo']; - } - for (var x = 0 ; x < info.log.length ; x++) { - output += info.log[x]+'
'; - } - vue.output_dialog.output = output; - - if (info.failed.indexOf(job.name) !== -1) { - vue.output_dialog.failed = true; - } else { - vue.output_dialog.failed = false; - } - } else { - vue.output_dialog.output = this.response; - vue.output_dialog.failed = true; - } - }, - onSuccess:function() { - if (this.jsonResponse) { - vue.showDialog(this.jsonResponse.message); - } else { - vue.showDialog('Something went wrong. Try again.'); - } - }, - onServerErr:function() { - if (this.jsonResponse) { - if (this.jsonResponse.message) { - vue.showDialog(this.jsonResponse.message); - } else { - vue.showDialog(this.status+' - Server Error.'); - } - } else { - vue.showDialog(this.status+' - Server Error.'); - } - }, - onClientErr:function() { - if (this.jsonResponse) { - if (this.jsonResponse.message) { - vue.showDialog(this.jsonResponse.message); - } else { - vue.showDialog(this.status+' - Client Error.'); - } - } else { - vue.showDialog(this.status+' - Client Error.'); - } - }, - onDisconnected:function() { - vue.showDialog('Check your internet connection and try again.'); - } - }).send(); - }, - checkIfEnterHit:function(e) { - if (e.keyCode === 13) { - this.login(); - } - }, - loadTasks:function() { - var vue = this; - new AJAXRequest({ - method:'get', - url:data.base+'/cron/apis/get-jobs', - beforeAjax:function() { - vue.loading = true; - }, - afterAjax:function() { - vue.loading = false; - }, - onSuccess:function() { - if (this.jsonResponse) { - vue.jobs = this.jsonResponse.jobs; - } else { - vue.showDialog('Something went wrong. Try again.'); - } - }, - onServerErr:function() { - if (this.jsonResponse) { - if (this.jsonResponse.message) { - vue.showDialog(this.jsonResponse.message); - } else { - vue.showDialog(this.status+' - Server Error.'); - } - } else { - vue.showDialog(this.status+' - Server Error.'); - } - }, - onClientErr:function() { - if (this.jsonResponse) { - if (this.jsonResponse.message) { - vue.showDialog(this.jsonResponse.message); - } else { - vue.showDialog(this.status+' - Client Error.'); - } - } else { - vue.showDialog(this.status+' - Client Error.'); - } - }, - onDisconnected:function() { - vue.showDialog('Check your internet connection and try again.'); - } - }).send(); - }, - dialogClosed:function() { - this.dialog.show = false; - }, - showDialog(message) { - this.dialog.message = message; - this.dialog.show = true; - }, - logout:function() { - var vue = this; - new AJAXRequest({ - method:'post', - url:data.base+'/cron/apis/logout', - params:{ - password:vue.password - }, - beforeAjax:function() { - vue.loading = true; - }, - afterAjax:function() { - vue.loading = false; - }, - onSuccess:function() { - if (this.jsonResponse) { - window.location.href = data.base+'/cron/login'; - } else { - vue.showDialog('Something went wrong. Try again.'); - } - }, - onServerErr:function() { - if (this.jsonResponse) { - if (this.jsonResponse.message) { - vue.showDialog(this.jsonResponse.message); - } else { - vue.showDialog(this.status+' - Server Error.'); - } - } else { - vue.showDialog(this.status+' - Server Error.'); - } - }, - onClientErr:function() { - if (this.jsonResponse) { - if (this.jsonResponse.message) { - vue.showDialog(this.jsonResponse.message); - } else { - vue.showDialog(this.status+' - Client Error.'); - } - } else { - vue.showDialog(this.status+' - Client Error.'); - } - }, - onDisconnected:function() { - vue.showDialog('Check your internet connection and try again.'); - } - }).send(); - }, - login:function() { - var vue = this; - new AJAXRequest({ - method:'post', - url:data.base+'/cron/apis/login', - params:{ - password:vue.password - }, - beforeAjax:function() { - vue.loading = true; - }, - afterAjax:function() { - if (this.status !== 200) { - vue.loading = false; - } - }, - onSuccess:function() { - if (this.jsonResponse) { - window.location.href = data.base+'/cron/jobs'; - } else { - vue.showDialog('Something went wrong. Try again.'); - } - }, - onServerErr:function() { - if (this.jsonResponse) { - if (this.jsonResponse.message) { - vue.showDialog(this.jsonResponse.message); - } else { - vue.showDialog(this.status+' - Server Error.'); - } - } else { - vue.showDialog(this.status+' - Server Error.'); - } - }, - onClientErr:function() { - if (this.jsonResponse) { - if (this.jsonResponse.message) { - vue.showDialog(this.jsonResponse.message); - } else { - vue.showDialog(this.status+' - Client Error.'); - } - } else { - vue.showDialog(this.status+' - Client Error.'); - } - }, - onDisconnected:function() { - vue.showDialog('Check your internet connection and try again.'); - } - }).send(); - } - } -}); \ No newline at end of file diff --git a/public/assets/js/scheduler-logic.js b/public/assets/js/scheduler-logic.js new file mode 100644 index 0000000..97137d3 --- /dev/null +++ b/public/assets/js/scheduler-logic.js @@ -0,0 +1,208 @@ +/* global ajax */ +ajax.setOnDisconnected(function () { + this.props.vue.showDialog('Check your internet connection and try again.'); +}); +ajax.setOnSuccess({ + id:'Login', + call:function() { + return this.url === 'scheduler/apis/login'; + }, + callback:function() { + if (this.jsonResponse) { + window.location.href = data.base+'/scheduler/tasks'; + } else { + this.props.vue.showDialog('Something went wrong. Try again.'); + } + } +}); +ajax.setBeforeAjax(function () { + this.props.vue.loading = true; +}); +ajax.setAfterAjax(function () { + this.props.vue.loading = false; +}); +ajax.setOnSuccess({ + id:'Logout', + call:function() { + return this.url === 'scheduler/apis/logout'; + }, + callback:function() { + if (this.jsonResponse) { + window.location.href = 'scheduler/login'; + } else { + vue.showDialog('Something went wrong. Try again.'); + } + } +}); +ajax.setOnSuccess({ + id:'Get Jobs', + call:function() { + return this.url === 'scheduler/apis/get-jobs'; + }, + callback:function() { + if (this.jsonResponse) { + this.props.vue.jobs = this.jsonResponse.jobs; + } else { + this.props.vue.showDialog('Something went wrong. Try again.'); + } + } +}); +ajax.setOnSuccess({ + id:'After Force Execution', + call:function() { + return this.url === 'scheduler/apis/force-execution'; + }, + callback:function() { + var vue = this.props.vue; + vue.loading = false; + vue.active_job.executing = false; + + if (this.status === 200 && this.jsonResponse) { + var output = ''; + var info = this.jsonResponse['more-info']; + + if (info === undefined) { + info = this.jsonResponse['more_info']; + } + + if (info === undefined) { + info = this.jsonResponse['moreInfo']; + } + for (var x = 0 ; x < info.log.length ; x++) { + output += info.log[x]+'
'; + } + vue.output_dialog.output = output; + + if (info.failed.indexOf(vue.active_job.name) !== -1) { + vue.output_dialog.failed = true; + } else { + vue.output_dialog.failed = false; + } + } else { + vue.output_dialog.output = this.response; + vue.output_dialog.failed = true; + } + } +}); +ajax.setOnServerError({ + id:'Server Error', + call:true, + callback:function() { + if (this.jsonResponse) { + if (this.jsonResponse.message) { + this.props.vue.showDialog(this.jsonResponse.message); + } else { + this.props.vue.showDialog(this.status+' - Server Error.'); + } + } else { + this.props.vue.showDialog(this.status+' - Server Error.'); + } + } +}); +ajax.setOnClientError({ + id:'Client Error', + call:true, + callback:function() { + if (this.jsonResponse) { + if (this.jsonResponse.message) { + vue.showDialog(this.jsonResponse.message); + } else { + vue.showDialog(this.status+' - Client Error.'); + } + } else { + vue.showDialog(this.status+' - Client Error.'); + } + } +}); +var app = new Vue({ + el:'#app', + vuetify: new Vuetify(), + data: { + password:'', + search:'', + loading:false, + jobs:[], + expanded:[], + jobs_table_headers:[ + {value:'info', text:''}, + {value:'name', text:'Job Name'}, + {value:'expression', text:'CRON Expression'}, + {value:'time.is_minute', text:'Is Minute'}, + {value:'time.is_hour', text:'Is Hour'}, + {value:'time.is_day_of_week', text:'Is Day of Week'}, + {value:'time.is_day_of_month', text:'Is Day of Month'}, + {value:'time.is_month', text:'Is Month'}, + {value:'actions', text:'Actions'}, + ], + dialog:{ + show:false, + message:'' + }, + output_dialog:{ + show:false, + output:'', + failed:false + } + }, + computed:{ + login_btn_disabled:function() { + var pass = this.password+''; + return pass.trim().length === 0; + } + }, + mounted:function () { + if (data.title === 'Scheduled Tasks') { + this.loadTasks(); + } + }, + methods:{ + forceExec:function (job) { + var params = { + 'job-name':job.name + }; + for(var x = 0 ; x < job.args.length ; x++) { + var argVal = job.args[x].value; + if (argVal !== undefined && argVal !== null && argVal.length !== 0) { + params[job.args[x].name] = argVal; + } + } + ajax.setURL('scheduler/apis/force-execution'); + ajax.setMethod('post'); + ajax.setParams(params); + ajax.send(); + }, + checkIfEnterHit:function(e) { + if (e.keyCode === 13) { + this.login(); + } + }, + loadTasks:function() { + ajax.setURL('scheduler/apis/get-jobs'); + ajax.setMethod('get'); + ajax.send(); + }, + dialogClosed:function() { + this.dialog.show = false; + }, + showDialog(message) { + this.dialog.message = message; + this.dialog.show = true; + }, + logout:function() { + ajax.setURL('scheduler/apis/logout'); + ajax.setMethod('get'); + ajax.send(); + }, + login:function() { + ajax.setURL('scheduler/apis/login'); + ajax.setMethod('post'); + ajax.setParams({ + password:this.password + }); + ajax.send(); + } + } +}); +ajax.bind({ + vue:app +}); \ No newline at end of file From f89f69c08c8ff92e7f99784f37b59462767edb24 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Thu, 6 Apr 2023 09:57:21 +0300 Subject: [PATCH 09/15] Update scheduler-logic.js --- public/assets/js/scheduler-logic.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/assets/js/scheduler-logic.js b/public/assets/js/scheduler-logic.js index 97137d3..7eee9ce 100644 --- a/public/assets/js/scheduler-logic.js +++ b/public/assets/js/scheduler-logic.js @@ -121,9 +121,9 @@ var app = new Vue({ password:'', search:'', loading:false, - jobs:[], + tasks:[], expanded:[], - jobs_table_headers:[ + tasks_table_headers:[ {value:'info', text:''}, {value:'name', text:'Job Name'}, {value:'expression', text:'CRON Expression'}, From 8e26493b172d2b3cfea035425905960371b46899 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Sat, 8 Apr 2023 10:33:55 +0300 Subject: [PATCH 10/15] Update scheduler-logic.js --- public/assets/js/scheduler-logic.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/public/assets/js/scheduler-logic.js b/public/assets/js/scheduler-logic.js index 7eee9ce..b69a910 100644 --- a/public/assets/js/scheduler-logic.js +++ b/public/assets/js/scheduler-logic.js @@ -105,12 +105,12 @@ ajax.setOnClientError({ callback:function() { if (this.jsonResponse) { if (this.jsonResponse.message) { - vue.showDialog(this.jsonResponse.message); + this.props.vue.showDialog(this.jsonResponse.message); } else { - vue.showDialog(this.status+' - Client Error.'); + this.props.vue.showDialog(this.status+' - Client Error.'); } } else { - vue.showDialog(this.status+' - Client Error.'); + this.props.vue.showDialog(this.status+' - Client Error.'); } } }); @@ -151,6 +151,10 @@ var app = new Vue({ } }, mounted:function () { + ajax.bind({ + vue:this + }); + ajax.setBase(data.base); if (data.title === 'Scheduled Tasks') { this.loadTasks(); } @@ -203,6 +207,3 @@ var app = new Vue({ } } }); -ajax.bind({ - vue:app -}); \ No newline at end of file From d2dd239866f59d7488ebdd49fd57ab7deb7d4443 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Sat, 29 Apr 2023 04:40:26 +0300 Subject: [PATCH 11/15] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9c6e536..6455c25 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ ], "require": { "php": ">=7.0", - "webfiori/framework":"v3.0.0-RC3" + "webfiori/framework":"v3.0.0-RC4" }, "keywords": [ "framework", From b5acfc95fc6dcf1ff0e60dda83b216b0d581eca0 Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Sat, 29 Apr 2023 04:40:30 +0300 Subject: [PATCH 12/15] Delete scheduler-logic.js --- public/assets/js/scheduler-logic.js | 209 ---------------------------- 1 file changed, 209 deletions(-) delete mode 100644 public/assets/js/scheduler-logic.js diff --git a/public/assets/js/scheduler-logic.js b/public/assets/js/scheduler-logic.js deleted file mode 100644 index b69a910..0000000 --- a/public/assets/js/scheduler-logic.js +++ /dev/null @@ -1,209 +0,0 @@ -/* global ajax */ -ajax.setOnDisconnected(function () { - this.props.vue.showDialog('Check your internet connection and try again.'); -}); -ajax.setOnSuccess({ - id:'Login', - call:function() { - return this.url === 'scheduler/apis/login'; - }, - callback:function() { - if (this.jsonResponse) { - window.location.href = data.base+'/scheduler/tasks'; - } else { - this.props.vue.showDialog('Something went wrong. Try again.'); - } - } -}); -ajax.setBeforeAjax(function () { - this.props.vue.loading = true; -}); -ajax.setAfterAjax(function () { - this.props.vue.loading = false; -}); -ajax.setOnSuccess({ - id:'Logout', - call:function() { - return this.url === 'scheduler/apis/logout'; - }, - callback:function() { - if (this.jsonResponse) { - window.location.href = 'scheduler/login'; - } else { - vue.showDialog('Something went wrong. Try again.'); - } - } -}); -ajax.setOnSuccess({ - id:'Get Jobs', - call:function() { - return this.url === 'scheduler/apis/get-jobs'; - }, - callback:function() { - if (this.jsonResponse) { - this.props.vue.jobs = this.jsonResponse.jobs; - } else { - this.props.vue.showDialog('Something went wrong. Try again.'); - } - } -}); -ajax.setOnSuccess({ - id:'After Force Execution', - call:function() { - return this.url === 'scheduler/apis/force-execution'; - }, - callback:function() { - var vue = this.props.vue; - vue.loading = false; - vue.active_job.executing = false; - - if (this.status === 200 && this.jsonResponse) { - var output = ''; - var info = this.jsonResponse['more-info']; - - if (info === undefined) { - info = this.jsonResponse['more_info']; - } - - if (info === undefined) { - info = this.jsonResponse['moreInfo']; - } - for (var x = 0 ; x < info.log.length ; x++) { - output += info.log[x]+'
'; - } - vue.output_dialog.output = output; - - if (info.failed.indexOf(vue.active_job.name) !== -1) { - vue.output_dialog.failed = true; - } else { - vue.output_dialog.failed = false; - } - } else { - vue.output_dialog.output = this.response; - vue.output_dialog.failed = true; - } - } -}); -ajax.setOnServerError({ - id:'Server Error', - call:true, - callback:function() { - if (this.jsonResponse) { - if (this.jsonResponse.message) { - this.props.vue.showDialog(this.jsonResponse.message); - } else { - this.props.vue.showDialog(this.status+' - Server Error.'); - } - } else { - this.props.vue.showDialog(this.status+' - Server Error.'); - } - } -}); -ajax.setOnClientError({ - id:'Client Error', - call:true, - callback:function() { - if (this.jsonResponse) { - if (this.jsonResponse.message) { - this.props.vue.showDialog(this.jsonResponse.message); - } else { - this.props.vue.showDialog(this.status+' - Client Error.'); - } - } else { - this.props.vue.showDialog(this.status+' - Client Error.'); - } - } -}); -var app = new Vue({ - el:'#app', - vuetify: new Vuetify(), - data: { - password:'', - search:'', - loading:false, - tasks:[], - expanded:[], - tasks_table_headers:[ - {value:'info', text:''}, - {value:'name', text:'Job Name'}, - {value:'expression', text:'CRON Expression'}, - {value:'time.is_minute', text:'Is Minute'}, - {value:'time.is_hour', text:'Is Hour'}, - {value:'time.is_day_of_week', text:'Is Day of Week'}, - {value:'time.is_day_of_month', text:'Is Day of Month'}, - {value:'time.is_month', text:'Is Month'}, - {value:'actions', text:'Actions'}, - ], - dialog:{ - show:false, - message:'' - }, - output_dialog:{ - show:false, - output:'', - failed:false - } - }, - computed:{ - login_btn_disabled:function() { - var pass = this.password+''; - return pass.trim().length === 0; - } - }, - mounted:function () { - ajax.bind({ - vue:this - }); - ajax.setBase(data.base); - if (data.title === 'Scheduled Tasks') { - this.loadTasks(); - } - }, - methods:{ - forceExec:function (job) { - var params = { - 'job-name':job.name - }; - for(var x = 0 ; x < job.args.length ; x++) { - var argVal = job.args[x].value; - if (argVal !== undefined && argVal !== null && argVal.length !== 0) { - params[job.args[x].name] = argVal; - } - } - ajax.setURL('scheduler/apis/force-execution'); - ajax.setMethod('post'); - ajax.setParams(params); - ajax.send(); - }, - checkIfEnterHit:function(e) { - if (e.keyCode === 13) { - this.login(); - } - }, - loadTasks:function() { - ajax.setURL('scheduler/apis/get-jobs'); - ajax.setMethod('get'); - ajax.send(); - }, - dialogClosed:function() { - this.dialog.show = false; - }, - showDialog(message) { - this.dialog.message = message; - this.dialog.show = true; - }, - logout:function() { - ajax.setURL('scheduler/apis/logout'); - ajax.setMethod('get'); - ajax.send(); - }, - login:function() { - ajax.setURL('scheduler/apis/login'); - ajax.setMethod('post'); - ajax.setParams({ - password:this.password - }); - ajax.send(); - } - } -}); From ab948959bd9023f593a57762b10fcb2f187b901b Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Sat, 29 Apr 2023 04:40:34 +0300 Subject: [PATCH 13/15] Delete server-err.js --- public/assets/js/server-err.js | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 public/assets/js/server-err.js diff --git a/public/assets/js/server-err.js b/public/assets/js/server-err.js deleted file mode 100644 index 74c9f61..0000000 --- a/public/assets/js/server-err.js +++ /dev/null @@ -1,18 +0,0 @@ -const app = new Vue({ - el: '#app', - vuetify: new Vuetify({ - - }), - data:{ - - }, - methods:{ - - }, - mounted:function () { - - }, - computed:{ - - } -}); \ No newline at end of file From 0d49684abaeeb3e19d2f4b44e1cc75d137e496ac Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Sat, 29 Apr 2023 04:42:18 +0300 Subject: [PATCH 14/15] Update composer.lock --- composer.lock | 154 ++++++++++++++++++++++++++------------------------ 1 file changed, 80 insertions(+), 74 deletions(-) diff --git a/composer.lock b/composer.lock index 50a9156..447b704 100644 --- a/composer.lock +++ b/composer.lock @@ -4,24 +4,24 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "309ff2d20af5766b2a8b2fb8af84755c", + "content-hash": "bfa31780e0dde9f14b096c5cd6ab8c9e", "packages": [ { "name": "webfiori/cli", - "version": "v1.0.10", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/WebFiori/cli.git", - "reference": "32ff3029ed0046f16377ef60207441b118b53db0" + "reference": "369284d230c8e1e3f5f11aa7561b3b6497ca9b08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WebFiori/cli/zipball/32ff3029ed0046f16377ef60207441b118b53db0", - "reference": "32ff3029ed0046f16377ef60207441b118b53db0", + "url": "https://api.github.com/repos/WebFiori/cli/zipball/369284d230c8e1e3f5f11aa7561b3b6497ca9b08", + "reference": "369284d230c8e1e3f5f11aa7561b3b6497ca9b08", "shasum": "" }, "require": { - "webfiori/file": "1.2.*" + "webfiori/file": "1.3.*" }, "type": "library", "autoload": { @@ -39,7 +39,7 @@ "email": "ibrahim@webfiori.com" } ], - "description": "Command line component of WebFiori framework", + "description": "Class library to simplify the process of creating command line based applications using PHP.", "keywords": [ "cli", "command line", @@ -48,7 +48,7 @@ ], "support": { "issues": "https://github.com/WebFiori/cli/issues", - "source": "https://github.com/WebFiori/cli/tree/v1.0.10" + "source": "https://github.com/WebFiori/cli/tree/v1.1.1" }, "funding": [ { @@ -64,20 +64,20 @@ "type": "ko_fi" } ], - "time": "2023-02-01T20:51:35+00:00" + "time": "2023-03-20T03:55:26+00:00" }, { "name": "webfiori/collections", - "version": "v1.1.1", + "version": "v1.1.3", "source": { "type": "git", "url": "https://github.com/WebFiori/collections.git", - "reference": "8ae72a75ea5ffa7def00df8dc256f69882aa2e5f" + "reference": "f2ba3f613ace3557f98a9904b50ef736e1b403f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WebFiori/collections/zipball/8ae72a75ea5ffa7def00df8dc256f69882aa2e5f", - "reference": "8ae72a75ea5ffa7def00df8dc256f69882aa2e5f", + "url": "https://api.github.com/repos/WebFiori/collections/zipball/f2ba3f613ace3557f98a9904b50ef736e1b403f4", + "reference": "f2ba3f613ace3557f98a9904b50ef736e1b403f4", "shasum": "" }, "require": { @@ -106,7 +106,7 @@ ], "support": { "issues": "https://github.com/WebFiori/collections/issues", - "source": "https://github.com/WebFiori/collections/tree/v1.1.1" + "source": "https://github.com/WebFiori/collections/tree/v1.1.3" }, "funding": [ { @@ -122,20 +122,20 @@ "type": "ko_fi" } ], - "time": "2022-07-16T18:22:14+00:00" + "time": "2023-02-14T23:21:31+00:00" }, { "name": "webfiori/database", - "version": "v0.5.4", + "version": "v0.7.1", "source": { "type": "git", "url": "https://github.com/WebFiori/database.git", - "reference": "a19c11701834c981d5ebe690729b5e1a91944086" + "reference": "dabb641cf5f2a6c929d9e955d68b9addd6b76df0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WebFiori/database/zipball/a19c11701834c981d5ebe690729b5e1a91944086", - "reference": "a19c11701834c981d5ebe690729b5e1a91944086", + "url": "https://api.github.com/repos/WebFiori/database/zipball/dabb641cf5f2a6c929d9e955d68b9addd6b76df0", + "reference": "dabb641cf5f2a6c929d9e955d68b9addd6b76df0", "shasum": "" }, "require": { @@ -161,7 +161,7 @@ ], "support": { "issues": "https://github.com/WebFiori/database/issues", - "source": "https://github.com/WebFiori/database/tree/v0.5.4" + "source": "https://github.com/WebFiori/database/tree/v0.7.1" }, "funding": [ { @@ -177,20 +177,20 @@ "type": "ko_fi" } ], - "time": "2023-01-03T21:44:54+00:00" + "time": "2023-04-03T20:41:19+00:00" }, { "name": "webfiori/err", - "version": "v1.0.5", + "version": "v1.0.6", "source": { "type": "git", "url": "https://github.com/WebFiori/err.git", - "reference": "44102a09fba3f7196551e3bde8aa3493696114b2" + "reference": "0d4a6faaf28d7165e68998de1d333fecc31fd548" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WebFiori/err/zipball/44102a09fba3f7196551e3bde8aa3493696114b2", - "reference": "44102a09fba3f7196551e3bde8aa3493696114b2", + "url": "https://api.github.com/repos/WebFiori/err/zipball/0d4a6faaf28d7165e68998de1d333fecc31fd548", + "reference": "0d4a6faaf28d7165e68998de1d333fecc31fd548", "shasum": "" }, "require": { @@ -217,7 +217,7 @@ ], "support": { "issues": "https://github.com/WebFiori/err/issues", - "source": "https://github.com/WebFiori/err/tree/v1.0.5" + "source": "https://github.com/WebFiori/err/tree/v1.0.6" }, "funding": [ { @@ -233,25 +233,25 @@ "type": "ko_fi" } ], - "time": "2022-10-18T15:19:46+00:00" + "time": "2023-03-08T22:36:33+00:00" }, { "name": "webfiori/file", - "version": "v1.2.2", + "version": "v1.3.2", "source": { "type": "git", "url": "https://github.com/WebFiori/file.git", - "reference": "020cdcae90f7a4f25fca9fe686cca744187317eb" + "reference": "28636c55c07f09c57c72a9989ac728fed4920211" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WebFiori/file/zipball/020cdcae90f7a4f25fca9fe686cca744187317eb", - "reference": "020cdcae90f7a4f25fca9fe686cca744187317eb", + "url": "https://api.github.com/repos/WebFiori/file/zipball/28636c55c07f09c57c72a9989ac728fed4920211", + "reference": "28636c55c07f09c57c72a9989ac728fed4920211", "shasum": "" }, "require": { "php": ">=7.0", - "webfiori/jsonx": "3.1.x" + "webfiori/jsonx": "3.2.x" }, "require-dev": { "webfiori/http": "*" @@ -282,7 +282,7 @@ ], "support": { "issues": "https://github.com/WebFiori/file/issues", - "source": "https://github.com/WebFiori/file/tree/v1.2.2" + "source": "https://github.com/WebFiori/file/tree/v1.3.2" }, "funding": [ { @@ -298,33 +298,37 @@ "type": "ko_fi" } ], - "time": "2022-11-07T15:25:44+00:00" + "time": "2023-04-29T00:10:31+00:00" }, { "name": "webfiori/framework", - "version": "v3.0.0-RC3", + "version": "v3.0.0-RC4", "source": { "type": "git", "url": "https://github.com/WebFiori/framework.git", - "reference": "3b4a3b0c01cbd95bd0da08cf150a802aea6ddccc" + "reference": "4c8876099258cad5dd38d46650c775803bdb03cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WebFiori/framework/zipball/3b4a3b0c01cbd95bd0da08cf150a802aea6ddccc", - "reference": "3b4a3b0c01cbd95bd0da08cf150a802aea6ddccc", + "url": "https://api.github.com/repos/WebFiori/framework/zipball/4c8876099258cad5dd38d46650c775803bdb03cd", + "reference": "4c8876099258cad5dd38d46650c775803bdb03cd", "shasum": "" }, "require": { + "ext-fileinfo": "*", + "ext-json": "*", + "ext-mbstring": "*", + "ext-openssl": "*", "php": ">=7.0", - "webfiori/cli": "v1.0.10", - "webfiori/collections": "v1.1.1", - "webfiori/database": "v0.5.4", - "webfiori/err": "v1.0.5", - "webfiori/file": "v1.2.2", - "webfiori/http": "v3.2.20 ", - "webfiori/jsonx": "v3.1.5", - "webfiori/mailer": "v1.0.2", - "webfiori/ui": "v2.4.0" + "webfiori/cli": "v1.1.1", + "webfiori/collections": "v1.1.3", + "webfiori/database": "v0.7.1", + "webfiori/err": "v1.0.6", + "webfiori/file": "v1.3.2", + "webfiori/http": "v3.3.2 ", + "webfiori/jsonx": "v3.2.1", + "webfiori/mailer": "v1.0.4", + "webfiori/ui": "v2.5.2" }, "require-dev": { "phpunit/phpunit": "*" @@ -368,25 +372,27 @@ "type": "ko_fi" } ], - "time": "2023-02-01T22:41:14+00:00" + "time": "2023-04-29T01:37:45+00:00" }, { "name": "webfiori/http", - "version": "v3.2.20", + "version": "v3.3.2", "source": { "type": "git", "url": "https://github.com/WebFiori/http.git", - "reference": "9e9abaf7cb3e2b6f92b01544fb128d6275c7b329" + "reference": "3529746cda9669eede378439b4fec1bd8be16460" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WebFiori/http/zipball/9e9abaf7cb3e2b6f92b01544fb128d6275c7b329", - "reference": "9e9abaf7cb3e2b6f92b01544fb128d6275c7b329", + "url": "https://api.github.com/repos/WebFiori/http/zipball/3529746cda9669eede378439b4fec1bd8be16460", + "reference": "3529746cda9669eede378439b4fec1bd8be16460", "shasum": "" }, "require": { + "ext-json": "*", + "ext-mbstring": "*", "php": ">=7.0", - "webfiori/jsonx": "3.1.x" + "webfiori/jsonx": "3.2.x" }, "type": "library", "autoload": { @@ -411,7 +417,7 @@ ], "support": { "issues": "https://github.com/WebFiori/http/issues", - "source": "https://github.com/WebFiori/http/tree/v3.2.20" + "source": "https://github.com/WebFiori/http/tree/v3.3.2" }, "funding": [ { @@ -419,20 +425,20 @@ "type": "custom" } ], - "time": "2023-01-31T22:18:40+00:00" + "time": "2023-03-20T23:39:09+00:00" }, { "name": "webfiori/jsonx", - "version": "v3.1.5", + "version": "v3.2.1", "source": { "type": "git", "url": "https://github.com/WebFiori/json.git", - "reference": "b53e318c63f53cd93a515e6291b1cd0608a70e5f" + "reference": "36f6759c4c998080fb34d92d87ec66e29b840caf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WebFiori/json/zipball/b53e318c63f53cd93a515e6291b1cd0608a70e5f", - "reference": "b53e318c63f53cd93a515e6291b1cd0608a70e5f", + "url": "https://api.github.com/repos/WebFiori/json/zipball/36f6759c4c998080fb34d92d87ec66e29b840caf", + "reference": "36f6759c4c998080fb34d92d87ec66e29b840caf", "shasum": "" }, "require": { @@ -456,7 +462,7 @@ ], "support": { "issues": "https://github.com/WebFiori/json/issues", - "source": "https://github.com/WebFiori/json/tree/v3.1.5" + "source": "https://github.com/WebFiori/json/tree/v3.2.1" }, "funding": [ { @@ -464,20 +470,20 @@ "type": "custom" } ], - "time": "2022-10-25T14:15:17+00:00" + "time": "2023-02-28T18:08:07+00:00" }, { "name": "webfiori/mailer", - "version": "v1.0.2", + "version": "v1.0.4", "source": { "type": "git", "url": "https://github.com/WebFiori/mail.git", - "reference": "dfe30da8fd79b61b1d738f84c2a526064ed3578f" + "reference": "027a231a532e53a69148b7fa0a3b014209dd9074" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WebFiori/mail/zipball/dfe30da8fd79b61b1d738f84c2a526064ed3578f", - "reference": "dfe30da8fd79b61b1d738f84c2a526064ed3578f", + "url": "https://api.github.com/repos/WebFiori/mail/zipball/027a231a532e53a69148b7fa0a3b014209dd9074", + "reference": "027a231a532e53a69148b7fa0a3b014209dd9074", "shasum": "" }, "require": { @@ -511,7 +517,7 @@ ], "support": { "issues": "https://github.com/WebFiori/mail/issues", - "source": "https://github.com/WebFiori/mail/tree/v1.0.2" + "source": "https://github.com/WebFiori/mail/tree/v1.0.4" }, "funding": [ { @@ -527,20 +533,20 @@ "type": "ko_fi" } ], - "time": "2022-07-17T11:26:46+00:00" + "time": "2023-03-21T04:40:03+00:00" }, { "name": "webfiori/ui", - "version": "v2.4.0", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/WebFiori/ui.git", - "reference": "229131fbb8f232af8d993bf76e0a0df72c335e64" + "reference": "3622328e255ff33d5dda637ee68298bf86eea345" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WebFiori/ui/zipball/229131fbb8f232af8d993bf76e0a0df72c335e64", - "reference": "229131fbb8f232af8d993bf76e0a0df72c335e64", + "url": "https://api.github.com/repos/WebFiori/ui/zipball/3622328e255ff33d5dda637ee68298bf86eea345", + "reference": "3622328e255ff33d5dda637ee68298bf86eea345", "shasum": "" }, "require": { @@ -570,7 +576,7 @@ ], "support": { "issues": "https://github.com/WebFiori/ui/issues", - "source": "https://github.com/WebFiori/ui/tree/v2.4.0" + "source": "https://github.com/WebFiori/ui/tree/v2.5.2" }, "funding": [ { @@ -578,7 +584,7 @@ "type": "custom" } ], - "time": "2022-12-13T22:38:27+00:00" + "time": "2023-04-02T04:29:41+00:00" } ], "packages-dev": [], @@ -593,5 +599,5 @@ "php": ">=7.0" }, "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.3.0" } From e263738c87c1f296316afc35fd640bb41cc92a0f Mon Sep 17 00:00:00 2001 From: Ibrahim BinAlshikh Date: Sat, 29 Apr 2023 04:44:21 +0300 Subject: [PATCH 15/15] Update README.md --- README.md | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index b448e4b..e1bdf02 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

- + @@ -22,7 +22,7 @@ ## What is WebFiori Framework? -WebFiori Framework is a mini web development framework which is built using PHP language. The framework is fully object oriented (OOP). It uses semi-MVC model but it does not force it. The framework comes with many features which can help in making your website or web application up and running in no time. +WebFiori Framework is a mini web development framework which is built using PHP language. The framework is fully object-oriented (OOP). It uses semi-MVC model, but it does not force it. The framework comes with many features which can help in making your website or web application up and running in no time. ## Supported PHP Versions | Build Status | @@ -39,7 +39,7 @@ WebFiori Framework is a mini web development framework which is built using PHP ## Key Features -* Provide minimum utilities to setup a small web application. +* Provide minimum utilities to setup a small/medium web application. * Theming and the ability to create multiple UIs for the same web app using any CSS or JavaScript framework. * Building and manipulating the DOM of a web page inside PHP. * Basic template engine. @@ -51,11 +51,10 @@ WebFiori Framework is a mini web development framework which is built using PHP * Access management by assigning system user a set of privileges. * Customized sessions manager. * Support for creating and sending nice-looking HTML emails. -* Autoloading of user defined classes (loading composer packages also supported). +* Autoload of user defined classes (loading composer packages also supported). * Ability to create background tasks and let them run in specific time using CRON. * Well-defined file upload and file handling sub-system. -* Basic support for running the framework throgh CLI. -* Ability to implement custom CLI commands. +* Basic support for creating CLI Applications. ## Standard Libraries @@ -63,15 +62,15 @@ Following table shows build status of the standard libraries that the framework | Library | Build | Latest | |----|----|----| -| [HTTP](https://github.com/WebFiori/http) | | | -| [File](https://github.com/WebFiori/file) | | | -| [Json](https://github.com/WebFiori/json) | | | -| [UI](https://github.com/WebFiori/ui) | | | -| [Collections](https://github.com/WebFiori/collections) | | | -| [Database](https://github.com/WebFiori/database) | | | -| [CLI](https://github.com/WebFiori/cli) | | | -| [Mailer](https://github.com/WebFiori/mail) | | | -| [Errors and Exceptions Handler](https://github.com/WebFiori/err) | | | +| [HTTP](https://github.com/WebFiori/http) | | | +| [File](https://github.com/WebFiori/file) | | | +| [Json](https://github.com/WebFiori/json) | | | +| [UI](https://github.com/WebFiori/ui) | | | +| [Collections](https://github.com/WebFiori/collections) | | | +| [Database](https://github.com/WebFiori/database) | | | +| [CLI](https://github.com/WebFiori/cli) | | | +| [Mailer](https://github.com/WebFiori/mail) | | | +| [Errors and Exceptions Handler](https://github.com/WebFiori/err) | | | ## Problems Solved @@ -79,31 +78,31 @@ One of the things that any developer cares about any software project is the pro * The ability to create a customized links to web pages as needed by using [Routing](https://webfiori.com/learn/routing). * No need for touching HTML to play with the DOM by using [UI Library](https://webfiori.com/learn/ui-package) of the framework. * Run PHP code as a CRON task through HTTP protocol or through terminal as a [Background Job](https://webfiori.com/learn/background-tasks). -* Changing whole user interface by changing one line of code throgh [Theming](https://webfiori.com/learn/themes). +* Changing whole user interface by changing one line of code through [Theming](https://webfiori.com/learn/themes). * Ability to move the source code of the web application without having to do a lot of re-configuration. * [Sending HTML email](https://webfiori.com/learn/sending-emails) messages with attachments without having to write a lot of code. * Solved the issues which are found in default PHP session management implementation by implementing a custom [Sessions Management System](https://webfiori.com/learn/sessions-management). -* Reduce the number of dependencies at which a developer need to setup a web application. +* Reduce the number of dependencies at which a developer need to set up a web application. ## Getting Started -To learn the basics of how to use the framework, please head on to https://webfiori.com/learn. You can also read samedocs docs which can be found in [docs repo](https://github.com/usernane/wf-docs). In addition to that, you can read the API docs of the framework at [the official website](https://webfiori.com/docs). +To learn the basics of how to use the framework, please head on to https://webfiori.com/learn. You can also read same docs which can be found in [docs repo](https://github.com/usernane/wf-docs). In addition to that, you can read the API docs of the framework at [the official website](https://webfiori.com/docs). ## Setup ### Local Development Environment -If you plan to test the framework on your local machine, the recomended way is to have AMP stack (Apache, MySQL and PHP). There are many available online. We suggest to use the ones that are offered by Bitnami. You can go to https://bitnami.com/stacks/infrastructure to check the available options. +If you plan to test the framework on your local machine, the recommended way is to have AMP stack (Apache, MySQL and PHP). There are many available online. We suggest to use the ones that are offered by Bitnami. You can go to https://bitnami.com/stacks/infrastructure to check the available options. -After installing AMP stack, you can ethier use composer to install the framework or install it manually by download it throgh https://webfiori.com/download. If you plan to use composer, then you must first download composer from their website: https://getcomposer.org/download/. Once downloaded, place the `.phar` file in the folder `htdocs` or your server root. Once you do that, run the terminal in `htdocs` and run the following command: +After installing AMP stack, you can either use composer to install the framework or install it manually by download it through https://webfiori.com/download. If you plan to use composer, then you must first download composer from their website: https://getcomposer.org/download/. Once downloaded, place the `.phar` file in the folder `htdocs` or your server root. Once you do that, run the terminal in `htdocs` and run the following command: ``` php composer.phar create-project --prefer-dist webfiori/app my-site ``` This command will create new folder with the name `my-site` and install the framework inside it. -For more information about how to setup the framework, [check here](https://webfiori.com/learn/installation). +For more information about how to set up the framework, [check here](https://webfiori.com/learn/installation). ## Contribution @@ -111,10 +110,8 @@ For more information about how to setup the framework, [check here](https://webf For information on how to contribute to the project, [check here](https://webfiori.com/contribute). ## Notes -* This project is started as a hoppy project. -* The main aim of this project is learning. * If you think that there is a better way of doing things or wants new feature, feel free to [drop an issue](https://github.com/WebFiori/framework/issues/new). -* To report security vulnerabilities, please send an email to [ibrahim@webfiori.com](mailto:ibrahim@webfiori.com). +* To report security vulnerabilities, please email [ibrahim@webfiori.com](mailto:ibrahim@webfiori.com). ## License