/** * Initializing i18n * * @param array $options */ public static function init($options = []) { $i18n = application::get('flag.global.i18n') ?? []; $i18n = array_merge_hard($i18n, $options ?? []); // determine final language $languages = factory::model('numbers_backend_i18n_languages_model_languages')->get(); $final_language = application::get('flag.global.__language_code') ?? session::get('numbers.entity.format.language_code') ?? $i18n['language_code'] ?? 'sys'; if (empty($languages[$final_language])) { $final_language = 'sys'; $i18n['rtl'] = 0; } // put settings into system if (!empty($languages[$final_language])) { foreach ($languages[$final_language] as $k => $v) { $k = str_replace('lc_language_', '', $k); if (in_array($k, ['code', 'inactive'])) { continue; } if (empty($v)) { continue; } $i18n[$k] = $v; } } $i18n['language_code'] = $final_language; self::$options = $i18n; session::set('numbers.entity.format.language_code', $final_language); application::set('flag.global.i18n', $i18n); self::$initialized = true; // initialize the module return factory::submodule('flag.global.i18n.submodule')->init($i18n); }
/** * Add library to the application * * @param string $library */ public static function add($library) { $connected = application::get('flag.global.library.' . $library . '.connected'); if (!$connected) { factory::submodule('flag.global.library.' . $library . '.submodule')->add(); application::set('flag.global.library.' . $library . '.connected', true); } }
/** * Draw captcha * * @param string $word * @param array $options */ public function draw($word, $options = []) { $width = !empty($options['width']) ? $options['width'] : 150; $height = !empty($options['height']) ? $options['height'] : 50; $word = $word . ''; // create new image $image = imagecreatetruecolor($width, $height); imagefilledrectangle($image, 0, 0, $width, $height, imagecolorallocate($image, 255, 255, 255)); // draw random lines for ($i = 0; $i < 10; $i++) { $color = imagecolorallocate($image, rand() % 255, rand() % 255, rand() % 255); imageline($image, 0, rand() % $height, $width, rand() % $height, $color); } // draw random pixels for ($i = 0; $i < 500; $i++) { $color = imagecolorallocate($image, rand() % 255, rand() % 255, rand() % 255); imagesetpixel($image, rand() % $width, rand() % $height, $color); } // drawing text $len = strlen($word); $x_start = 5; $x_len = ($width - $x_start * 2) / $len; $y_start = 5; $y_end = $height - 5; for ($i = 0; $i < $len; $i++) { $color = imagecolorallocate($image, rand() % 100, rand() % 100, rand() % 100); $font_size = rand(16, 24); $x = $x_start + $x_len * $i; $y = rand($y_start + $font_size, $y_end); $angle = rand(-30, 30); imagettftext($image, $font_size, $angle, $x, $y, $color, __DIR__ . '/fonts/arial.ttf', $word[$i]); } // returning image if (!empty($options['return_image'])) { ob_start(); imagepng($image); imagedestroy($image); return ob_get_clean(); } else { // output image, important to set content type in application application::set('flag.global.__content_type', 'image/png'); header("Content-type: image/png"); imagepng($image); imagedestroy($image); exit; } }
/** * Initialize db connections, cache and session */ public static function init($options = []) { // initialize mbstring mb_internal_encoding('UTF-8'); mb_regex_encoding('UTF-8'); // get flags & dependencies $flags = application::get('flag'); $backend = application::get('numbers.backend', ['backend_exists' => true]); // processing wildcard first $wildcard = application::get('wildcard'); $wildcard_keys = null; if (!empty($wildcard['enabled']) && !empty($wildcard['model'])) { $wildcard_keys = call_user_func($wildcard['model']); application::set(['wildcard', 'keys'], $wildcard_keys); } // initialize cryptography $crypt = application::get('crypt'); if (!empty($crypt) && $backend) { foreach ($crypt as $crypt_link => $crypt_settings) { if (!empty($crypt_settings['submodule']) && !empty($crypt_settings['autoconnect'])) { $crypt_object = new crypt($crypt_link, $crypt_settings['submodule'], $crypt_settings); } } } // create database connections $db = application::get('db'); if (!empty($db) && $backend) { foreach ($db as $db_link => $db_settings) { if (empty($db_settings['autoconnect']) || empty($db_settings['servers']) || empty($db_settings['submodule'])) { continue; } $connected = false; foreach ($db_settings['servers'] as $server_key => $server_values) { $db_object = new db($db_link, $db_settings['submodule']); // wildcards replaces if (isset($wildcard_keys[$db_link])) { $server_values['dbname'] = $wildcard_keys[$db_link]['dbname']; } // connecting $server_values = array_merge2($server_values, $db_settings); $db_status = $db_object->connect($server_values); if ($db_status['success'] && $db_status['status']) { $connected = true; break; } } // checking if not connected if (!$connected) { throw new Exception('Unable to open database connection!'); } } } // initialize cache $cache = application::get('cache'); if (!empty($cache) && $backend) { foreach ($cache as $cache_link => $cache_settings) { if (empty($cache_settings['submodule']) || empty($cache_settings['autoconnect'])) { continue; } $connected = false; foreach ($cache_settings['servers'] as $cache_server) { $cache_object = new cache($cache_link, $cache_settings['submodule']); $cache_status = $cache_object->connect($cache_server); if ($cache_status['success']) { $connected = true; break; } } // checking if not connected if (!$connected) { throw new Exception('Unable to open cache connection!'); } } } // if we are from command line we exit here if (!empty($options['__run_only_bootstrap'])) { return; } // initialize session $session = application::get('flag.global.session'); if (!empty($session['start']) && $backend && !application::get('flag.global.__skip_session')) { session::start(isset($session['options']) ? $session['options'] : []); } // we need to get overrides from session and put them back to flag array $flags = array_merge_hard($flags, session::get('numbers.flag')); application::set('flag', $flags); // initialize i18n if ($backend) { $temp_result = i18n::init(); if (!$temp_result['success']) { throw new Exception('Could not initialize i18n.'); } } // format format::init(); // including libraries that we need to auto include if (!empty($flags['global']['library'])) { foreach ($flags['global']['library'] as $k => $v) { // we need to skip certain keys if ($k == 'submodule' || $k == 'options') { continue; } // we only include if autoconnect is on if (!empty($v['autoconnect'])) { factory::submodule('flag.global.library.' . $k . '.submodule')->add(); } } } // check if we need to include system files from frontend if (application::get('dep.submodule.numbers.frontend.system')) { numbers_frontend_system_model_base::start(); } }
/** * Set variable into i18n * * @param string $variable * @param mixed $value */ public static function set($variable, $value) { application::set('flag.global.i18n.' . $variable, $value); }
public static function process($options = []) { // start buffering helper_ob::start(true); $controller_class = self::$settings['mvc']['controller_class']; // if we are handling error message and controller class has not been loaded if ($controller_class == 'controller_error' && error_base::$flag_error_already && !class_exists('controller_error')) { require './controller/error.php'; } $controller = new $controller_class(); // processing options if (!empty($options)) { foreach ($options as $k => $v) { $controller->{$k} = $v; } } // put action into controller $controller->action = ['code' => self::$settings['mvc']['controller_action_code'], 'full' => self::$settings['mvc']['controller_action']]; // check ACL if ($controller_class != 'controller_error') { helper_acl::merge_data_with_db($controller, self::$settings['mvc']['controller_class']); if (helper_acl::can_be_executed($controller, true) == false) { throw new Exception('Permission denied!', -1); } } else { // important to unset controller data application::set('controller', null); } // auto populating input property in controller if (!empty(self::$settings['application']['controller']['input'])) { $controller->input = request::input(null, true, true); } // init method if (method_exists($controller, 'init')) { call_user_func(array($controller, 'init')); } // check if action exists if (!method_exists($controller, $controller->action['full'])) { throw new Exception('Action does not exists!'); } // calling action echo call_user_func(array($controller, $controller->action['full'])); // auto rendering view only if view exists, processing extension order as specified in .ini file $temp_reflection_obj = new ReflectionClass($controller); $controller_dir = pathinfo($temp_reflection_obj->getFileName(), PATHINFO_DIRNAME) . '/'; $controller_file = end(self::$settings['mvc']['controllers']); $view = self::$settings['mvc']['controller_view']; $flag_view_found = false; if (!empty($view)) { $extensions = explode(',', isset(self::$settings['application']['view']['extension']) ? self::$settings['application']['view']['extension'] : 'html'); foreach ($extensions as $extension) { $file = $controller_dir . $controller_file . '.' . $view . '.' . $extension; if (file_exists($file)) { $controller = new view($controller, $file, $extension); $flag_view_found = true; break; } } // if views are mandatory if (!empty(self::$settings['application']['view']['mandatory']) && !$flag_view_found) { throw new Exception('View ' . $view . ' does not exists!'); } } // autoloading media files layout::include_media($controller_dir, $controller_file, $view, $controller_class); // appending view after controllers output $controller->view = ($controller->view ?? '') . helper_ob::clean(); // if we have to render debug toolbar if (debug::$toolbar) { helper_ob::start(); } // call pre rendering method in bootstrap bootstrap::pre_render(); // rendering layout $__skip_layout = application::get('flag.global.__skip_layout'); if (!empty(self::$settings['mvc']['controller_layout']) && empty($__skip_layout)) { helper_ob::start(); if (file_exists(self::$settings['mvc']['controller_layout_file'])) { $controller = new layout($controller, self::$settings['mvc']['controller_layout_file'], self::$settings['mvc']['controller_layout_extension']); } // session expiry dialog before replaces session::expiry_dialog(); // buffer output and handling javascript files, chicken and egg problem $from = ['<!-- [numbers: messages] -->', '<!-- [numbers: title] -->', '<!-- [numbers: document title] -->', '<!-- [numbers: actions] -->', '<!-- [numbers: breadcrumbs] -->', '<!-- [numbers: javascript links] -->', '<!-- [numbers: javascript data] -->', '<!-- [numbers: css links] -->', '<!-- [numbers: layout onload] -->', '<!-- [numbers: layout onhtml] -->']; $to = [layout::render_messages(), layout::render_title(), layout::render_document_title(), layout::render_actions(), layout::render_breadcrumbs(), layout::render_js(), layout::render_js_data(), layout::render_css(), layout::render_onload(), layout::$onhtml]; echo str_replace($from, $to, helper_ob::clean()); } else { echo $controller->view; } // ajax calls that has not been processed by application if (application::get('flag.global.__ajax')) { layout::render_as(['success' => false, 'error' => [i18n(null, 'Could not process ajax call!')]], 'application/json'); } }
/** * Validate if controller can be executed * * @param object $controller_object * @return boolean */ public static function can_be_executed(&$controller_object, $redirect = false) { $authorized = session::get(['numbers', 'authorized']); // authorized if ($authorized) { // see if controller is for authorized if (empty($controller_object->acl['authorized'])) { return false; } // permissions if (!empty($controller_object->acl['permission'])) { if (self::$permissions == null) { self::handle_permissions(); } // admin account can see everything if (self::$flag_admin) { // we need to put permission into controller $permission_list = []; foreach ($controller_object->actions['by_id'] as $k => $v) { $permission_list[$k] = true; } application::set(['controller', 'acl', 'permissions'], $permission_list); return true; } // see if we have this action code registered if (empty($controller_object->actions['by_code'][$controller_object->action['code']])) { return false; } // check if we have access to the controller if (empty($controller_object->controller_id) || empty(self::$permissions[$controller_object->controller_id])) { return false; } // if we have action $all_actions = []; foreach (self::$permissions[$controller_object->controller_id] as $k => $v) { if ($v == true) { $all_actions[] = $k; } } $merged = array_intersect($all_actions, $controller_object->actions['by_code'][$controller_object->action['code']]); if (empty($merged)) { return false; } // we need to put permission into controller application::set(['controller', 'acl', 'permissions'], self::$permissions[$controller_object->controller_id]); } } else { // we need to redirect to login controller if not authorized if ($redirect && !empty($controller_object->acl['authorized']) && empty($controller_object->acl['public']) && !application::get('flag.global.__skip_session')) { request::redirect(application::get('flag.global.authorization.login.controller')); } // public permission if (empty($controller_object->acl['public'])) { return false; } } return true; }
/** * Include all media files for controller * * @param string $path * @param string $controller * @param string $view * @param string $class */ public static function include_media($path, $controller, $view, $class) { // generating a list of extensions $valid_extensions = ['js', 'css']; if (application::get('dep.submodule.numbers.frontend.media.scss')) { $valid_extensions[] = 'scss'; } // we need to fix path for submodules $path_fixed = str_replace('/', '_', $path); $path_js = str_replace('_' . $controller, '', $class) . '_'; if (substr($path, 0, 8) == 'numbers/') { $path = '../libraries/vendor/' . $path; } //$path = application::get(['application', 'path_full']) . $path; // build an iterator $iterator = new FilesystemIterator($path); $filter = new RegexIterator($iterator, '/' . $controller . '(.' . $view . ')?.(' . implode('|', $valid_extensions) . ')$/'); $file_list = []; // iterating foreach ($filter as $v) { $temp = $v->getFilename(); $extension = pathinfo($temp, PATHINFO_EXTENSION); // we need to sort in a way that view files are included second if ($controller . '.' . $extension == $temp) { $sort = 1000; } else { $sort = 2000; } $new = '/numbers/media_generated/application_' . $path_js . $temp; if ($extension == 'js') { self::add_js($new, $sort); } else { if ($extension == 'css') { self::add_css($new, $sort); } else { if ($extension == 'scss') { $new .= '.css'; self::add_css($new, $sort); } } } // adding media files to application for further reporting application::set(['application', 'loaded_classes', $class, 'media'], ['file' => $temp, 'full' => $new], ['append' => true]); } }