diff --git a/database_dump/smart-home-server_database.sql b/database_dump/smart-home-server_database.sql new file mode 100644 index 0000000..be9b27a --- /dev/null +++ b/database_dump/smart-home-server_database.sql @@ -0,0 +1,22 @@ +-- phpMyAdmin SQL Dump +-- version 5.2.1 +-- https://www.phpmyadmin.net/ +-- +-- Хост: localhost +-- Время создания: Авг 08 2025 г., 06:09 +-- Версия сервера: 11.8.2-MariaDB +-- Версия PHP: 8.4.10 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- База данных: `smart-home-server` +-- diff --git a/database_dump/smart-home-server_extra.sql b/database_dump/smart-home-server_extra.sql new file mode 100644 index 0000000..87e842d --- /dev/null +++ b/database_dump/smart-home-server_extra.sql @@ -0,0 +1,92 @@ + +-- +-- Индексы сохранённых таблиц +-- + +-- +-- Индексы таблицы `devices` +-- +ALTER TABLE `devices` + ADD PRIMARY KEY (`id`); + +-- +-- Индексы таблицы `groups` +-- +ALTER TABLE `groups` + ADD PRIMARY KEY (`id`); + +-- +-- Индексы таблицы `logs` +-- +ALTER TABLE `logs` + ADD PRIMARY KEY (`id`); + +-- +-- Индексы таблицы `notifications` +-- +ALTER TABLE `notifications` + ADD PRIMARY KEY (`id`); + +-- +-- Индексы таблицы `scripts` +-- +ALTER TABLE `scripts` + ADD PRIMARY KEY (`id`); + +-- +-- Индексы таблицы `users` +-- +ALTER TABLE `users` + ADD PRIMARY KEY (`id`); + +-- +-- Индексы таблицы `user_sessions` +-- +ALTER TABLE `user_sessions` + ADD PRIMARY KEY (`id`); + +-- +-- AUTO_INCREMENT для сохранённых таблиц +-- + +-- +-- AUTO_INCREMENT для таблицы `devices` +-- +ALTER TABLE `devices` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; + +-- +-- AUTO_INCREMENT для таблицы `groups` +-- +ALTER TABLE `groups` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; + +-- +-- AUTO_INCREMENT для таблицы `logs` +-- +ALTER TABLE `logs` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; + +-- +-- AUTO_INCREMENT для таблицы `notifications` +-- +ALTER TABLE `notifications` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; + +-- +-- AUTO_INCREMENT для таблицы `scripts` +-- +ALTER TABLE `scripts` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; + +-- +-- AUTO_INCREMENT для таблицы `users` +-- +ALTER TABLE `users` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; + +-- +-- AUTO_INCREMENT для таблицы `user_sessions` +-- +ALTER TABLE `user_sessions` + MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; diff --git a/database_dump/smart-home-server_table_devices.sql b/database_dump/smart-home-server_table_devices.sql new file mode 100644 index 0000000..6fe9f6d --- /dev/null +++ b/database_dump/smart-home-server_table_devices.sql @@ -0,0 +1,23 @@ + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `devices` +-- + +CREATE TABLE `devices` ( + `id` int(11) NOT NULL, + `alias` varchar(100) NOT NULL, + `name` varchar(100) NOT NULL, + `device_type` varchar(50) NOT NULL, + `device_name` varchar(100) NOT NULL, + `device_ip` varchar(50) NOT NULL, + `device_mac` varchar(100) NOT NULL, + `device_id` varchar(100) NOT NULL, + `firmware_version` varchar(10) NOT NULL, + `connection_state` varchar(50) NOT NULL COMMENT 'active | lost', + `description` text NOT NULL, + `lact_contact` timestamp NOT NULL, + `update_at` timestamp NOT NULL DEFAULT current_timestamp(), + `create_at` timestamp NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/database_dump/smart-home-server_table_groups.sql b/database_dump/smart-home-server_table_groups.sql new file mode 100644 index 0000000..e63cd81 --- /dev/null +++ b/database_dump/smart-home-server_table_groups.sql @@ -0,0 +1,16 @@ + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `groups` +-- + +CREATE TABLE `groups` ( + `id` int(11) NOT NULL, + `alias` varchar(100) NOT NULL, + `name` varchar(100) NOT NULL, + `description` text NOT NULL, + `permissions` text NOT NULL DEFAULT '[]' COMMENT 'JSON struct. Array of permissions', + `update_at` timestamp NOT NULL DEFAULT current_timestamp(), + `create_at` timestamp NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/database_dump/smart-home-server_table_logs.sql b/database_dump/smart-home-server_table_logs.sql new file mode 100644 index 0000000..8963082 --- /dev/null +++ b/database_dump/smart-home-server_table_logs.sql @@ -0,0 +1,18 @@ + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `logs` +-- + +CREATE TABLE `logs` ( + `id` int(11) NOT NULL, + `type` varchar(50) DEFAULT NULL COMMENT 'user | group | device | script | event | system | [custom_type] - (Для удобного поиска)', + `user_id` int(11) DEFAULT 0, + `group_alias` varchar(100) DEFAULT NULL, + `device_id` int(11) DEFAULT 0, + `script_alias` varchar(100) DEFAULT NULL, + `event_name` varchar(100) DEFAULT NULL, + `content` text NOT NULL, + `create_at` timestamp NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/database_dump/smart-home-server_table_notifications.sql b/database_dump/smart-home-server_table_notifications.sql new file mode 100644 index 0000000..d566f6c --- /dev/null +++ b/database_dump/smart-home-server_table_notifications.sql @@ -0,0 +1,17 @@ + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `notifications` +-- + +CREATE TABLE `notifications` ( + `id` int(11) NOT NULL, + `user_id` int(11) NOT NULL COMMENT 'for user with id...', + `type` varchar(50) NOT NULL COMMENT '"system" | "script" | "aside"', + `icon` varchar(255) NOT NULL COMMENT 'Load from icon pack or url to img', + `title` varchar(255) NOT NULL, + `body` text NOT NULL, + `link` varchar(255) NOT NULL, + `create_at` timestamp NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/database_dump/smart-home-server_table_scripts.sql b/database_dump/smart-home-server_table_scripts.sql new file mode 100644 index 0000000..59665f0 --- /dev/null +++ b/database_dump/smart-home-server_table_scripts.sql @@ -0,0 +1,20 @@ + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `scripts` +-- + +CREATE TABLE `scripts` ( + `id` int(11) NOT NULL, + `alias` varchar(100) NOT NULL, + `path` varchar(255) NOT NULL, + `filename` varchar(100) NOT NULL, + `state` varchar(50) NOT NULL COMMENT 'enabled | disabled', + `name` varchar(100) NOT NULL, + `description` text NOT NULL, + `added_by` int(11) NOT NULL COMMENT 'user_id', + `created_by` varchar(255) NOT NULL COMMENT 'Author of script', + `update_at` timestamp NOT NULL DEFAULT current_timestamp(), + `create_at` timestamp NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/database_dump/smart-home-server_table_user_sessions.sql b/database_dump/smart-home-server_table_user_sessions.sql new file mode 100644 index 0000000..d57eb1b --- /dev/null +++ b/database_dump/smart-home-server_table_user_sessions.sql @@ -0,0 +1,16 @@ + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `user_sessions` +-- + +CREATE TABLE `user_sessions` ( + `id` int(11) NOT NULL, + `user_id` int(11) NOT NULL, + `token` varchar(100) NOT NULL, + `state` varchar(50) NOT NULL DEFAULT 'active' COMMENT 'active | outdated | killed', + `is_eternal` tinyint(1) NOT NULL DEFAULT 0, + `last_activity` timestamp NOT NULL DEFAULT current_timestamp(), + `create_at` timestamp NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/database_dump/smart-home-server_table_users.sql b/database_dump/smart-home-server_table_users.sql new file mode 100644 index 0000000..cf21849 --- /dev/null +++ b/database_dump/smart-home-server_table_users.sql @@ -0,0 +1,19 @@ + +-- -------------------------------------------------------- + +-- +-- Структура таблицы `users` +-- + +CREATE TABLE `users` ( + `id` int(11) NOT NULL, + `group_id` int(11) NOT NULL DEFAULT 0, + `nickname` varchar(100) NOT NULL COMMENT 'like login', + `role` varchar(50) NOT NULL DEFAULT '''user''' COMMENT 'user | admin | superadmin', + `password` varchar(255) NOT NULL COMMENT 'hash', + `first_name` int(11) NOT NULL, + `mid_name` int(11) NOT NULL, + `userpic` int(11) NOT NULL, + `contacts` text NOT NULL DEFAULT '{}' COMMENT 'json object', + `create_at` timestamp NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/server/.gitignore b/server/.gitignore new file mode 100644 index 0000000..a379718 --- /dev/null +++ b/server/.gitignore @@ -0,0 +1,9 @@ + +.phpintel/ +SHServ/Logs/ +node_modules/ +users_files/ +side_scripts/__pycache__ +side_scripts/*/__pycache__ +side_scripts/iziua_data_lendlease/used_urls.json +*.pyc diff --git a/server/.htaccess b/server/.htaccess new file mode 100644 index 0000000..f6caf00 --- /dev/null +++ b/server/.htaccess @@ -0,0 +1,8 @@ +#Options +FollowSymlinks +RewriteEngine On + +RewriteBase / +RewriteCond %{REQUEST_FILENAME} !-f +RewriteCond %{REQUEST_FILENAME} !-d +RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css|json) +RewriteRule ^([^?]*) index.php \ No newline at end of file diff --git a/server/Fury/Drivers/TemplateDriver.php b/server/Fury/Drivers/TemplateDriver.php new file mode 100644 index 0000000..72137a6 --- /dev/null +++ b/server/Fury/Drivers/TemplateDriver.php @@ -0,0 +1,60 @@ + + * @version 0.1 + */ + +namespace Fury\Drivers; + +use \Fury\Modules\Template\DriverInterface; +use \Fury\Kernel\AppContainer; + +class TemplateDriver implements DriverInterface{ + public $events_ins; + + public function __construct(){ + $this -> events_ins = AppContainer::events(); + } + + public function event_create_template_instance($template_instance){ + $this -> events_ins -> module_call( + 'Template.create_template_instance', + compact('template_instance') + ); + } + + public function event_start_making(String $template_name, String $template_file, Array $inside_data, $template_instance){ + $this -> events_ins -> module_call( + 'Template.start_making', + compact( + 'template_instance', + 'template_name', + 'inside_data', + 'template_file' + ) + ); + } + + public function event_ready_template(String $template_name, $template_instance){ + $this -> events_ins -> module_call( + 'Template.ready_template', + compact( + 'template_instance', + 'template_name' + ) + ); + } + + public function event_start_joining(String $child_template_name, Array $inside_data){ + $this -> events_ins -> module_call( + 'Template.start_joining', + compact( + 'child_template_name', + 'inside_data' + ) + ); + } +} \ No newline at end of file diff --git a/server/Fury/Drivers/ThinBuilderDriver.php b/server/Fury/Drivers/ThinBuilderDriver.php new file mode 100644 index 0000000..a2cdaf2 --- /dev/null +++ b/server/Fury/Drivers/ThinBuilderDriver.php @@ -0,0 +1,22 @@ + bootstrap = $bootstrap; + } + + public function event_ready_sql(String $sql){ + events() -> module_call('ThinBuilder.ready_sql', ['sql' => $sql]); + } + + public function event_query(String $sql, $result){ + events() -> module_call('ThinBuilder.query', [ + 'sql' => $sql, + 'result' => $result + ]); + } +} \ No newline at end of file diff --git a/server/Fury/Kernel/AppContainer.php b/server/Fury/Kernel/AppContainer.php new file mode 100644 index 0000000..aa500fa --- /dev/null +++ b/server/Fury/Kernel/AppContainer.php @@ -0,0 +1,106 @@ + + * Date: 31.01.2020 + * @version 0.1 + */ + +class AppContainer{ + /** + * Array with flags + * + * @var Array + */ + protected static $already_set = [ + 'bootstrap' => false, + 'app' => false, + 'events' => false, + 'logging' => false + ]; + + /** + * Container with instances + * + * @var array + */ + protected static $container = []; + + /** + * Magic method for adding instance to container + * @example AppContainer::set_app($app_instance) or AppContainer::set_bootstrap($app_instance) or ... + * + * @method __callStatic + * + */ + public static function __callStatic(String $name, $args){ + try{ + if(strpos($name, 'set_') === false){ + throw new \Exception('Undefined method ' . $name); + } + + list(, $var_name) = explode('set_', $name); + if(!isset(self::$already_set[$var_name])){ + throw new \Exception('Undefined method ' . $name); + } + + if(!self::$already_set[$var_name]){ + self::$already_set[$var_name] = true; + self::$container[$var_name] = $args[0]; + return true; + }else{ + return false; + } + }catch(\Exception $e){ + echo $e -> getMessage(); + } + } + + /** + * Get application instance + * + * @method app + * + * @return mixed + */ + public static function app(){ + return self::$container['app']; + } + + /** + * Get bootstrap instance + * + * @method bootstrap + * + * @return mixed + */ + public static function bootstrap(){ + return self::$container['bootstrap']; + } + + /** + * Get Event instance + * + * @method events + * + * @return Events + */ + public static function events(){ + return self::$container['events']; + } + + /** + * Get Logging instance + * + * @method logging + * + * @return Logging + */ + public static function logging(){ + return self::$container['logging']; + } +} \ No newline at end of file diff --git a/server/Fury/Kernel/BaseApp.php b/server/Fury/Kernel/BaseApp.php new file mode 100644 index 0000000..6fd0dc4 --- /dev/null +++ b/server/Fury/Kernel/BaseApp.php @@ -0,0 +1,9 @@ + + * Date: 05.01.2020 + * Update At: 09.02.2020 + * @version 0.1 + */ + +class Bootstrap{ + /** + * Name of current project folder + * + * @var String + */ + public $project_folder; + + /** + * DB class instance + * + * @var DB + */ + public $db; + + /** + * CallControl instance + * + * @var CallControl + */ + protected $call_control; + + /** + * Init class instance + * + * @var Init + */ + protected $init; + + /** + * Constructor with params + * + * @method __construct + * + * @param String $project_folder Name of current project folder + */ + public function __construct(String $project_folder){ + $this -> project_folder = $project_folder; + AppContainer::set_bootstrap($this); + $this -> init = new Init($this); + $this -> init -> init(); + } + + /** + * Initialization global application config + * + * @method init_config + * + * @return void + */ + public function init_config(){ + // init project config + if(!file_exists("{$this -> project_folder}/config.php")){ + die("Config file not found!"); + } + define("FCONF", include_once("{$this -> project_folder}/config.php")); + } + + /** + * Initialization global application constants + * + * @method init_consts + * + * @return void + */ + public function init_consts(){ + define("APP_NAME", FCONF['app_name']); + define("PROJECT_FOLDER", $this -> project_folder); + } + + /** + * Initialization of default DB connection, but only if exists connect parameters to database + * + * @method init_db + * + * @return void + */ + public function init_db(){ + if(isset(FCONF['db']) and FCONF['default_db_wrap']){ + $this -> db = new DB(FCONF['db']); + } + } + + /** + * Initialization of application started files + * + * @method init_app_file + * + * @return void + */ + public function init_app_file(){ + if(isset(FCONF['app_file'])){ + $path_to_app_file = "{$this -> project_folder}/" . FCONF['app_file']; + if(file_exists($path_to_app_file)){ + include_once($path_to_app_file); + } + } + } + + /** + * Initialization of events system + * + * @method init_events + * + * @return void + */ + public function init_events(){ + $events = new Events(); + AppContainer::set_events($events); + } + + /** + * Initialization of call controller + * + * @method init_call_control + * + * @return void + */ + public function init_call_control(){ + $this -> call_control = CallControl::ins($this); + } + + /** + * Initialization of logging system + * + * @method init_logging + * + * @return void + */ + public function init_logging(){ + $logging = new Logging(); + AppContainer::set_logging($logging); + } + + /** + * Initialization of base model + * + * @method init_model + * + * @return void + */ + public function init_model(){ + Model::ins($this -> db); + } + + /** + * Adding call of event about application on ready + * + * @method ready_app_event + * + * @return void + */ + public function ready_app_event(){ + events() -> kernel_call('Bootstrap.ready_app', ['bootstrap' => $this]); + } + + /** + * Adding call of event about application started + * + * @method app_starting_event + * + * @return void + */ + public function app_starting_event(){ + events() -> kernel_call('Bootstrap.app_starting', ['bootstrap' => $this]); + } + + /** + * Adding call of event about application finished + * + * @method app_finished_event + * + * @return void + */ + public function app_finished_event(){ + events() -> kernel_call('Bootstrap.app_finished', ['bootstrap' => $this]); + } +} \ No newline at end of file diff --git a/server/Fury/Kernel/CallControl.php b/server/Fury/Kernel/CallControl.php new file mode 100644 index 0000000..208cd65 --- /dev/null +++ b/server/Fury/Kernel/CallControl.php @@ -0,0 +1,222 @@ + + * @version 0.1 + * Date: 08.01.2020 + * Update At: 31.01.2020 + */ + +class CallControl extends \Fury\Libs\Singleton{ + /** + * loca container for bootstrap instance + * + * @var Bootstrap + */ + protected $bootstrap; + + /** + * Flag about call + * + * @var boolean + */ + public $call_was_been = false; + + /** + * This is constructor. You know him + * + * @method __construct + * + * @param Bootstrap | NULL $bootstrap Bootstrap class instance + */ + public function __construct($bootstrap = NULL){ + if($bootstrap){ + $this -> bootstrap = $bootstrap; + } + + events() -> handler('kernel:Bootstrap.app_finished', function($params){ + $call_control = CallControl::ins(); + if(!$call_control -> call_was_been){ + events() -> kernel_call('CallControl.no_calls', []); + } + }); + } + + /** + * Call to controller class method. + * + * @method call_action + * + * @param String $getpost_flag 'GET_POST' | 'URI' + * @param String $src_route Raw route + * @param Mixed $action Action. We need call to him + * @param array $src_params Raw array with params + * + * @return void + */ + public function call_action(String $getpost_flag, String $src_route, $action, $src_params = []){ + $type = $getpost_flag ? 'GET_POST' : 'URI'; + + // make final params; + if($getpost_flag){ + if(strpos($src_route, '?')){ + list(, $src_route) = explode('?', $src_route); + } + $route = explode('&', $src_route); + $params = []; + foreach ($route as $i => $var) { + $params[$var] = $src_params[$var]; + } + }else{ + $params = $src_params; + } + + // call action with params + if(is_object($action)){ + $this -> action_result($this -> call_for_anon_func($type, $src_route, $action, $params)); + }elseif(strpos($action, '@') === false){ + $this -> action_result($this -> call_for_simple_func($type, $src_route, $action, $params)); + }else{ + $this -> action_result($this -> call_for_class_meth($type, $src_route, $action, $params)); + } + } + + /** + * Call to anonymize function + * + * @method call_for_anon_func + * + * @param String $type 'GET_POST' | 'URI' + * @param String $src_route Raw route string + * @param Function $action Anon func. We call to her + * @param Array $params Parameters for our anon func + * + * @return mixed [Result of working our action (anon func)] + */ + protected function call_for_anon_func($type, $src_route, $action, $params){ + $this -> gen_event_leading_call($type, $src_route, $action, $params); + $res = $action($params); // call + $this -> gen_event_completed_call($type, $src_route, $action, $params, $res); + return $res; + } + + /** + * Call to action if action is simple function + * + * @method call_for_simple_func + * + * @param String $type 'GET_POST' | 'URI' + * @param Mixed $src_template raw route template + * @param String $action Function name in string type + * @param Array $params Function arguments + * + * @return mixed [Result of working our action (anon func)] + */ + protected function call_for_simple_func(String $type, $src_template, String $action, $params){ + // call for simple func + $ref_func = new \ReflectionFunction($action); + $real_action_params = $ref_func -> getParameters(); + $final_action_params = []; + foreach ($real_action_params as $arg) { + if(isset($params[$arg -> name])){ + $final_action_params[$arg -> name] = $params[$arg -> name]; + } + } + + logging() -> set('CallControl@call_for_simple_func', 'Calling controller function', "$type, $src_template, $action, $final_action_params"); + $this -> gen_event_leading_call($type, $src_template, $action, $final_action_params); + $res = call_user_func_array($action, $final_action_params); + $this -> gen_event_completed_call($type, $src_template, $action, $final_action_params, $res); + return $res; + } + + /** + * Call to action if action is method of class + * + * @method call_for_class_meth + * + * @param String $type 'GET_POST' | 'URI' + * @param Mixed $src_template Raw route template + * @param String $action Class name and method name in string type. Like "Classname@methname" + * @param Array $params Method arguments + * + * @return mixed [Result of working our action (anon func)] + */ + protected function call_for_class_meth(String $type, $src_template, String $action, $params){ + list($action_class, $action_meth) = explode('@', $action); + $class_object = call_user_func_array([$action_class, 'ins'], [$this -> bootstrap]); + $ref_class = new \ReflectionClass($action_class); + $real_action_params = $ref_class -> getMethod($action_meth) -> getParameters(); + $final_action_params = []; + foreach ($real_action_params as $arg) { + if(isset($params[$arg -> name])){ + $final_action_params[$arg -> name] = $params[$arg -> name]; + } + } + + logging() -> set('CallControl@call_for_simple_func', 'Calling controller class and method', $type, $src_template, $action, $final_action_params); + $this -> gen_event_leading_call($type, $src_template, $action, $final_action_params); + $res = call_user_func_array([$class_object, $action_meth], $final_action_params); + $this -> gen_event_completed_call($type, $src_template, $action, $final_action_params, $res); + return $res; + } + + /** + * Generating event leading call. Will be runned before call action + * + * @method gen_event_leading_call + * + * @param String $type 'GET_POST' | 'URI' + * @param String $route_template Raw route template + * @param Mixed $action + * @param Array $params Arguments for action + * + * @return void + */ + protected function gen_event_leading_call(String $type, String $route_template, $action, $params){ + $this -> call_was_been = true; + events() -> kernel_call( + 'CallControl.leading_call', + compact('type', 'route_template', 'action', 'params') + ); + } + + /** + * Generating event completed call. Will be runned after call to action + * + * @method gen_event_completed_call + * + * @param String $type 'GET_POST' | 'URI' + * @param String $route_template Raw route template + * @param Mixed $action + * @param Array $params Arguments for action + * @param Mixed $result Result of worked action + * + * @return void + */ + protected function gen_event_completed_call(String $type, String $route_template, $action, $params, $result){ + $this -> call_was_been = true; + events() -> kernel_call( + 'CallControl.completed_call', + compact('type', 'route_template', 'action', 'params', 'result') + ); + } + + /** + * Result of action. Will be runned when action woking is finished. + * + * @method action_result + * + * @param Mixed $result Result of worked action + * + * @return void + */ + protected function action_result($result){ + echo $result; + + logging() -> dump(); + } +} \ No newline at end of file diff --git a/server/Fury/Kernel/Controller.php b/server/Fury/Kernel/Controller.php new file mode 100644 index 0000000..2562549 --- /dev/null +++ b/server/Fury/Kernel/Controller.php @@ -0,0 +1,17 @@ + events_ins = events(); + return $this -> create_connect($db_params); + } + + public function create_connect($db_params){ + $this -> db_params = $db_params; + $dblib = "{$db_params['dblib']}:host={$db_params['host']};dbname={$db_params['dbname']};charset={$db_params['charset']}"; + $this -> connect = new \PDO($dblib, $db_params['user'], $db_params['password']); + $this -> gen_event_create_connect($this -> connect, $this -> db_params); + return $this -> connect; + } + + private function gen_event_create_connect($connect, $db_params){ + $this -> events_ins -> kernel_call( + 'DB.create_connect', + compact('connect', 'db_params') + ); + } + + public function get_connect(){ + return $this -> connect; + } + + public function query($sql, $params = NULL){ + if(is_null($params)){ + return $this -> connect -> query($sql); + } + + return $this -> connect -> query($sql, $params); + } +} \ No newline at end of file diff --git a/server/Fury/Kernel/Events.php b/server/Fury/Kernel/Events.php new file mode 100644 index 0000000..f211ba1 --- /dev/null +++ b/server/Fury/Kernel/Events.php @@ -0,0 +1,168 @@ + map = []; + foreach($this -> event_types as $type){ + $this -> map[$type] = []; + } + } + + /** + * Get events map + * + * @method get_map + * + * @param boolean $full_map_flag Flag. If true - returned full map with app and kernel events, else only events map of app + * + * @return array + */ + public function get_map($full_map_flag = false){ + if($full_map_flag){ + return $this -> map; + } + + return $this -> map['app']; + } + + /** + * Get history of calling events handlers + * + * @method get_call_history + * + * @return array + */ + public function get_call_history(){ + return $this -> call_history; + } + + /** + * Event generation in the right places + * + * @method call + * + * @param string $type kernel or app + * @param string $event_name Uniq name of event + * @param array $params Array with parameters for event handlers + * + * @return boolean + */ + private function call($type, $event_name, $params){ + if(!isset($this -> map[$type][$event_name])){ + return false; + } + + foreach ($this -> map[$type][$event_name] as $i => $handler) { + $log_id = $this -> log_call_history($type, $event_name, $params); + $result = $handler($params); + $this -> add_result_to_log_call_history($log_id, $result); + } + + return true; + } + + /** + * logging call to history list + * + * @method log_call_history + * + * @param string $type Events type + * @param string $event_name Name of events + * @param array $params Parameters + * + * @return int Unique ID of handler call + */ + private function log_call_history($type, $event_name, $params){ + if(!FCONF['debug']){ + return false; + } + + $log_id = uniqid(); + $this -> call_history[$log_id] = [ + 'type' => $type, + 'event_name' => $event_name, + 'params' => $params + ]; + return $log_id; + } + + /** + * Add result of working event handler + * + * @method add_result_to_log_call_history + * + * @param int $log_id Unique log id + * @param any $result Result of working event handler + */ + private function add_result_to_log_call_history($log_id, $result){ + if(!FCONF['debug']){ + return false; + } + + if(isset($this -> call_history[$log_id])){ + $this -> call_history[$log_id]['result'] = $result; + return true; + } + return false; + } + + /** + * Add new handler for event + * + * @method handler + * + * @param string $event_name Name of events with type. Example "app:my_event" or "kernel:some_event" + * @param function $handler Anonymous function that will be the handler + * + * @return boolean result + */ + public function handler($event_name, $handler){ + list($type, $event_name) = explode(':', $event_name); + $type = trim(strtolower($type)); + $event_name = trim($event_name); + + if(!isset($this -> map[$type])){ + return false; + } + + if($event_name == ''){ + return false; + } + + if(isset($this -> map[$type][$event_name]) and is_array($this -> map[$type][$event_name])){ + $this -> map[$type][$event_name][] = $handler; + }else{ + $this -> map[$type][$event_name] = [$handler]; + } + + return true; + } + + public function __call($methname, $args){ + foreach ($this -> event_types as $i => $type) { + if(strpos($methname, $type . '_call') === false) + continue; + return $this -> call($type, $args[0], $args[1]); + } + return false; + } + +} \ No newline at end of file diff --git a/server/Fury/Kernel/Init.php b/server/Fury/Kernel/Init.php new file mode 100644 index 0000000..44c0b43 --- /dev/null +++ b/server/Fury/Kernel/Init.php @@ -0,0 +1,57 @@ + + * @version 0.1 + * Date: 09.02.2020 + */ + +class Init{ + /** + * Bootstrap class instance + * + * @var Bootstrap + */ + protected $bootstrap; + + /** + * Constructor with params + * + * @method __construct + * + * @param Bootstrap $bootstrap Bootstrap instance + */ + public function __construct(Bootstrap $bootstrap){ + $this -> bootstrap = $bootstrap; + } + + /** + * Method for framework and application initialization + * If you need changed order of initialization - ok, but be careful :) + * + * @method init + * + * @return void + */ + public function init(){ + $this -> bootstrap -> init_config(); + $this -> bootstrap -> init_consts(); + $this -> bootstrap -> init_logging(); + $this -> bootstrap -> init_events(); + + $this -> bootstrap -> app_starting_event(); + + $this -> bootstrap -> init_call_control(); + $this -> bootstrap -> init_app_file(); + + $this -> bootstrap -> init_db(); + $this -> bootstrap -> init_model(); + + $this -> bootstrap -> ready_app_event(); + + $this -> bootstrap -> app_finished_event(); + } +} \ No newline at end of file diff --git a/server/Fury/Kernel/Logging.php b/server/Fury/Kernel/Logging.php new file mode 100644 index 0000000..3e2a60d --- /dev/null +++ b/server/Fury/Kernel/Logging.php @@ -0,0 +1,98 @@ + storage = []; + $this -> session_id = uniqid(); + $this -> logs_folder = FCONF['logs_folder']; + } + + /** + * Set new log item + * + * @method set + * + * @param string $place String in format "Classname@methname" or "funcname" + * @param string $title Title of log. + * @param string $message Any text message + */ + public function set($place, $title, $message){ + if(!FCONF['logs_enable']) + return false; + + if(strpos($place, '@') === false){ + $class = ''; + $meth = $place; + }else{ + list($class, $meth) = explode('@', $place); + } + + $this -> storage[] = [ + 'class' => $class, + 'meth' => $meth, + 'title' => $title, + 'message' => $message, + 'timestamp' => microtime(true) + ]; + + return true; + } + + + /** + * Dumping session logs to json file + * + * @method dump + * + * @return boolean Result of writing to log file + */ + public function dump(){ + $log_filename = date('d.m.Y') . '.log.json'; + $path_to_log_file = $this -> logs_folder . '/' . $log_filename; + $session = [ + 'session_id' => $this -> session_id, + 'timestamp' => microtime(true), + 'logs' => $this -> storage + ]; + + if(!file_exists($path_to_log_file)){ + file_put_contents($path_to_log_file, ''); + chmod($path_to_log_file, 0755); + return file_put_contents($path_to_log_file, json_encode([$session], JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT)); + } + + $logs = json_decode(file_get_contents($path_to_log_file), true); + $logs[] = $session; + return file_put_contents($path_to_log_file, json_encode($logs, JSON_UNESCAPED_SLASHES|JSON_PRETTY_PRINT)); + } +} \ No newline at end of file diff --git a/server/Fury/Kernel/Model.php b/server/Fury/Kernel/Model.php new file mode 100644 index 0000000..2d944bd --- /dev/null +++ b/server/Fury/Kernel/Model.php @@ -0,0 +1,17 @@ + lang = $lang; + $this -> vocabulary = ["en" => [ + "Aenean facilisis venenatis ipsum vel aliquet.", + "Aenean rhoncus malesuada auctor.", + "Cras sit amet magna sit amet felis eleifend lacinia.", + "Donec nec velit eget tellus adipiscing iaculis eu non lorem.", + "Donec ac tellus eu tellus dignissim blandit.", + "Donec diam dui, mollis venenatis lacinia ac, pretium id augue.", + "Donec lectus dolor, cursus eget facilisis id, ultrices ac mauris.", + "Duis sem quam, euismod ac rhoncus id, adipiscing sed sem.", + "Etiam sagittis tellus sapien.", + "In accumsan bibendum magna a egestas.", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", + "Maecenas tristique magna nulla, in fringilla purus.", + "Nulla eleifend velit faucibus eros rhoncus molestie.", + "Nulla pellentesque dolor at metus molestie ultrices nec vitae metus.", + "Pellentesque vel felis purus, ut dignissim erat.", + "Pellentesque quis purus nec odio aliquet bibendum ut vitae risus.", + "Phasellus sed felis vitae purus dictum fermentum.", + "Praesent ac tellus dui, in euismod leo.", + "Proin vulputate tincidunt erat id auctor.", + "Sed non justo enim.", + "Vestibulum imperdiet nunc id metus pellentesque eleifend.", + "Vivamus ultricies iaculis arcu, vitae bibendum tellus feugiat venenatis.", + "Sed ultricies mi vel aliquet eleifend.", + "Ut egestas est id ligula gravida, quis lobortis lacus consectetur.", + "Cras ac urna fringilla, bibendum leo sit amet, suscipit nisi.", + "Sed gravida erat sit amet neque rutrum mattis.", + "Integer at ex nec nunc euismod scelerisque.", + "Nullam faucibus dui imperdiet rutrum rhoncus.", + "Proin scelerisque sapien et augue sodales auctor.", + "In posuere erat ut posuere mollis.", + "Morbi lobortis ipsum eu ipsum eleifend, eu tincidunt arcu sagittis." + ], + "ru" => [ + "Интеллект естественно понимает под собой интеллигибельный закон внешнего мира, открывая новые горизонты.", + "Гедонизм осмысляет дедуктивный метод. Надстройка нетривиальна.", + "Дискретность амбивалентно транспонирует гравитационный парадокс.", + "Смысл жизни, следовательно, творит данный закон внешнего мира.", + "Дедуктивный метод решительно представляет собой бабувизм.", + "Имеется спорная точка зрения, гласящая примерно следующее: элементы политического процесса, превозмогая сложившуюся непростую экономическую ситуацию, превращены в посмешище, хотя само их существование приносит несомненную пользу обществу.", + "Но явные признаки победы институционализации в равной степени предоставлены сами себе.", + "В своём стремлении повысить качество жизни, они забывают, что существующая теория предоставляет широкие возможности для экономической целесообразности принимаемых решений.", + "Не следует, однако, забывать, что глубокий уровень погружения не оставляет шанса для экспериментов, поражающих по своей масштабности и грандиозности.", + "Сложно сказать, почему некоторые особенности внутренней политики и по сей день остаются уделом либералов, которые жаждут быть ограничены исключительно образом мышления!", + "В целом, конечно, социально-экономическое развитие выявляет срочную потребность первоочередных требований.", + "Каждый из нас понимает очевидную вещь: социально-экономическое развитие позволяет выполнить важные задания по разработке инновационных методов управления процессами.", + "Предварительные выводы неутешительны: новая модель организационной деятельности, а также свежий взгляд на привычные вещи - безусловно открывает новые горизонты для позиций, занимаемых участниками в отношении поставленных задач!", + "А также элементы политического процесса преданы социально-демократической анафеме.", + "В частности, убеждённость некоторых оппонентов предполагает независимые способы реализации глубокомысленных рассуждений.", + "Задача организации, в особенности же консультация с широким активом позволяет выполнить важные задания по разработке системы массового участия.", + "Таким образом, граница обучения кадров способствует подготовке и реализации переосмысления внешнеэкономических политик.", + "Есть над чем задуматься: независимые государства формируют глобальную экономическую сеть и при этом - преданы социально-демократической анафеме.", + "Предприниматели в сети интернет освещают чрезвычайно интересные особенности картины в целом, однако конкретные выводы, разумеется, преданы социально-демократической анафеме.", + "Принимая во внимание показатели успешности, консультация с широким активом представляет собой интересный эксперимент проверки первоочередных требований.", + "Как уже неоднократно упомянуто, стремящиеся вытеснить традиционное производство, нанотехнологии, инициированные исключительно синтетически, объединены в целые кластеры себе подобных.", + "Учитывая ключевые сценарии поведения, высококачественный прототип будущего проекта напрямую зависит от экспериментов, поражающих по своей масштабности и грандиозности.", + "Идейные соображения высшего порядка, а также граница обучения кадров предопределяет высокую востребованность дальнейших направлений развития.", + "В частности, постоянный количественный рост и сфера нашей активности, в своём классическом представлении, допускает внедрение приоритизации разума над эмоциями.", + "Для современного мира курс на социально-ориентированный национальный проект обеспечивает актуальность глубокомысленных рассуждений.", + "И нет сомнений, что некоторые особенности внутренней политики объявлены нарушающими общечеловеческие нормы этики и морали.", + "С другой стороны, перспективное планирование представляет собой интересный эксперимент проверки анализа существующих паттернов поведения.", + "Мы вынуждены отталкиваться от того, что реализация намеченных плановых заданий однозначно определяет каждого участника как способного принимать собственные решения касаемо прогресса профессионального сообщества.", + "Значимость этих проблем настолько очевидна, что убеждённость некоторых оппонентов представляет собой интересный эксперимент проверки экономической целесообразности принимаемых решений.", + "Учитывая ключевые сценарии поведения, экономическая повестка сегодняшнего дня требует анализа системы массового участия." + ] + ]; + + $this -> count_sentence = count($this -> vocabulary[$this -> lang]); + + $this -> names = ["male" => [], "female" => []]; + $this -> names["male"] = [ + "Liam", "Noah", "Mason", "Ethan", "Logan", + "Lucas", "Jackson", "Aiden", "Oliver", "Jacob", + "Elijah", "Alexander", "James", "Benjamin", "Jack", + "Luke", "William", "Michael", "Owen", "Daniel", + "Carter", "Gabriel", "Henry", "Matthew", "Wyatt", + "Caleb", "Jayden", "Nathan", "Ryan", "Isaac", + "Liam","Noah","Oliver","Elijah","James","William","Benjamin","Lucas","Henry","Theodore","Jack","Levi", + "Alexander","Jackson","Mateo","Daniel","Michael","Mason","Sebastian","Ethan","Logan","Owen","Samuel", + "Jacob","Asher","Aiden","John","Joseph","Wyatt","David","Leo","Luke","Julian","Hudson","Grayson","Matthew", + "Ezra","Gabriel","Carter","Isaac","Jayden","Luca","Anthony","Dylan","Lincoln","Thomas","Maverick", + "Elias","Josiah","Charles","Caleb","Christopher","Ezekiel","Miles","Jaxon","Isaiah","Andrew", + "Joshua","Nathan","Nolan","Adrian","Cameron","Santiago","Eli","Aaron","Ryan","Angel","Cooper", + "Waylon","Easton","Kai","Christian","Landon","Colton","Roman","Axel","Brooks","Jonathan","Robert", + "Jameson","Ian","Everett","Greyson","Wesley","Jeremiah","Hunter","Leonardo","Jordan","Jose","Bennett", + "Silas","Nicholas","Parker","Beau","Weston","Austin","Connor","Carson","Dominic","Xavier","Jaxson", + "Jace","Emmett","Adam","Declan","Rowan","Micah","Kayden","Gael","River","Ryder","Kingston","Damian", + "Sawyer","Luka","Evan","Vincent","Legend","Myles","Harrison","August","Bryson","Amir","Giovanni", + "Chase","Diego","Milo","Jasper","Walker","Jason","Brayden","Cole","Nathaniel","George","Lorenzo", + "Zion","Luis","Archer","Enzo","Jonah","Thiago","Theo","Ayden","Zachary","Calvin","Braxton","Ashton", + "Rhett","Atlas","Jude","Bentley","Carlos","Ryker","Adriel","Arthur","Ace","Tyler","Jayce","Max", + ]; + $this -> names["female"] = [ + "Emma", "Olivia", "Ava", "Sophia", "Isabella", + "Mia", "Charlotte", "Amelia", "Emily", "Madison", + "Harper", "Abigail", "Avery", "Lily", "Ella", + "Chloe", "Evelyn", "Sofia", "Aria", "Ellie", + "Aubrey", "Scarlett", "Zoey", "Hannah", "Audrey", + "Grace", "Addison", "Zoe", "Elizabeth", "Nora" + ]; + + $this -> surnames = [ + "Smith", "Johnson", "Williams", "Jones", "Brown", + "Davis", "Miller", "Wilson", "Moore", "Taylor", + "Anderson", "Thomas", "Jackson", "White", "Harris", + "Martin", "Thompson", "Garcia", "Martinez", "Robinson", + "Clark", "Rodriguez", "Lewis", "Lee", "Walker", + "Hall", "Allen", "Young", "Hernandez", "King", + "Wright", "Lopez", "Hill", "Scott", "Green", + "Adams", "Baker", "Gonzalez", "Nelson", "Carter", + "Mitchell", "Perez", "Roberts", "Turner", "Phillips", + "Campbell", "Parker", "Evans", "Edwards", "Collins", + "Stewart", "Sanchez", "Morris", "Rogers", "Reed", + "Cook", "Morgan", "Bell", "Murphy", "Bailey", + "Rivera", "Cooper", "Richardson", "Cox", "Howard", + "Ward", "Torres", "Peterson", "Gray", "Ramirez", + "James", "Watson", "Brooks", "Kelly", "Sanders", + "Price", "Bennett", "Wood", "Barnes", "Ross", + "Henderson", "Coleman", "Jenkins", "Perry", "Powell", + "Long", "Patterson", "Flores", "Washington", "Hughes", + "Butler", "Simmons", "Gonzales", "Foster", "Bryant", + "Alexander", "Russell", "Griffin", "Diaz", "Hayes", + "Elliot","Graham","Kaiden","Maxwell","Juan","Dean","Matteo","Malachi","Ivan","Elliott","Jesus", + "Emiliano","Messiah","Gavin","Maddox","Camden","Hayden","Leon","Antonio","Justin","Tucker","Brandon", + "Kevin","Judah","Finn","King","Brody","Xander","Nicolas","Charlie","Arlo","Emmanuel","Barrett", + "Felix","Alex","Miguel","Abel","Alan","Beckett","Amari","Karter","Timothy","Abraham","Jesse", + "Zayden","Blake","Alejandro","Dawson","Tristan","Victor","Avery","Joel","Grant","Eric","Patrick", + "Peter","Richard","Edward","Andres","Emilio","Colt","Knox","Beckham","Adonis","Kyrie","Matias", + "Oscar","Lukas","Marcus","Hayes","Caden","Remington","Griffin","Nash","Israel","Steven","Holden", + "Rafael","Zane","Jeremy","Kash","Preston","Kyler","Jax","Jett","Kaleb","Riley","Simon","Phoenix", + "Javier","Bryce","Louis","Mark","Cash","Lennox","Paxton","Malakai","Paul","Kenneth","Nico","Kaden", + "Lane","Kairo","Maximus","Omar","Finley","Atticus","Crew","Brantley","Colin","Dallas","Walter", + "Brady","Callum","Ronan","Hendrix","Jorge","Tobias","Clayton","Emerson","Damien","Zayn","Malcolm", + "Kayson","Bodhi","Bryan","Aidan","Cohen","Brian","Cayden","Andre","Niko","Maximiliano","Zander", + "Khalil","Rory","Francisco","Cruz","Kobe","Reid","Daxton","Derek","Martin","Jensen","Karson","Tate", + "Muhammad","Jaden","Joaquin","Josue","Gideon","Dante","Cody","Bradley","Orion","Spencer","Angelo", + "Erick","Jaylen","Julius","Manuel","Ellis","Colson","Cairo","Gunner","Wade","Chance","Odin","Anderson", + "Kane","Raymond","Cristian","Aziel","Prince","Ezequiel","Jake","Otto","Eduardo","Rylan","Ali","Cade", + "Stephen","Ari","Kameron","Dakota","Warren","Ricardo","Killian","Mario","Romeo","Cyrus","Ismael", + "Russell","Tyson","Edwin","Desmond","Nasir","Remy","Tanner","Fernando","Hector","Titus","Lawson", + "Sean","Kyle","Elian","Corbin","Bowen","Wilder","Armani","Royal","Stetson","Briggs","Sullivan", + "Leonel","Callan","Finnegan","Jay","Zayne","Marshall","Kade","Travis","Sterling","Raiden","Sergio", + "Tatum","Cesar","Zyaire","Milan","Devin","Gianni","Kamari","Royce","Malik","Jared","Franklin", + "Clark","Noel","Marco","Archie","Apollo","Pablo","Garrett","Oakley","Memphis","Quinn","Onyx", + "Alijah","Baylor","Edgar","Nehemiah","Winston","Major","Rhys","Forrest","Jaiden","Reed","Santino", + "Troy","Caiden","Harvey","Collin","Solomon","Donovan","Damon","Jeffrey","Kason","Sage","Grady", + "Kendrick","Leland","Luciano","Pedro","Hank","Hugo","Esteban","Johnny","Kashton","Ronin", + "Ford","Mathias","Porter","Erik","Johnathan","Frank","Tripp","Casey","Fabian","Leonidas","Baker", + "Matthias","Philip","Jayceon","Kian","Saint","Ibrahim","Jaxton","Augustus","Callen","Trevor","Ruben", + "Adan","Conor","Dax","Braylen","Kaison","Francis","Kyson","Andy","Lucca","Mack","Peyton","Alexis", + "Deacon","Kasen","Kamden","Frederick","Princeton","Braylon","Wells","Nikolai","Iker","Bo","Dominick", + "Moshe","Cassius","Gregory","Lewis","Kieran","Isaias","Seth","Marcos","Omari","Shane","Keegan","Jase", + "Asa","Sonny","Uriel","Pierce","Jasiah","Eden","Rocco","Banks","Cannon","Denver","Zaiden","Roberto", + "Shawn","Drew","Emanuel","Kolton","Ayaan","Ares","Conner","Jalen","Alonzo","Enrique","Dalton","Moses", + "Koda","Bodie","Jamison","Phillip","Zaire","Jonas","Kylo","Moises","Shepherd","Allen","Kenzo", + "Mohamed","Keanu","Dexter","Conrad","Bruce","Sylas","Soren","Raphael","Rowen","Gunnar","Sutton", + "Quentin","Jaziel","Emmitt","Makai","Koa","Maximilian","Brixton","Dariel","Zachariah","Roy","Armando", + "Corey","Saul","Izaiah","Danny","Davis","Ridge","Yusuf","Ariel","Valentino","Jayson","Ronald", + "Albert","Gerardo","Ryland","Dorian","Drake","Gage","Rodrigo","Hezekiah","Kylan","Boone","Ledger", + "Santana","Jamari","Jamir","Lawrence","Reece","Kaysen","Shiloh","Arjun","Marcelo","Abram","Benson", + "Huxley","Nikolas","Zain","Kohen","Samson","Miller","Donald","Finnley","Kannon","Lucian","Watson","Keith", + "Westin","Tadeo","Sincere","Boston","Axton","Amos","Chandler","Leandro","Raul","Scott","Reign", + "Alessandro","Camilo","Derrick","Morgan","Julio","Clay","Edison","Jaime","Augustine","Julien","Zeke", + "Marvin","Bellamy","Landen","Dustin","Jamie","Krew","Kyree","Colter","Johan","Houston","Layton", + "Quincy","Case","Atreus","Cayson","Aarav","Darius","Harlan","Justice","Abdiel","Layne","Raylan", + "Arturo","Taylor","Anakin","Ander","Hamza","Otis","Azariah","Leonard","Colby","Duke","Flynn","Trey", + "Gustavo","Fletcher","Issac","Sam","Trenton","Callahan","Chris","Mohammad","Rayan","Lionel","Bruno", + "Jaxxon","Zaid","Brycen","Roland","Dillon","Lennon","Ambrose","Rio","Mac","Ahmed","Samir","Yosef", + "Tru","Creed","Tony","Alden","Aden","Alec","Carmelo","Dario","Marcel","Roger","Ty","Ahmad","Emir", + "Landyn","Skyler","Mohammed","Dennis","Kareem","Nixon","Rex","Uriah","Lee","Louie","Rayden","Reese", + "Alberto","Cason","Quinton","Kingsley","Chaim","Alfredo","Mauricio","Caspian","Legacy","Ocean","Ozzy", + "Briar","Wilson","Forest","Grey","Joziah","Salem","Neil","Remi","Bridger","Harry","Jefferson", + "Lachlan","Nelson","Casen","Salvador","Magnus","Tommy","Marcellus","Maximo","Jerry","Clyde","Aron", + "Keaton","Eliam","Lian","Trace","Douglas","Junior","Titan","Cullen","Cillian","Musa","Mylo","Hugh", + "Tomas","Vincenzo","Westley","Langston","Byron","Kiaan","Loyal","Orlando","Kyro","Amias","Amiri", + "Jimmy","Vicente","Khari","Brendan","Rey","Ben","Emery","Zyair","Bjorn","Evander","Ramon","Alvin", + "Ricky","Jagger","Brock","Dakari","Eddie","Blaze","Gatlin","Alonso","Curtis","Kylian","Nathanael", + "Devon","Wayne","Zakai","Mathew","Rome","Riggs","Aryan","Avi","Hassan","Lochlan","Stanley","Dash", + "Kaiser","Benicio","Bryant","Talon","Rohan","Wesson","Joe","Noe","Melvin","Vihaan","Zayd","Darren", + "Enoch","Mitchell","Jedidiah","Brodie","Castiel","Ira","Lance","Guillermo","Thatcher","Ermias","Misael", + "Jakari","Emory","Mccoy","Rudy","Thaddeus","Valentin","Yehuda","Bode","Madden","Kase","Bear","Boden", + "Jiraiya","Maurice","Alvaro","Ameer","Demetrius","Eliseo","Kabir","Kellan","Allan","Azrael","Calum", + "Niklaus","Ray","Damari","Elio","Jon","Leighton","Axl","Dane","Eithan","Eugene","Kenji","Jakob", + "Colten","Eliel","Nova","Santos","Zahir","Idris","Ishaan","Kole","Korbin","Seven","Alaric","Kellen", + "Bronson","Franco","Wes","Larry","Mekhi","Jamal","Dilan","Elisha","Brennan","Kace","Van","Felipe","Fisher", + "Cal","Dior","Judson","Alfonso","Deandre","Rocky","Henrik","Reuben","Anders","Arian","Damir","Jacoby", + "Khalid","Kye","Mustafa","Jadiel","Stefan","Yousef","Aydin","Jericho","Robin","Wallace","Alistair","Davion", + "Alfred","Ernesto","Kyng","Everest","Gary","Leroy","Yahir","Braden","Kelvin","Kristian","Adler","Avyaan", + "Brayan","Jones","Truett","Aries","Joey","Randy","Jaxx","Jesiah","Jovanni","Azriel","Brecken","Harley", + "Zechariah","Gordon","Jakai","Carl","Graysen","Kylen","Ayan","Branson","Crosby","Dominik","Jabari", + "Jaxtyn","Kristopher","Ulises","Zyon","Fox","Howard","Salvatore","Turner","Vance","Harlem","Jair","Jakobe", + "Jeremias","Osiris","Azael","Bowie","Canaan","Elon","Granger","Karsyn","Zavier","Cain","Dangelo","Heath", + "Yisroel","Gian","Shepard","Harold","Kamdyn","Rene","Rodney","Yaakov","Adrien","Kartier","Cassian", + "Coleson","Ahmir","Darian","Genesis","Kalel","Agustin","Wylder","Yadiel","Ephraim","Kody","Neo","Ignacio", + "Osman","Aldo","Abdullah","Cory","Blaine","Dimitri","Khai","Landry","Palmer","Benedict","Leif","Koen", + "Maxton","Mordechai","Zev","Atharv","Bishop","Blaise","Davian" + ]; + + $this -> phone_numbers = ["country_code" => ["+1", "+3", "+7", "+9", "+2", "+4"], "region_code" => [ + 209, 213, 310, 323, 408, 415, 424, 510, 530, 559, 562, 619, 626, 650, 661, 707, 714, 760, 805, 818, 831, 858, 909, 925, 949, + 239, 305, 321, 352, 386, 407, 561, 727, 754, 772, 786, 813, 850, 863, 904, 941, 954, + 217, 224, 309, 312, 331, 464, 618, 630, 708, 773, 779, 815, 847, 872 + ]]; + $this -> phone_numbers["count_country_code"] = count($this -> phone_numbers["country_code"]); + $this -> phone_numbers["count_region_code"] = count($this -> phone_numbers["region_code"]); + $this -> email_domen_list = [ + "gmail", + "yahoo", + "hotmail", + "outlook", + "mail" + ]; + } + + /** + * wrap for $this -> gen() + * + * @return Array + */ + public function gen_list(Int $count_items){ + return $this -> gen($count_items); + } + + /** + * Generate preset words + * + * @return String + */ + public function gen_words(Int $count_words){ + $max_count = 30; + if($count_words > $max_count) $count_words = $max_count; + list($paragraph) = $this -> gen_paragraphs(1, 10, 20); + $paragraph = explode(" ", $paragraph); + $words = []; + for($i = 0; $i < $count_words; $i++){ + $words[] = $paragraph[$i]; + } + $words = implode(" ", $words); + $words = trim($words, ","); + return $words; + } + + /** + * Generate preset count paragraphs + * + * @return Array + */ + public function gen_paragraphs(Int $count_p, Int $min_len = 1, Int $max_len = 30){ + $p = []; + for($i=0; $i<$count_p; $i++){ + $paragraphy_len = rand($min_len, $max_len); + $p[] = implode(" ", $this -> gen($paragraphy_len)); + } + + return $p; + } + + /** + * Generate one paragraph + * + * @return String + */ + public function gen_paragraph(Int $count_sentence = 0){ + if(!$count_sentence) $count_sentence = rand(1, 30); + $p = implode(" ", $this -> gen($count_sentence)); + return $p; + } + + /** + * gen Generated base list width random sentence + * + * @return Array + */ + private function gen(Int $count){ + $prevnum = -1; + $li = []; + for($i=0; $i<$count; $i++){ + $currentnum = rand(0, $this -> count_sentence - 1); + if($currentnum == $prevnum){ + $currentnum = rand(0, $this -> count_sentence - 1); + } + $li[] = $this -> vocabulary[$this -> lang][$currentnum]; + $prevnum = $currentnum; + } + + return $li; + } + + // ---- NAMES ---- // + + /** + * Generate and return random eng name + * + * @return String + */ + public function get_name(String $sex = ""){ + if($sex == ""){ + $sex = rand(0, 1) ? "male" : "female"; + } + $count_names = count($this -> names[$sex]); + return $this -> names[$sex][rand(0, $count_names - 1)]; + } + + /** + * Wrapper for get_name func + * + * @return String [female name] + */ + public function get_female_name(){ + return $this -> get_name("female"); + } + + /** + * Wwrapper for get_name func + * + * @return String [male name] + */ + public function get_male_name(){ + return $this -> get_name("male"); + } + + /** + * @return String [return surname] + */ + public function get_surname(){ + $count_surnames = count($this -> surnames); + return $this -> surnames[rand(0, $count_surnames - 1)]; + } + + /** + * Return name and surname with separator space + * + * @return String [return name and surname with separator space] + */ + public function get_full_name_to_str(){ + return $this -> get_name() . " " . $this -> get_surname(); + } + + /** + * Return name and surname in array + * + * @return Array [return name and surname in array] + */ + public function get_full_name_to_arr(){ + return ["name" => $this -> get_name(), "surname" => $this -> get_surname()]; + } + + // ---- PHONE NUMBERS ---- // + + /** + * @return String [formated phone number] + */ + public function get_phone_number(){ + $count_country_code = $this -> phone_numbers["count_country_code"] - 1; + $count_region_code = $this -> phone_numbers["count_region_code"] - 1; + $country_code = $this -> phone_numbers["country_code"][ rand(0, $count_country_code) ]; + $region_code = $this -> phone_numbers["region_code"][ rand(0, $count_region_code) ]; + $phone_number = $country_code . " " . $region_code . "-" . rand(100, 999) . "-" . rand(1000, 9999); + return $phone_number; + } + + // ---- EMAIL ---- // + + /** + * Email address + * + * @return String [email] + */ + public function get_email(String $name = "", String $surname = ""){ + $count = count($this -> email_domen_list) - 1; + $name = $name != "" ? $name : $this -> get_name(); + $surname = $surname != "" ? $surname : $this -> get_surname(); + $sep_arr = [".", "_", ""]; + $sep = $sep_arr[ rand(0, count($sep_arr) - 1) ]; + $host = $this -> email_domen_list[ rand(0, $count) ]; + $email = strtolower($name) . $sep . strtolower($surname) . "@" . $host . ".com"; + return $email; + } + + // ---- USER ---- // + + /** + * data about one random user + * + * @return Array [user card in assoc array] + */ + public function get_user_card(String $sex = ""){ + if($sex == ""){ + $sex = rand(0, 1) ? "male" : "female"; + } + $name = $this -> get_name($sex); + $surname = $this -> get_surname(); + $user = [ + "name" => $name, + "surname" => $surname, + "sex" => $sex, + "phone" => $this -> get_phone_number(), + "email" => $this -> get_email($name, $surname) + ]; + + return $user; + } +} \ No newline at end of file diff --git a/server/Fury/Libs/Singleton.php b/server/Fury/Libs/Singleton.php new file mode 100644 index 0000000..01c7331 --- /dev/null +++ b/server/Fury/Libs/Singleton.php @@ -0,0 +1,19 @@ + + * @version 0.1 + * Date: 19.07.2022 + */ + +class ErrorHandler{ + /** + * With all errs in source view + */ + private Array $errs_src; + + /** + * What errors need to be displayed and logined + */ + private Array $important_errors; + + public function __construct(){ + $this -> important_errors = FCONF["error_handler"]["important_errors"]; + + if(!FCONF["debug"]){ + error_reporting(-1); + }else{ + error_reporting(0); + } + + $this -> set_err_handler(); + } + + /** + * Set custom error handler + */ + public function set_err_handler(){ + set_error_handler([$this, "error_handler"], E_ALL); + register_shutdown_function([$this, "fatal_error_handler"]); + // set_exception_handler([$this, "exception_handler"]); + } + + // FIXME + public function exception_handler(\Exception $e) { + $this -> error_handler( + $e -> getCode(), + $e -> getMessage(), + $e -> getFile(), + $e -> getLine() + ); + } + + /** + * Set custom FATAL error handler + */ + public function fatal_error_handler(){ + $error = error_get_last(); + if ($error){ + $this -> view_fatal_error($error["type"], $error["message"], $error["file"], $error["line"]); + } + } + + /** + * Handle of error + */ + public function error_handler(Int $errno, String $errstr, String $errfile, Int $errline){ + $err_type = $this -> get_err_type($errno); + if(!$this -> error_is_important($err_type)){ + return true; + } + + $this -> view_fatal_error($errno, $errstr, $errfile, $errline); + return true; + } + + /** + * Get type of error + */ + private function get_err_type(Int $errno){ + $errors = array( + E_ERROR => "E_ERROR", + E_WARNING => "E_WARNING", + E_PARSE => "E_PARSE", + E_NOTICE => "E_NOTICE", + E_CORE_ERROR => "E_CORE_ERROR", + E_CORE_WARNING => "E_CORE_WARNING", + E_COMPILE_ERROR => "E_COMPILE_ERROR", + E_COMPILE_WARNING => "E_COMPILE_WARNING", + E_USER_ERROR => "E_USER_ERROR", + E_USER_WARNING => "E_USER_WARNING", + E_USER_NOTICE => "E_USER_NOTICE", + E_STRICT => "E_STRICT", + E_RECOVERABLE_ERROR => "E_RECOVERABLE_ERROR", + E_DEPRECATED => "E_DEPRECATED", + E_USER_DEPRECATED => "E_USER_DEPRECATED", + ); + + return isset($errors[$errno]) ? $errors[$errno] : "EXCEPTION"; + } + + /** + * Get lines with errors from file + */ + public function get_prog_code(String $errfile, Int $errline) { + $file = explode("\n", file_get_contents($errfile)); + $code = []; + for($i = $errline - 8; $i < $errline + 6; $i++){ + if(!isset($file[$i])) continue; + if(trim($file[$i]) == "") continue; + $code[$i + 1] = str_replace("\t", " ", htmlspecialchars($file[$i])); + } + return $code; + } + + protected function error_is_important(String $errtype){ + foreach($this -> important_errors as $important_error){ + if($errtype == $important_error){ + return true; + } + } + return false; + } + + /** + * show styles and html code for fatal error + */ + public function view_fatal_error(Int $errno, String $errstr, String $errfile, Int $errline){ + http_response_code(500); + if(!FCONF["debug"]) return false; + $err_type = $this -> get_err_type($errno); + $code = $this -> get_prog_code($errfile, $errline); + $errstr = str_replace(["\\", "\n", "\r", "\t", "\""], ["\", "", "", "", "'"], str_replace("`", "'", $errstr)); + $code = str_replace(["\\", "\n"], ["\", ""], str_replace("`", "'", $code)); + $this -> show_err_page(compact("errno", "err_type", "errstr", "errfile", "errline", "code")); + } + + protected function show_err_page(Array $data) { + $json_data = json_encode($data); + echo "
" . implode("
", $this -> lorem_ipsum -> gen_paragraphs(rand(1, 8), 1, 20)) . "
", + rand(1, 2), + rand(0, 1), + rand(0, 10000), + "UAH", + rand(400000, 600000) / 10000, + rand(220000, 300000) / 10000, + "Ukraine", + "Украина", + "TestRegion", + "ТестРегион", + "TestCity", + "ТестГород", + 0 + ); + + echo "\n#{$i} {$title}"; + } + + echo "\nDone"; + } + + public function generate_uadpost_from_json($json_data) { + $uadpost_data = json_decode($json_data); + + $rand_user = app() -> factory -> getter() -> get_user_by("id", rand(1, 9999)); + + $images = new Images(); + if($uadpost_data -> image and strlen($uadpost_data -> image)) { + echo "Upload image " . $uadpost_data -> image . "\n"; + $img = @file_get_contents($uadpost_data -> image); + if($img) { + $img = (new Utils()) -> convert_png_to_jpg($img); + $img = "data:image/jpeg;base64," . base64_encode($img); + $img_upload_result = $images -> upload($img); + } + } + + echo "Creating UAdPost\n"; + $uadpost = app() -> factory -> creator() -> create_uadpost( + $rand_user -> id(), + $uadpost_data -> title, + $uadpost_data -> description, + rand(1, 2), + rand(0, 1), + $uadpost_data -> price, + $uadpost_data -> currency, + rand(400000, 600000) / 10000, + rand(220000, 300000) / 10000, + "Ukraine", + "Украина", + "TestRegion", + "ТестРегион", + "TestCity", + "ТестГород", + $img_upload_result ? 1 : 0 + ); + + if($uadpost and $img_upload_result) { + $images -> create_from_aliases( + [ $img_upload_result["alias"] ], + $uadpost, + $rand_user -> id() + ); + } + + echo "Was created \n"; + } +} \ No newline at end of file diff --git a/server/SHServ/Helpers/GetSetImplementation.php b/server/SHServ/Helpers/GetSetImplementation.php new file mode 100644 index 0000000..966d22c --- /dev/null +++ b/server/SHServ/Helpers/GetSetImplementation.php @@ -0,0 +1,39 @@ + data; + } + + public function get(String $field_name) { + if(in_array($field_name, static::$fields)) { + return $this -> data[$field_name]; + } + + throw new \Exception("Error of GET, field `{$field_name}` not found"); + } + + public function set(String $field_name, $field_val) { + if(!in_array($field_name, static::$fields)){ + throw new \Exception("Error of SET, field `{$field_name}` not found"); + } + + $this -> data[$field_name] = $field_val; + $this -> modified_fields[$field_name] = $field_val; + return $this; + } + + public function __get($field_name) { + return $this -> get($field_name); + } + + public function __set($field_name, $field_val) { + return $this -> set($field_name, $field_val); + } +} diff --git a/server/SHServ/Helpers/PetInstancesImplementation.php b/server/SHServ/Helpers/PetInstancesImplementation.php new file mode 100644 index 0000000..180986a --- /dev/null +++ b/server/SHServ/Helpers/PetInstancesImplementation.php @@ -0,0 +1,23 @@ + pet_instances[$instance_name])) { + $this -> pet_instances[$instance_name] = $callback(); + } + + return $this -> pet_instances[$instance_name]; + } + + public function forward_instance_init(String $instance_name, $instance) { + $this -> pet_instances[$instance_name] = $instance; + } + + public function get_existing_pet_list() { + return array_keys($this -> pet_instances); + } +} diff --git a/server/SHServ/Helpers/Validator.php b/server/SHServ/Helpers/Validator.php new file mode 100644 index 0000000..369c23f --- /dev/null +++ b/server/SHServ/Helpers/Validator.php @@ -0,0 +1,7 @@ + utils; + } +} \ No newline at end of file diff --git a/server/SHServ/Middleware/Entity.php b/server/SHServ/Middleware/Entity.php new file mode 100644 index 0000000..3746160 --- /dev/null +++ b/server/SHServ/Middleware/Entity.php @@ -0,0 +1,91 @@ + entity_tablename = $entity_tablename; + $this -> entity_id = $entity_id; + + if(count($data)) { + $this -> fill($data); + } + } + + public function fill(Array $data = []) { + if(count($data)) { + $this -> data = $data; + } else { + $this -> select_from_db(); + } + + $this -> was_filled = true; + } + + protected function select_from_db() { + list($this -> data) = $this -> thin_builder() -> select( + $this -> entity_tablename, + [], + ['id', '=', $this -> entity_id], + ['id'], + 'DESC', + [0, 1] + ); + } + + public function get(String $field_name): Mixed { + if(!$this -> was_filled()) { + $this -> fill(); + } + + return $this -> parent_get($field_name); + } + + public function was_filled(): Bool { + return $this -> was_filled; + } + + public function thin_builder(): \Fury\Modules\ThinBuilder\ThinBuilder { + return app() -> thin_builder; + } + + public function id(): Int { + return $this -> entity_id; + } + + public function update(): Array|Bool { + if(!count($this -> modified_fields)){ + return []; + } + + $where = [ ["id", "=", $this -> entity_id] ]; + $this -> modified_fields[$this -> field_name_of_update_at] = date("Y-m-d H:i:s"); + + if(!$this -> thin_builder() -> update($this -> entity_tablename, $this -> modified_fields, $where)) { + return false; + } + + $result = $this -> modified_fields; + $this -> modified_fields = []; + return $result; + } + + public static function get_fields(): Array { + return static::$fields; + } + + protected function remove_entity() { + return app() -> thin_builder -> delete(static::$table_name, [ "id", "=", $this -> id() ]); + } +} \ No newline at end of file diff --git a/server/SHServ/Middleware/Model.php b/server/SHServ/Middleware/Model.php new file mode 100644 index 0000000..7b9b777 --- /dev/null +++ b/server/SHServ/Middleware/Model.php @@ -0,0 +1,26 @@ + devtools -> using_model(get_class($this)); + } + + public function utils(){ + if(!$this -> utils_ins){ + $this -> utils_ins = new \SHServ\Utils(); + } + + return $this -> utils_ins; + } + + public function thin_builder(){ + return app() -> thin_builder; + } +} \ No newline at end of file diff --git a/server/SHServ/Models/Example_Auth.php b/server/SHServ/Models/Example_Auth.php new file mode 100644 index 0000000..5a54fb3 --- /dev/null +++ b/server/SHServ/Models/Example_Auth.php @@ -0,0 +1,41 @@ + factory -> creator() -> create_user( + app() -> utils -> gen_alias_from_email($email), + $email, + $password + ); + + if($user) { + $profile = app() -> factory -> creator() -> create_profile($user -> id()); + } + + return $user; + } + + public function signin(String $email, String $password) { + $password = sha1($password); + $user = app() -> factory -> getter() -> get_user_by("email", $email); + + if(!$user or $user -> get("password") != $password) { + return false; + } + + return app() -> sessions -> init_session($user -> id()); + } + + public function signout() { + return app() -> sessions -> close_current_session(); + } + + public function remove_session(Int $uid) { + + } +} \ No newline at end of file diff --git a/server/SHServ/Routes.php b/server/SHServ/Routes.php new file mode 100644 index 0000000..8a5e7c6 --- /dev/null +++ b/server/SHServ/Routes.php @@ -0,0 +1,120 @@ + router = $router; + $this -> cf = FCONF["controllers_folder"]; + $this -> cn = "\\" . FCONF["app_name"] . "\\" . FCONF["controllers_folder"]; + } + + public function routes_init() { + $this -> uri_routes(); + $this -> get_routes(); + $this -> post_routes(); + } + + protected function uri_routes() { + // pages + // $this -> router -> uri("/", "{$this -> cn}\\SearchController@search_page"); + // $this -> router -> uri('/not-found.html', "{$this -> cn}\\InfoPagesController@not_found_page"); + + // $this -> router -> uri('/uadpost/$alias', "{$this -> cn}\\UAdPostController@view_page"); + + + // $this -> router -> uri( + // '/profile/orders/$utype/exclude-states', + // function($args) { + // return app() -> utils -> redirect( + // app() -> routes -> urlto("OrderController@orders_cur_user_page", ["utype" => $args["utype"]]) + // ); + // } + // ); + + } + + protected function get_routes() { + // $this -> router -> get( + // [ "uadpost_id", "state" ], + // "{$this -> cn}\\UAdPostController@change_uadpost_state", + // "/profile/uadposts/change-state.html" + // ); + } + + protected function post_routes() { + $this -> router -> post( + [ "email", "password", "password_again" ], + "{$this -> cn}\\AuthController@signup", + "/auth/signup" + ); + } + + /** + * urlto, get url by action name [with arguments] + * @var String $action_name - Action name, like a "HelloController@world_action" + * @var Array $url_args - Assoc array with arguments (ONLY FOR REQUEST TYPE GET) + * + * @return String Url to action, ready for use + */ + public function urlto(String $action_name, Array $url_args = []) { + $routes_map = $this -> router -> get_routes_map(); + $desired_action = "{$this -> cn}\\{$action_name}"; + foreach($routes_map["uri"] as $url => $action) { + if($action == $desired_action) { + foreach($url_args as $arg_name => $arg_val) { + $url = str_replace("\${$arg_name}", $arg_val, $url); + } + + return $url; + } + } + + foreach($routes_map["post"] as $url_pattern => $action){ + if($action == $desired_action) { + list($url) = explode("?", $url_pattern); + return $url; + } + } + + foreach($routes_map["get"] as $url_pattern => $action){ + if($action == $desired_action) { + list($url, $param_names) = explode("?", $url_pattern); + if(count($url_args)) { + $param_names = explode("&", $param_names); + $params = array_flip($param_names); + foreach($params as $key => $val) { + if(!isset($url_args[$key])) { + continue; + } + + $params[$key] = $url_args[$key]; + } + }else{ + $params = []; + } + + return $url . "?" . http_build_query($params); + } + } + } +} \ No newline at end of file diff --git a/server/SHServ/Sessions.php b/server/SHServ/Sessions.php new file mode 100644 index 0000000..a877800 --- /dev/null +++ b/server/SHServ/Sessions.php @@ -0,0 +1,109 @@ + thin_builder -> insert($this -> table_name, [ + "uid" => $uid, + "token" => $token, + "create_at" => date("Y-m-d H:i:s") + ]); + + return $result ? $token : false; + } + + public function close($token) { + $session = $this -> get_session_by_token($token); + if(!$session) { + return false; + } + + $session -> set("state", 2); + return $session -> update(); + } + + public function close_current_session() { + return $this -> close($this -> get_auth_token()); + } + + public function set_session(String $token) { + setcookie("auth_token", $token, time() + 3600 * 24 * 30, "/"); + } + + public function init_session(Int $uid) { + $token = $this -> create($uid); + + if($token){ + $this -> set_session($token); + } + + return $token; + } + + public function is_auth() { + return $this -> get_current_session() ? true : false; + } + + public function get_auth_token() { + return isset($_COOKIE["auth_token"]) ? $_COOKIE["auth_token"] : null; + } + + public function auth_user() { + if(!$this -> get_auth_token()) { + return null; + } + + if(!$this -> auth_user_instance) { + $session = $this -> get_current_session(); + if(!$session){ + return null; + } + + $this -> auth_user_instance = new User($session -> get("uid")); + } + + return $this -> auth_user_instance; + } + + public function get_current_session() { + if(!$this -> current_session_instance){ + $token = $this -> get_auth_token(); + if(!$token) { + return null; + } + + $this -> current_session_instance = $this -> get_session_by_token($token); + if($this -> current_session_instance){ + $this -> current_session_instance -> set("last_using_at", date("Y-m-d H:i:s")) -> update(); + } + } + + return $this -> current_session_instance; + } + + public function get_session_by_token(String $token) { + $result = app() -> thin_builder -> select( + Session::$table_name, + Session::get_fields(), + [ + ["token", "=", $token], + "AND", + ["state", "=", 1] + ] + ); + + if(!$result) { + return null; + } + + return new Session(intval($result[0]["id"]), $result[0]); + } +} \ No newline at end of file diff --git a/server/SHServ/Utils.php b/server/SHServ/Utils.php new file mode 100644 index 0000000..6d8fe4d --- /dev/null +++ b/server/SHServ/Utils.php @@ -0,0 +1,230 @@ + count($tablename, [ [$field_name, "=", $value] ]) ? true : false; + } + + public function response_error(String $error_alias, Array $failed_fields = [], Array $extra = []) { + return json_encode(array_merge([ + "status" => false, + "error_alias" => $error_alias, + "failed_fields" => $failed_fields, + "msg" => $this -> get_msg_by_alias($error_alias) + ], $extra)); + } + + public function response_success(Array $resp_data = []) { + return json_encode([ + "status" => true, + "data" => $resp_data + ]); + } + + public function get_msg_by_alias(String $alias){ + return FCONF['text_msgs'][$alias]; + } + + public function compress_image(String $source, String $destination, Int $quality) { + $info = getimagesize($source); + + if ($info['mime'] == 'image/jpeg') + $image = imagecreatefromjpeg($source); + elseif ($info['mime'] == 'image/gif') + $image = imagecreatefromgif($source); + elseif ($info['mime'] == 'image/png') + $image = imagecreatefrompng($source); + + imagejpeg($image, $destination, $quality); + + return $destination; + } + + public function image_resize(String $file_name, String $output, Int $quality, Int $width, $height = 0) { + list($wid, $ht) = \getimagesize($file_name); + $r = $wid / $ht; + $height = $height ? $height : $width / $r; + + if ($width / $height > $r) { + $new_width = $height * $r; + $new_height = $height; + } else { + $new_height = $width / $r; + $new_width = $width; + } + + $source = \imagecreatefromjpeg($file_name); + $dst = \imagecreatetruecolor($new_width, $new_height); + \imagecopyresampled($dst, $source, 0, 0, 0, 0, $new_width, $new_height, $wid, $ht); + \imagejpeg($dst, $output, $quality); + } + + public function transliterate_cyr_lat(String $str) { + $cyr = [ + 'Љ','Њ','Џ','џ','ш','ђ','ч','ћ','ж','љ','њ','Ш','Ђ','Ч','Ћ', + 'Ж','Ц','ц','а','б','в','г','д','е','ё','ж','з','и','й','к','л','м','н', + 'о','п', 'р','с','т','у','ф','х','ц','ч','ш','щ','ъ','ы','ь','э','ю','я', + 'А','Б','В','Г','Д','Е','Ё','Ж','З','И','Й','К','Л','М','Н','О','П','Р', + 'С','Т','У','Ф','Х','Ц','Ч','Ш','Щ','Ъ','Ы','Ь','Э','Ю','Я','Є','є', + 'Ї','ї','і' + ]; + + $lat = [ + 'Lj','Nj','Dž','dž','š','đ','č','ć','ž','lj','nj','Š','Đ','Č','Ć','Ž','C','c', + 'a','b','v','g','d','e','io','zh','z','i','y','k','l','m','n','o','p', 'r','s', + 't','u','f','h','ts','ch','sh','sht','a','i','y','e','yu','ya', 'A','B','V', + 'G','D','E','Io','Zh','Z','I','Y','K','L','M','N','O','P','R','S','T','U','F', + 'H','Ts','Ch','Sh','Sht','A','I','Y','e','Yu','Ya','Ye','ye','Yi','yi','i', + ]; + + return str_replace($cyr, $lat, $str); + } + + public function gen_from_text_alias(String $str) { + return str_replace( + [" ", ".", ",", "@", "!", "#", '$', "%", "^", "&", "?", "*", "(", ")", "+", "[", "]", "{", "}", ":", ";", "/", "<", ">", "\\"], + ["-", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""], + $this -> transliterate_cyr_lat(strtolower($str)) + ); + } + + public function get_current_page_num(): Int { + return max(1, intval(isset($_GET["pn"]) ? $_GET["pn"] : 0)); + } + + public function get_limits_for_select_query(Int $per_page): Array { + $current_page = $this -> get_current_page_num(); + $from = ($current_page - 1) * $per_page; + return [$from, $per_page]; + } + + public function lang_mistake_flip(String $str) { + $str = str_replace( + ["{", "}", "!", "@", "#", '$', "%", "^", "&", "*", "(", ")"], + ["", "", "", "", "", '$', "", "", "", "", "", ""], + $str + ); + $vocabluary_lat = "`qwertyuiop[]asdfghjkl;'zxcvbnm,. {}<>-+_1234567890"; + $vocabluary_cyr = "ёйцукенгшщзхъфывапролджэячсмитьбю хъбю-+_1234567890"; + + $len = mb_strlen($str); + $new_str = ""; + for($i = 0; $i < $len; $i++) { + $in_lat = mb_strpos($vocabluary_lat, mb_substr($str, $i, 1)); + $in_cyr = mb_strpos($vocabluary_cyr, mb_substr($str, $i, 1)); + + if($in_lat !== false) { + $new_str .= mb_substr($vocabluary_cyr, $in_lat, 1); + continue; + } + + if($in_cyr !== false) { + $new_str .= mb_substr($vocabluary_lat, $in_cyr, 1); + continue; + } + + $new_str .= $str[$i]; + } + + return $new_str; + } + + public function get_default_val_for_type(String $type) { + $default_val = null; + $types_default_vals = [ + "Int" => 0, + "String" => "", + "JSON" => "{}", + "Float" => 0 + ]; + + return $types_default_vals[$type]; + } + + public function link_is_active(String $action, Array $params = []) { + return app() -> routes -> urlto($action, $params) == app() -> router -> uri; + } + + public function formatted_timestamp(String $timestamp, $with_clock = false): String { + if($with_clock) { + return date("d.m.Y H:i", strtotime($timestamp)); + } + + return date("d.m.Y", strtotime($timestamp)); + } + + public function get_delivery_method_map() { + return [ + 1 => "Новая почта", + 2 => "Укр почта", + 3 => "Самовивоз", + 4 => "Другое", + ]; + } + + public function convert_price_to_uah_from(String $currency, Float $price): Float { + if($currency == "UAH") { + return $price; + } + + $timestamp = date("Ymd"); + $api_request = "https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?valcode={$currency}&date={$timestamp}&json"; + $api_resp = file_get_contents($api_request); + if(!$api_resp) { + return 0; + } + + $resp = json_decode($api_resp, true); + return $resp[0]["rate"] * $price; + } + + public function convert_png_to_jpg($png_data) { + $png_image = imagecreatefromstring($png_data); + $jpg_image = imagecreatetruecolor(imagesx($png_image), imagesy($png_image)); + + imagecopy($jpg_image, $png_image, 0, 0, 0, 0, imagesx($png_image), imagesy($png_image)); + + ob_start(); + imagejpeg($jpg_image, NULL, 100); + $jpg_data = ob_get_contents(); + ob_end_clean(); + + imagedestroy($png_image); + imagedestroy($jpg_image); + + return $jpg_data; + } + + public function dayname_translate(String $dayname, String $lang = "ru"): ?String { + $days = [ + ["en" => "monday", "ru" => "понедельник", "uk" => "понеділок"], + ["en" => "tuesday", "ru" => "вторник", "uk" => "вівторок"], + ["en" => "wednesday", "ru" => "среда", "uk" => "середа"], + ["en" => "thursday", "ru" => "четверг", "uk" => "четвер"], + ["en" => "friday", "ru" => "пятница", "uk" => "п'ятниця"], + ["en" => "saturday", "ru" => "суббота", "uk" => "субота"], + ["en" => "sunday", "ru" => "воскресенье", "uk" => "неділя"] + ]; + + $dayname = strtolower($dayname); + + foreach($days as $day) { + if($day["en"] == $dayname) { + return $day[$lang]; + } + } + + return null; + } +} \ No newline at end of file diff --git a/server/SHServ/config.php b/server/SHServ/config.php new file mode 100644 index 0000000..1d7ddb6 --- /dev/null +++ b/server/SHServ/config.php @@ -0,0 +1,27 @@ + "SHServ", + "debug" => true, + "default_db_wrap" => false, + "db" => [ + "dblib" => "mysql", + "host" => "localhost", + "dbname" => "smart-home-serv", + "charset" => "utf8", + "user" => "eugene", + "password" => "root" + ], + "app_file" => "App.php", + "templates_folder" => "Templates", + "logs_enable" => true, + "logs_folder" => "SHServ/Logs", + "devmode" => true, + + "controllers_folder" => "Controllers", + "text_msgs" => require_once("SHServ/text-msgs.php"), + + "error_handler" => [ + "important_errors" => ["E_WARNING", "E_ERROR", "E_CORE_ERROR", "EXCEPTION"] + ], +]; \ No newline at end of file diff --git a/server/SHServ/text-msgs.php b/server/SHServ/text-msgs.php new file mode 100644 index 0000000..8e28078 --- /dev/null +++ b/server/SHServ/text-msgs.php @@ -0,0 +1,60 @@ + text message + */ + +return [ + // Errors + "incorrect_email" => "Не корректный E-mail", + "too_short_password" => "Слишком короткий пароль", + "different_passwords" => "Пароли не совпадают", + "email_already_exists" => "Такой E-mail уже существует", + "undefined_error" => "Ой, что-то пошло не так", + "empty_field" => "Поле не может быть пустым", + "unregistered_email" => "Такой E-mail не зарегистрирован", + "incorrect_password" => "Не верный пароль", + "not_found_any_sessions" => "Требуется войти в систему", + "already_logged" => "Вы уже в системе", + "error_of_img_upload" => "Ошибка загрузки изображения", + "title_too_short" => "Слишком короткое название", + "price_not_specified" => "Укажите цену", + "location_not_specified" => "Укажите местоположение, не обязательно точное", + "disagree_with_rules" => "Если Вы не согласны с правилами публикации, Вы не можете добавить объявление", + "empty_first_name" => "Укажите Ваше имя, это обязательно", + "empty_second_name" => "Укажите Вашу имя, это обязательно", + "empty_patronymic" => "Укажите Ваше отчество", + "empty_phone_number" => "Укажите контактный номер телефона", + "unlogged_user" => "Сначала нужно войти", + "fail_creating_uadpost" => "Ошибка создания объявления", + "textfield_too_large" => "Превышен лимит количества символов", + "fail_publishing_uadpost" => "Ошибка публикации объявления", + "uadpost_not_exist" => "Такое объявление не существует", + "server_not_available" => "Сервер не доступен", + "uadpost_no_available" => "Объявление больше не доступно", + "price_was_changed" => "Цена была изменена", + "fail_creating_order" => "Не удалось создать запрос покупки", + "fail_access_to_order" => "Не удалось получить доступ к заказу", + "selected_state_not_exists" => "Выбраного состояния не существует", + "uncorrect_delivery_method" => "Укажите метод доставки", + "np_fail_of_department_number" => "Укажите номер отделения или поштомата", + "np_fail_of_selected_city" => "Выберите населённый пункт", + + // Other + "accept_removing" => "Подтвердите удаление", + "remove" => "Удалить", + "cancel" => "Отмена", + "deactivate_selected_uadpost" => "Деактивировать выбранное объявление?", + "deactivate" => "Деактивировать", + "publishing_selected_uadpost" => "Опубликовать выбранное объявление?", + "publishing" => "Опубликовать", + "terms_of_use_not_selected" => "Пользовательское соглашение не выбрано", + "success_and_redirecting" => "Успешно! Перенаправление...", + "accept" => "Принять", + "confirm" => "Подтвердить", + "confirmed" => "Успешно подтверждено", + "canceled" => "Успешно отменено", + "cancel_order" => "Отменить заказ", + "completed" => "Успешно завершено", + "complete_order" => "Заказ выполнен", +]; \ No newline at end of file diff --git a/server/console.php b/server/console.php new file mode 100644 index 0000000..78e6806 --- /dev/null +++ b/server/console.php @@ -0,0 +1,30 @@ + generate_random_users($argv[2]); + break; + case "generator.uadposts": + (new Generator()) -> generate_random_uadpost($argv[2]); + break; + case "create.uadpost": + (new Generator()) -> generate_uadpost_from_json($argv[2]); + break; + case "get.config": + echo json_encode(FCONF); + break; + default: echo "\nNo command"; + } + + echo "\n"; +} + +console(); \ No newline at end of file diff --git a/server/index.php b/server/index.php new file mode 100644 index 0000000..d2b918f --- /dev/null +++ b/server/index.php @@ -0,0 +1,5 @@ +