/** * Process options * * @param string $model_and_method - model::method * @param object $existing_object * @param array $where * @param array $existing_values * @param array $skip_values * @param array $options * @return array */ public static function process_options($model_and_method, $existing_object = null, $where = [], $existing_values = [], $skip_values = [], $options = []) { // put changes into options $options['where'] = array_merge_hard($options['where'] ?? [], $where); $options['existing_values'] = $existing_values; $options['skip_values'] = $skip_values; // see if we have cached version $hash = sha1($model_and_method . serialize($options)); if (isset(self::$cached_options[$hash])) { return self::$cached_options[$hash]; } else { $temp = explode('::', $model_and_method); if (count($temp) == 1) { $model = $temp[0]; $method = 'options'; } else { $model = $temp[0]; $method = $temp[1]; } if ($model == 'this' && !empty($existing_object)) { $object = $existing_object; } else { $object = factory::model($model, true); } self::$cached_options[$hash] = $object->{$method}($options); return self::$cached_options[$hash]; } }
/** * 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); }
/** * Process */ public function get() { $result = []; foreach ($this->data as $k => $v) { $model = new $v(); $result = array_merge_hard($result, [$k => $model->get()]); } return $result; }
/** * Render field * * @param array $field * @param string $key * @param boolean $flag_second * @param array $input * @return string */ public static function render_column($field, $key, $flag_second = false, $input = []) { $field['method'] = $field['method'] ?? 'html::input'; $options = ['id' => 'filter_' . $key . ($flag_second ? '2' : ''), 'name' => 'filter[' . $key . ($flag_second ? '2' : '') . ']', 'value' => $input['filter'][$key . ($flag_second ? '2' : '')] ?? null]; $options = array_merge_hard($field, $options); if (!empty($field['options_model'])) { $params = $field['options_params'] ?? []; $options['options'] = factory::model($field['options_model'])->options(['where' => $params, 'i18n' => true]); } return call_user_func_array(explode('::', $field['method']), [$options]); }
/** * Delegate arguments to submodule * * @param string $flag * @param string $submodule * @param array $arguments * @return mixed */ public static function delegate($flag, $submodule, $arguments) { $options = application::get($flag . '.' . $submodule . '.options'); if (!empty($options)) { // todo: maybe add to first array instead to first element in arguments $arguments[0] = array_merge_hard($options, $arguments[0]); } // we need to determine whether we need to use additional submodule if (application::get($flag . '.' . $submodule . '.submodule') && empty($arguments[0]['flag_call_previous_parent'])) { return call_user_func_array([self::submodule($flag . '.' . $submodule . '.submodule'), $submodule], $arguments); } else { return call_user_func_array([self::submodule($flag . '.submodule'), $submodule], $arguments); } }
/** * Frontend action */ public function action_frontend() { $input = request::input(); // legend echo self::render_topic('frontend'); // processing submit $input['name'] = $input['name'] ?? 'numbers.frontend.html.class.base'; $frontend_frameworks = ['numbers.frontend.html.class.base' => ['name' => 'Plain'], 'numbers.frontend.html.semanticui.base' => ['name' => 'Semantic UI'], 'numbers.frontend.html.bootstrap.base' => ['name' => 'Bootstrap']]; if (!empty($input['submit_yes'])) { $settings = []; $libraries = []; if ($input['name'] == 'numbers.frontend.html.class.base') { $settings = ['submodule' => $input['name'], 'options' => ['grid_columns' => 16], 'calendar' => ['submodule' => 'numbers.frontend.components.calendar.numbers.base']]; $libraries['semanticui']['autoconnect'] = false; $libraries['bootstrap']['autoconnect'] = false; } else { if ($input['name'] == 'numbers.frontend.html.semanticui.base') { $settings = ['submodule' => $input['name'], 'options' => ['grid_columns' => 16], 'calendar' => ['submodule' => 'numbers.frontend.components.calendar.numbers.base']]; $libraries['semanticui']['autoconnect'] = true; $libraries['bootstrap']['autoconnect'] = false; } else { if ($input['name'] == 'numbers.frontend.html.bootstrap.base') { $settings = ['submodule' => $input['name'], 'options' => ['grid_columns' => 12], 'calendar' => ['submodule' => 'numbers.frontend.components.calendar.numbers.base']]; $libraries['semanticui']['autoconnect'] = false; $libraries['bootstrap']['autoconnect'] = true; } } } // we need to merge old and new values session::set('numbers.flag.global.html', array_merge_hard(session::get('numbers.flag.global.html'), $settings)); session::set('numbers.flag.global.library', array_merge_hard(session::get('numbers.flag.global.library'), $libraries)); header('Location: /numbers/frontend/system/controller/dev/~frontend?name=' . $input['name']); exit; } // form $ms = 'Name: ' . html::select(['name' => 'name', 'options' => $frontend_frameworks, 'no_choose' => true, 'value' => $input['name']]) . ' '; $ms .= html::submit(['name' => 'submit_yes']); echo html::form(['name' => 'db', 'action' => '#db_test', 'value' => $ms]); }
/** * Money format * * @param mixed $amount * @param array $options * @return string */ public static function money_format($amount, $options = []) { $format = array_merge_hard(self::$options['locale_options'], $options['locale_options'] ?? []); $options['decimals'] = $options['decimals'] ?? 2; // sometimes symbols contain decimal point, we change it to thousands_sep if (!empty($options['symbol'])) { $options['symbol'] = str_replace($format['mon_decimal_point'], $format['mon_thousands_sep'], $options['symbol']); } else { $options['symbol'] = ''; } // convert to string if (!is_string($amount)) { $amount = $amount . ''; } $negative = strpos($amount, '-') !== false; $amount = ltrim($amount, '-'); // if the number portion has been formatted if (empty($options['amount_partially_formatted'])) { $temp = explode('.', $amount); $number = $temp[0]; $fraction = $temp[1] ?? ''; // process number if (empty($number)) { $number = '0'; } if ($format['mon_thousands_sep'] . '' !== '' && !empty($format['mon_grouping'])) { $counter = 0; $mon_grouping = []; $symbols = array_reverse(mb_str_split($number), true); $number = ''; foreach ($symbols as $k => $v) { // grab group size if ($counter == 0) { if (empty($mon_grouping)) { $mon_grouping = $format['mon_grouping']; } if (count($mon_grouping) > 1) { $counter = array_shift($mon_grouping); } else { $counter = $mon_grouping[0]; } } // skip number of characters $counter--; $number = $v . $number; if ($counter == 0 && $k > 0) { $number = $format['mon_thousands_sep'] . $number; } } } // left precision if (!empty($options['digits'])) { if (strlen($number) < $options['digits']) { $number = str_pad($number, $options['digits'], ' ', STR_PAD_LEFT); } } // right precision if ($options['decimals'] > 0) { $fraction = substr(str_pad($fraction, $options['decimals'], '0', STR_PAD_RIGHT), 0, $options['decimals']); $number = $number . $format['mon_decimal_point'] . $fraction; } } else { $number = $amount; } // translate characters $number = self::number_to_from_native_language($number, $options); // format based on settings $cs_precedes = $negative ? $format['n_cs_precedes'] : $format['p_cs_precedes']; $sep_by_space = $negative ? $format['n_sep_by_space'] : $format['p_sep_by_space']; $sign_posn = $negative ? $format['n_sign_posn'] : $format['p_sign_posn']; // if accounting formatting if (!empty($options['accounting'])) { // if we have currency symbol we added it based on settings if (!empty($options['symbol'])) { $number = ($cs_precedes ? $options['symbol'] . ($sep_by_space === 1 ? ' ' : '') : '') . $number . (!$cs_precedes ? ($sep_by_space === 1 ? ' ' : '') . $options['symbol'] : ''); } if ($negative) { $number = '(' . $number . ')'; } else { $number = ' ' . $number . ' '; } } else { $positive_sign = $format['positive_sign']; $negative_sign = $format['negative_sign']; $sign = $negative ? $negative_sign : $positive_sign; $other_sign = $negative ? $positive_sign : $negative_sign; $sign_padding = ''; if ($sign_posn) { for ($i = 0; $i < strlen($other_sign) - strlen($sign); $i++) { $sign_padding .= ' '; } } $temp_value = ''; switch ($sign_posn) { case 0: // parentheses surround value and currency symbol if (!empty($options['symbol'])) { $number = $cs_precedes ? $options['symbol'] . ($sep_by_space === 1 ? ' ' : '') . $number : $number . ($sep_by_space === 1 ? ' ' : '') . $options['symbol']; } $number = '(' . $number . ')'; break; case 1: // sign precedes if (!empty($options['symbol'])) { $number = $cs_precedes ? $options['symbol'] . ($sep_by_space === 1 ? ' ' : '') . $number : $number . ($sep_by_space === 1 ? ' ' : '') . $options['symbol']; } $number = $sign_padding . $sign . ($sep_by_space === 2 ? ' ' : '') . $number; break; case 2: // sign follows if (!empty($options['symbol'])) { $number = $cs_precedes ? $options['symbol'] . ($sep_by_space === 1 ? ' ' : '') . $number : $number . ($sep_by_space === 1 ? ' ' : '') . $options['symbol']; } $number = $number . ($sep_by_space === 2 ? ' ' : '') . $sign . $sign_padding; break; case 3: //sign precedes currency symbol $symbol = ''; if (!empty($options['symbol'])) { $symbol = $cs_precedes ? $options['symbol'] . ($sep_by_space === 1 ? ' ' : '') : ($sep_by_space === 2 ? ' ' : '') . $options['symbol']; } $number = $cs_precedes ? $sign_padding . $sign . ($sep_by_space === 2 ? ' ' : '') . $symbol . $number : $number . ($sep_by_space === 1 ? ' ' : '') . $sign . $sign_padding . $symbol; break; case 4: // sign succeeds currency symbol $symbol = ''; $symbol_sep = ''; if (!empty($options['symbol'])) { $symbol = $options['symbol']; $symbol_sep = $sep_by_space === 1 ? ' ' : ''; } $number = $cs_precedes ? $symbol . ($sep_by_space === 2 ? ' ' : '') . $sign_padding . $sign . $symbol_sep . $number : $number . $symbol_sep . $symbol . ($sep_by_space === 2 ? ' ' : '') . $sign . $sign_padding; break; } } return $number; }
/** * @see html::table() */ public static function table($options = []) { $rows = isset($options['options']) ? $options['options'] : []; if (!empty($options['header']) && is_array($options['header'])) { $header = $options['header']; } else { // we need to grab header from first row $header = current($rows); $options['skip_header'] = true; } $result = []; $first_column = null; // header first if (!empty($header) && empty($options['skip_header'])) { $temp2 = '<thead>'; $temp2 .= '<tr>'; foreach ($header as $k => $v) { // determine first column if ($first_column === null) { $first_column = $k; } if (is_array($v)) { $tag = !empty($v['header_use_td_tag']) ? 'td' : 'th'; $temp_value = isset($v['value']) ? $v['value'] : ''; unset($v['value']); $temp2 .= '<' . $tag . ' ' . self::generate_attributes($v, $tag) . '>' . $temp_value . '</' . $tag . '>'; } else { $temp2 .= '<th nowrap>' . $v . '</th>'; } } $temp2 .= '</tr>'; $temp2 .= '</thead>'; $result[] = $temp2; } // unsetting some values unset($options['options'], $options['header'], $options['skip_header']); // rows second foreach ($rows as $k => $v) { // we need to extract row attributes from first column $row_options = []; foreach ($header as $k2 => $v2) { if (isset($v[$k2]) && is_array($v[$k2])) { $row_options = array_merge_hard($row_options, array_key_extract_by_prefix($v[$k2], 'row_')); } } $temp2 = '<tr ' . self::generate_attributes($row_options, 'tr') . '>'; // important we render based on header array and not on what is in rows $flag_colspan = 0; foreach ($header as $k2 => $v2) { if ($flag_colspan > 0) { $flag_colspan--; continue; } if (!isset($v[$k2])) { $v[$k2] = null; } if (is_array($v[$k2])) { $temp3 = isset($v[$k2]['value']) ? $v[$k2]['value'] : ''; unset($v[$k2]['value']); if (!empty($v[$k2]['nowrap'])) { $v[$k2]['nowrap'] = 'nowrap'; } if (!empty($v[$k2]['colspan'])) { $flag_colspan = $v[$k2]['colspan']; $flag_colspan--; } $temp2 .= '<td ' . self::generate_attributes($v[$k2], 'td') . '>' . $temp3 . '</td>'; } else { $temp2 .= '<td nowrap>' . $v[$k2] . '</td>'; } } // reset colspan $flag_colspan = 0; $temp2 .= '</tr>'; $result[] = $temp2; } // todo: add footer // todo: maybe use <thead>, <tfoot>, and a <tbody> tags return '<table ' . self::generate_attributes($options, 'table') . '>' . implode('', $result) . '</table>'; }
/** * Data default renderer * * @return string */ private final function render_data_default() { $result = ''; // if we have no rows we display a messsage if ($this->num_rows == 0) { return html::message(['type' => 'warning', 'options' => [i18n(null, object_content_messages::no_rows_found)]]); } $counter = 1; $table = ['header' => [], 'options' => []]; // action flags $actions = []; if (object_controller::can('record_view')) { $actions['view'] = true; } // generate columns foreach ($this->columns as $k => $v) { // if we can not view we skip action column if (empty($actions) && $k == 'action') { continue; } $table['header'][$k] = ['value' => i18n(null, $v['name']), 'nowrap' => true, 'width' => $v['width'] ?? null]; } // generate rows foreach ($this->rows as $k => $v) { // process all columns first $row = []; foreach ($this->columns as $k2 => $v2) { // if we can not view we skip action column if (empty($actions) && $k2 == 'action') { continue; } $value = []; // create cell properties foreach (['width', 'align'] as $v3) { if (isset($v2[$v3])) { $value[$v3] = $v2[$v3]; } } // process rows if ($k2 == 'action') { $value['value'] = []; if (!empty($actions['view'])) { $mvc = application::get('mvc'); $pk = extract_keys($this->model_object->pk, $v); $url = $mvc['controller'] . '/_edit?' . http_build_query2($pk); $value['value'][] = html::a(['value' => i18n(null, 'View'), 'href' => $url]); } $value['value'] = implode(' ', $value['value']); } else { if ($k2 == 'row_number') { $value['value'] = format::id($counter) . '.'; } else { if ($k2 == 'offset_number') { $value['value'] = format::id($this->offset + $counter) . '.'; } else { if (!empty($v2['options_model'])) { if (strpos($v2['options_model'], '::') === false) { $v2['options_model'] .= '::options'; } $params = $v2['options_params'] ?? []; if (!empty($v2['options_depends'])) { foreach ($v2['options_depends'] as $k0 => $v0) { $params[$k0] = $v[$v0]; } } $crypt_object = new crypt(); $hash = $crypt_object->hash($v2['options_model'] . serialize($params)); if (!isset($this->cached_options[$hash])) { $method = factory::method($v2['options_model'], null, true); $this->cached_options[$hash] = call_user_func_array($method, [['where' => $params]]); } if (isset($this->cached_options[$hash][$v[$k2]])) { $value['value'] = $this->cached_options[$hash][$v[$k2]]['name']; } else { $value['value'] = null; } } else { if (!empty($v2['options']) && !is_array($v[$k2])) { if (isset($v2['options'][$v[$k2]])) { $value['value'] = $v2['options'][$v[$k2]]['name']; } else { $value['value'] = null; } } else { if (isset($v[$k2])) { $value['value'] = $v[$k2]; } else { $value['value'] = null; } } } } } } // put value into row if (!empty($v2['format'])) { $format_options = $v2['format_options'] ?? []; if (!empty($v2['format_depends'])) { $format_depends = $v2['format_depends']; $this->process_params_and_depends($format_depends, $v); $format_options = array_merge_hard($format_options, $format_depends); } $method = factory::method($v2['format'], 'format'); $value['value'] = call_user_func_array([$method[0], $method[1]], [$value['value'], $format_options]); } $row[$k2] = $value; } // put processed columns though user defined function if (method_exists($this, 'render_data_rows')) { $table['options'][$counter] = $this->render_data_rows($row, $v); } else { $table['options'][$counter] = $row; } $counter++; } return html::table($table); }
/** * Render elements value * * @param array $options * @param mixed $value * @param array $neighbouring_values * @return string * @throws Exception */ public function render_element_value(&$options, $value = null, &$neighbouring_values = []) { // field name and values_key $options['options']['field_name'] = $options['options']['details_field_name'] ?? $options['options']['name']; $options['options']['field_values_key'] = implode('[::]', $options['options']['field_values_key'] ?? [$options['options']['field_name']]); // custom renderer if (!empty($options['options']['custom_renderer'])) { $method = factory::method($options['options']['custom_renderer'], null, true); $options_custom_renderer = $options; call_user_func_array($method, [&$this, &$options, &$value, &$neighbouring_values]); } // handling override_field_value method if (!empty($this->wrapper_methods['override_field_value']['main'])) { call_user_func_array($this->wrapper_methods['override_field_value']['main'], [&$this, &$options, &$value, &$neighbouring_values]); } $result_options = $options['options']; $options['options']['value'] = $value; array_key_extract_by_prefix($result_options, 'label_'); $element_expand = !empty($result_options['expand']); $html_suffix = $result_options['html_suffix'] ?? ''; // unset certain keys unset($result_options['order'], $result_options['required'], $result_options['html_suffix']); // processing options $flag_select_or_autocomplete = !empty($result_options['options_model']) || !empty($result_options['options']); if (!empty($result_options['options_model'])) { if (empty($result_options['options_params'])) { $result_options['options_params'] = []; } if (empty($result_options['options_options'])) { $result_options['options_options'] = []; } $result_options['options_options']['i18n'] = $result_options['options_options']['i18n'] ?? true; $result_options['options_options']['acl'] = $result_options['options_options']['acl'] ?? $this->acl; if (empty($result_options['options_depends'])) { $result_options['options_depends'] = []; } // options depends & params $this->process_params_and_depends($result_options['options_depends'], $neighbouring_values, $options, true); $this->process_params_and_depends($result_options['options_params'], $neighbouring_values, $options, false); $result_options['options_params'] = array_merge_hard($result_options['options_params'], $result_options['options_depends']); // we do not need options for autocomplete if (strpos($result_options['method'], 'autocomplete') === false) { $skip_values = []; if (!empty($options['options']['details_key'])) { if (!empty($options['options']['details_parent_key'])) { $temp_key = $options['options']['details_parent_key'] . '::' . $options['options']['details_key']; if (!empty($this->misc_settings['details_unique_select'][$temp_key][$options['options']['details_field_name']][$options['options']['__parent_row_number']])) { $skip_values = array_keys($this->misc_settings['details_unique_select'][$temp_key][$options['options']['details_field_name']][$options['options']['__parent_row_number']]); } } else { if (!empty($this->misc_settings['details_unique_select'][$options['options']['details_key']][$options['options']['details_field_name']])) { $skip_values = array_keys($this->misc_settings['details_unique_select'][$options['options']['details_key']][$options['options']['details_field_name']]); } } } $result_options['options'] = object_data_common::process_options($result_options['options_model'], $this, $result_options['options_params'], $value, $skip_values, $result_options['options_options']); } else { // we need to inject form id into autocomplete $result_options['form_id'] = "form_{$this->form_link}_form"; } } // by default all selects are searchable if not specified otherwise if ($flag_select_or_autocomplete) { $result_options['searchable'] = $result_options['searchable'] ?? false; } // different handling for different type switch ($options['type']) { case 'container': $options_container = $options; //$options_container['previous_data'] = $v; // todo: pass $form_data_key from parent $options_container['previous_key'] = $options['previous_key']; // render container $temp_container_value = $this->render_container($data['fm_part_child_container_name'], $parents, $options_container); if (!empty($html_expand)) { // get part id $temp_id = $this->id('part_details', ['part_name' => $data['fm_part_name'], 'part_id' => $options_container['previous_id']]); $temp_id_div_inner = $temp_id . '_html_expand_div_inner'; $temp_expand_div_inner = ['id' => $temp_id_div_inner, 'style' => 'display: none;', 'value' => $temp_container_value]; $temp_expand_div_a = ['href' => 'javascript:void(0);', 'onclick' => "numbers.element.toggle('{$temp_id_div_inner}');", 'value' => '+ / -']; $temp_expand_div_outer = ['align' => 'left', 'value' => html::a($temp_expand_div_a) . '<br />' . html::div($temp_expand_div_inner)]; $value = html::div($temp_expand_div_outer); } else { $value = $temp_container_value; } $result_options['value'] = $value; break; case 'field': $element_method = $result_options['method'] ?? 'html::input'; if (strpos($element_method, '::') === false) { $element_method = 'html::' . $element_method; } // value in special order $flag_translated = false; if (in_array($element_method, ['html::a', 'html::submit', 'html::button', 'html::button2'])) { // translate value $result_options['value'] = i18n($result_options['i18n'] ?? null, $result_options['value'] ?? null); // process confirm_message $result_options['onclick'] = $result_options['onclick'] ?? ''; if (!empty($result_options['confirm_message'])) { $result_options['onclick'] .= 'return confirm(\'' . strip_tags(i18n(null, $result_options['confirm_message'])) . '\');'; } // processing onclick for buttons if (in_array($element_method, ['html::submit', 'html::button', 'html::button2'])) { if (!empty($result_options['onclick']) && strpos($result_options['onclick'], 'this.form.submit();') !== false) { $result_options['onclick'] = str_replace('this.form.submit();', "numbers.form.trigger_submit(this.form);", $result_options['onclick']) . ' return true;'; } else { if (empty($result_options['onclick'])) { $result_options['onclick'] .= 'numbers.form.trigger_submit_on_button(this); return true;'; } else { $result_options['onclick'] = 'numbers.form.trigger_submit_on_button(this); ' . $result_options['onclick']; } } } $flag_translated = true; // icon if (!empty($result_options['icon'])) { $result_options['value'] = html::icon(['type' => $result_options['icon']]) . ' ' . $result_options['value']; } // accesskey if (isset($result_options['accesskey'])) { $accesskey = explode('::', i18n(null, 'accesskey::' . $result_options['name'] . '::' . $result_options['accesskey'], ['skip_translation_symbol' => true])); $result_options['accesskey'] = $accesskey[2]; $result_options['title'] = ($result_options['title'] ?? '') . ' ' . i18n(null, 'Shortcut Key: ') . $accesskey[2]; } } else { if (in_array($element_method, ['html::div', 'html::span'])) { if (!empty($result_options['i18n'])) { $result_options['value'] = i18n($result_options['i18n'] ?? null, $result_options['value'] ?? null); $flag_translated = true; } } else { // editable fields $result_options['value'] = $value; // if we need to empty value, mostly for password fields if (!empty($result_options['empty_value'])) { $result_options['value'] = ''; } // we need to empty zero integers and sequences, before format if (($result_options['php_type'] ?? '') == 'integer' && ($result_options['type'] ?? '') != 'boolean' && ($result_options['domain'] ?? '') != 'counter' && 'counter' && empty($result_options['value'])) { $result_options['value'] = ''; } // format, not for selects/autocompletes/presets if (!$flag_select_or_autocomplete) { if (!empty($result_options['format'])) { if (!empty($this->errors['fields'][$result_options['error_name']]) && empty($this->errors['formats'][$result_options['error_name']])) { // nothing } else { $result_options['format_options'] = $result_options['format_options'] ?? []; if (!empty($result_options['format_depends'])) { $this->process_params_and_depends($result_options['format_depends'], $neighbouring_values, $options, true); $result_options['format_options'] = array_merge_hard($result_options['format_options'], $result_options['format_depends']); } $method = factory::method($result_options['format'], 'format'); $result_options['value'] = call_user_func_array([$method[0], $method[1]], [$result_options['value'], $result_options['format_options']]); } } } // align if (!empty($result_options['align'])) { $result_options['style'] = ($result_options['style'] ?? '') . 'text-align:' . $result_options['align'] . ';'; } // processing persistent if (!empty($result_options['persistent']) && $this->values_loaded) { if ($result_options['persistent'] === 'if_set') { $original_value = $detail = array_key_get($this->original_values, $result_options['values_key']); if (!empty($original_value)) { $result_options['readonly'] = true; } } else { if (count($result_options['values_key']) == 1) { // parent record $result_options['readonly'] = true; } else { if (empty($result_options['__new_row'])) { // details $temp = $result_options['values_key']; array_pop($temp); $detail = array_key_get($this->original_values, $temp); if (!empty($detail)) { $result_options['readonly'] = true; } } } } } // maxlength if (in_array($result_options['type'] ?? '', ['char', 'varchar']) && !empty($result_options['length'])) { $result_options['maxlength'] = $result_options['length']; } // global readonly if (!empty($this->misc_settings['global']['readonly']) && empty($result_options['navigation'])) { $result_options['readonly'] = true; } // title if (isset($options['options']['label_name'])) { $result_options['title'] = ($result_options['title'] ?? '') . ' ' . strip_tags(i18n(null, $options['options']['label_name'])); } } } // translate place holder if (array_key_exists('placeholder', $result_options)) { if (!empty($result_options['placeholder'])) { $result_options['placeholder'] = strip_tags(i18n(null, $result_options['placeholder'])); } } else { if (!empty($result_options['validator_method']) && empty($result_options['value'])) { $temp = object_validator_base::method($result_options['validator_method'], $result_options['value'], $result_options['validator_params'] ?? [], $options['options'], $neighbouring_values); if ($flag_select_or_autocomplete) { $placeholder = $temp['placeholder_select']; } else { $placeholder = $temp['placeholder']; } if (!empty($placeholder)) { $result_options['placeholder'] = strip_tags(i18n(null, $placeholder)); } } } // events foreach (numbers_frontend_html_class_html5::$events as $e) { if (!empty($result_options['readonly'])) { // important - readonly emenets cannot have events unset($result_options[$e]); } else { if (!empty($result_options[$e])) { $result_options[$e] = str_replace('this.form.submit();', 'numbers.form.trigger_submit(this);', $result_options[$e]); $result_options[$e] = str_replace('this.form.extended.', $this->misc_settings['extended_js_class'] . '.', $result_options[$e]); } } } break; case 'html': $element_method = null; break; default: throw new Exception('Render detail type: ' . $data['fm_part_type']); } // handling html_method if (isset($element_method)) { $method = factory::method($element_method, 'html'); $field_method_object = factory::model($method[0], true); // todo: unset non html attributes $value = $field_method_object->{$method[1]}($result_options); // building navigation if (!empty($result_options['navigation'])) { $name = 'navigation[' . $result_options['name'] . ']'; $temp = '<table width="100%" dir="ltr">'; // always left to right $temp .= '<tr>'; $temp .= '<td width="1%">' . html::button2(['name' => $name . '[first]', 'value' => html::icon(['type' => 'step-backward']), 'onclick' => 'numbers.form.trigger_submit_on_button(this);', 'title' => i18n(null, 'First')]) . '</td>'; $temp .= '<td width="1%"> </td>'; $temp .= '<td width="1%">' . html::button2(['name' => $name . '[previous]', 'value' => html::icon(['type' => 'caret-left']), 'onclick' => 'numbers.form.trigger_submit_on_button(this);', 'title' => i18n(null, 'Previous')]) . '</td>'; $temp .= '<td width="1%"> </td>'; $temp .= '<td width="90%">' . $value . '</td>'; $temp .= '<td width="1%"> </td>'; $temp .= '<td width="1%">' . html::button2(['name' => $name . '[refresh]', 'value' => html::icon(['type' => 'refresh']), 'onclick' => 'numbers.form.trigger_submit_on_button(this);', 'title' => i18n(null, 'Refresh')]) . '</td>'; $temp .= '<td width="1%"> </td>'; $temp .= '<td width="1%">' . html::button2(['name' => $name . '[next]', 'value' => html::icon(['type' => 'caret-right']), 'onclick' => 'numbers.form.trigger_submit_on_button(this);', 'title' => i18n(null, 'Next')]) . '</td>'; $temp .= '<td width="1%"> </td>'; $temp .= '<td width="1%">' . html::button2(['name' => $name . '[last]', 'value' => html::icon(['type' => 'step-forward']), 'onclick' => 'numbers.form.trigger_submit_on_button(this);', 'title' => i18n(null, 'Last')]) . '</td>'; $temp .= '</tr>'; $temp .= '</table>'; $value = $temp; } } // html suffix and prefix if (!empty($html_suffix)) { $value .= $html_suffix; } // if we need to display settings if (application::get('flag.numbers.frontend.html.form.show_field_settings')) { $id_original = $result_options['id'] . '__settings_original'; $id_modified = $result_options['id'] . '__settings_modified'; $value .= html::a(['href' => 'javascript:void(0);', 'onclick' => "\$('#{$id_original}').toggle();", 'value' => html::label2(['type' => 'primary', 'value' => count($options['options'])])]); $value .= html::a(['href' => 'javascript:void(0);', 'onclick' => "\$('#{$id_modified}').toggle();", 'value' => html::label2(['type' => 'warning', 'value' => count($result_options)])]); $value .= '<div id="' . $id_original . '" style="display:none; position: absolute; text-align: left; width: 500px; z-index: 32000;">' . print_r2($options['options'], true) . '</div>'; $value .= '<div id="' . $id_modified . '" style="display:none; position: absolute; text-align: left; width: 500px; z-index: 32000;">' . print_r2($result_options, true) . '</div>'; } // we need to put original options back if (!empty($options['options']['custom_renderer'])) { $options = $options_custom_renderer; } return $value; }
/** * Merge variables into object * * @param object $object * @param array $vars */ function object_merge_values(&$object, $vars) { foreach ($vars as $k => $v) { if (property_exists($object, $k) && is_array($object->{$k})) { foreach ($v as $k2 => $v2) { if ($v2 === null) { unset($object->{$k}[$k2]); } else { if (isset($object->{$k}[$k2]) && is_array($object->{$k}[$k2])) { $object->{$k}[$k2] = array_merge_hard($object->{$k}[$k2], $v2); } else { $object->{$k}[$k2] = $v2; } } } } else { $object->{$k} = $v; } } }
/** * Constructor * * @param array $options * input - form input * form - form options * segment - segment options * type * header * footer */ public function __construct($options = []) { // we need to handle overrrides parent::override_handle($this); // step 0: apply data fixes if (method_exists($this, 'overrides')) { $this->overrides($this); } // we need to merge override input if (!empty($this->values)) { $options['input'] = array_merge_hard($options['input'] ?? [], $this->values); } if (isset($options['form_link'])) { $this->form_link = $options['form_link']; } // step 1: create form object $this->form_object = new numbers_frontend_html_form_base($this->form_link, array_merge_hard($this->options, $options)); // class $this->form_object->form_class = get_called_class(); $this->form_object->form_parent =& $this; $this->form_object->acl = $this->acl; // add collection $this->form_object->collection = $this->collection; $this->form_object->preload_collection_object(); // must initialize it before calls to container/row/element $this->form_object->column_prefix = $this->column_prefix ?? $this->form_object->collection_object->primary_model->column_prefix ?? null; // master object if (!empty($this->master_options['model'])) { $this->master_options['type'] = $this->master_options['type'] ?? ''; $this->master_options['ledger'] = strtoupper($this->master_options['ledger']) ?? ''; $this->form_object->master_options = $this->master_options; $this->form_object->master_object = factory::model($this->master_options['model'], true); } // title if (!empty($this->title)) { $this->form_object->title = $this->title; } else { // we generate a title based on class name $temp = explode('_model_form_', get_called_class()); $temp = explode('_', $temp[1]); $this->title = $this->form_object->title = ucwords(implode(' ', $temp)); } // step 2: create all containers foreach ($this->containers as $k => $v) { if ($v === null) { continue; } $this->form_object->container($k, $v); } // step 3: create all rows foreach ($this->rows as $k => $v) { foreach ($v as $k2 => $v2) { if ($v2 === null) { continue; } $this->form_object->row($k, $k2, $v2); } } // step 3: create all elements foreach ($this->elements as $k => $v) { foreach ($v as $k2 => $v2) { foreach ($v2 as $k3 => $v3) { if ($v3 === null) { continue; } $this->form_object->element($k, $k2, $k3, $v3); } } } // step 3: methods foreach (['save', 'validate', 'refresh', 'success', 'pre_render', 'override_field_value', 'override_tabs', 'process_default_value'] as $v) { if (method_exists($this, $v)) { $this->form_object->wrapper_methods[$v]['main'] = [&$this, $v]; } } // extensions can have their own verify methods if (!empty($this->wrapper_methods)) { foreach ($this->wrapper_methods as $k => $v) { $index = 1; foreach ($v as $k2 => $v2) { $this->form_object->wrapper_methods[$k][$index] = [new $k2(), $v2]; $index++; } } } // last step: process form if (empty($options['skip_processing'])) { $this->form_object->process(); } }
/** * Determine model map * * @param string $class * @param string $widget_name * @return boolean * @throws Exception */ public final function determine_model_map($class, $widget_name) { $this->virtual_class_name = $class . '__virtual__' . $widget_name; $model = factory::model($class, true); $this->name = $model->name . '__' . $widget_name; // determine pk $counter = 1; $all_int = true; $columns = []; $this->map = []; $this->__relation_pk = []; foreach ($model->pk as $v) { if ($model->columns[$v]['php_type'] == 'integer') { if ($v == $model->column_prefix . 'id') { $temp = explode('_', $v); unset($temp[0]); $new = $this->column_prefix . implode('_', $temp); } else { $new = str_replace($model->column_prefix, $this->column_prefix, $v); } $columns[$new] = $model->columns[$v]; // copy the same settings if (!empty($columns[$new]['domain'])) { $columns[$new]['domain'] = str_replace('_sequence', '', $columns[$new]['domain']); unset($columns[$new]['type'], $columns[$new]['php_type']); } $this->map[$v] = $new; } else { $all_int = false; } $counter++; } // if we have no integer pk if (!$all_int) { if (!empty($model->relation['field'])) { $new = str_replace($model->column_prefix, $this->column_prefix, $model->relation['field']); $columns = []; $columns[$new] = $model->columns[$model->relation['field']]; // copy the same settings if (!empty($columns[$new]['domain'])) { $columns[$new]['domain'] = str_replace('_sequence', '', $columns[$new]['domain']); unset($columns[$new]['type'], $columns[$new]['php_type']); } $this->map = [$model->relation['field'] => $new]; $this->__relation_pk = $model->pk; } else { throw new Exception('Unable to create widget model!'); } } $this->columns = array_merge_hard($this->columns, $columns); return true; }
/** * Convert array of percentages to grid columns * * @param mixed $percentage_array * @return array */ public static function percentage_to_grid_columns($percentage_array, $options = []) { if (!is_array($percentage_array)) { $percentage_array = [$percentage_array]; } $options = array_merge_hard(application::get('flag.numbers.framework.html.options'), $options); if (empty($options['grid_columns'])) { $options['grid_columns'] = 12; } $step = 100 / $options['grid_columns']; $total = 0; $empty = 0; $arr = ['percent' => [], 'final' => [], 'temp' => [], 'grouped' => []]; foreach ($percentage_array as $k => $v) { $arr['percent'][$k] = $v ? $v : 0; if (!empty($v)) { $total += $v; } else { $empty += 1; } } // if we have empty columns and percent is less than 100 we prepopulate if ($total < 100 && $empty != 0) { $temp = (100 - $total) / $empty; foreach ($arr['percent'] as $k => $v) { if ($v == 0) { $arr['percent'][$k] = $temp; $total += $temp; } } } // we need to rescale if percent is more than 100 if ($total > 100) { $scale = 100 / $total; foreach ($arr['percent'] as $k => $v) { $arr['percent'][$k] = $v * $scale; } } // sort in ascending order asort($arr['percent']); $cells_left = $options['grid_columns']; foreach ($arr['percent'] as $k => $v) { if ($v <= $step) { $arr['final'][$k] = 1; $cells_left--; } else { $rounded = floor($v / $step); $leftover = $v - $rounded * $step; $arr['final'][$k] = $rounded; $cells_left -= $rounded; if ($leftover > 0) { $arr['temp'][$k] = $leftover; } } } // if we have cells left we distribute if ($cells_left > 0) { // grouping & sorting for special handling /* todo: polish login for left overs foreach ($arr['percent'] as $k => $v) { $arr['grouped'][$v][$k] = 1; } krsort($arr['grouped']); $temp = array_values($arr['grouped']); if ($cells_left == 2 && count($arr['grouped']) > 1 && count($temp[0]) == 1 && count($temp[1]) > 1) { $arr['final'][key($temp[0])]+= 2; $cells_left = 0; } */ // if we got here we distribute on by one if ($cells_left > 0) { arsort($arr['temp']); foreach ($arr['temp'] as $k => $v) { $arr['final'][$k]++; $cells_left--; unset($arr['temp'][$k]); if ($cells_left == 0) { break; } } } } return ['success' => true, 'error' => [], 'data' => $arr['final']]; }
/** * Process models * * @param array $options * @return array */ public static function process_models($options = []) { $result = ['success' => false, 'error' => [], 'hint' => [], 'data' => []]; do { // we need to process all dependencies first $dep = self::process_deps_all($options); if (!$dep['success']) { $result = $dep; $result['error'][] = 'You must fix all dependency related errors first before processing models.'; break; } // proccesing models if (empty($dep['data']['model_processed'])) { $result['error'][] = 'You do not have models to process!'; break; } $object_attributes = []; $object_relations = []; $object_forms = []; $flag_relation = application::get('dep.submodule.numbers.data.relations') ? true : false; $object_documentation = []; $object_import = []; $ddl = new numbers_backend_db_class_ddl(); // run 1 to deterine virtual tables $first = true; $virtual_models = $dep['data']['model_processed']; run_again: foreach ($virtual_models as $k => $v) { $k2 = str_replace('.', '_', $k); if ($v == 'object_table') { $model = factory::model($k2, true); foreach (['attributes', 'audit', 'addresses'] as $v0) { if ($model->{$v0}) { $v01 = $v0 . '_model'; $virtual_models[str_replace('_', '.', $model->{$v01})] = 'object_table'; } } } } if ($first) { $first = false; goto run_again; // some widgets have attributes } $dep['data']['model_processed'] = array_merge_hard($dep['data']['model_processed'], $virtual_models); $domains = object_data_domains::get_static(); // run 2 foreach ($dep['data']['model_processed'] as $k => $v) { $k2 = str_replace('.', '_', $k); if ($v == 'object_table') { $model = factory::model($k2, true); $temp_result = $ddl->process_table_model($model); if (!$temp_result['success']) { array_merge3($result['error'], $temp_result['error']); } $object_documentation[$v][$k2] = $k2; // relation if ($flag_relation) { if (!empty($model->relation)) { $domain = $model->columns[$model->relation['field']]['domain'] ?? null; if (!empty($domain)) { $domain = str_replace('_sequence', '', $domain); $type = $domains[$domain]['type']; } else { $type = $model->columns[$model->relation['field']]['type']; } $object_relations[$k2] = ['rn_relattr_code' => $model->relation['field'], 'rn_relattr_name' => $model->title, 'rn_relattr_model' => $k2, 'rn_relattr_domain' => $domain, 'rn_relattr_type' => $type, 'rn_relattr_inactive' => !empty($model->relation['inactive']) ? 1 : 0]; } if (!empty($model->attributes)) { $object_attributes[$k2] = ['rn_attrmdl_code' => $k2, 'rn_attrmdl_name' => $model->title, 'rn_attrmdl_inactive' => 0]; } } } else { if ($v == 'object_sequence') { $temp_result = $ddl->process_sequence_model($k2); if (!$temp_result['success']) { array_merge3($result['error'], $temp_result['error']); } $object_documentation[$v][$k2] = $k2; } else { if ($v == 'object_function') { $temp_result = $ddl->process_function_model($k2); if (!$temp_result['success']) { array_merge3($result['error'], $temp_result['error']); } $object_documentation[$v][$k2] = $k2; } else { if ($v == 'object_extension') { $temp_result = $ddl->process_function_extension($k2); if (!$temp_result['success']) { array_merge3($result['error'], $temp_result['error']); } $object_documentation[$v][$k2] = $k2; } else { if ($v == 'object_import') { $object_import[$k2] = ['model' => $k2]; } } } } } } // if we have erros if (!empty($result['error'])) { break; } // db factory $db_factory = factory::get('db'); // we load objects from database $loaded_objects = []; foreach ($ddl->db_links as $k => $v) { $ddl_object = $db_factory[$k]['ddl_object']; $temp_result = $ddl_object->load_schema($k); if (!$temp_result['success']) { array_merge3($result['error'], $temp_result['error']); } else { $loaded_objects[$k] = $temp_result['data']; } } // if we have erros if (!empty($result['error'])) { break; } // get a list of all db links $db_link_list = array_unique(array_merge(array_keys($ddl->objects), array_keys($loaded_objects))); // if we are dropping schema if ($options['mode'] == 'drop') { $ddl->objects = []; } // compare schemas per db link $schema_diff = []; $total_per_db_link = []; $total = 0; foreach ($db_link_list as $k) { // we need to have a back end for comparison $compare_options['backend'] = $db_factory[$k]['backend']; // comparing $temp_result = $ddl->compare_schemas(isset($ddl->objects[$k]) ? $ddl->objects[$k] : [], isset($loaded_objects[$k]) ? $loaded_objects[$k] : [], $compare_options); if (!$temp_result['success']) { array_merge3($result['hint'], $temp_result['error']); } else { $schema_diff[$k] = $temp_result['data']; if (!isset($total_per_db_link[$k])) { $total_per_db_link[$k] = 0; } $total_per_db_link[$k] += $temp_result['count']; $total += $temp_result['count']; } } // if there's no schema changes if ($total == 0) { if ($options['mode'] == 'commit') { goto import_data; } else { $result['success'] = true; } break; } // we need to provide a list of changes foreach ($total_per_db_link as $k => $v) { $result['hint'][] = ''; $result['hint'][] = "Db link {$k} requires {$v} changes!"; // printing summary $result['hint'][] = ' * Link ' . $k . ': '; foreach ($schema_diff[$k] as $k2 => $v2) { $result['hint'][] = ' * ' . $k2 . ': '; foreach ($v2 as $k3 => $v3) { $result['hint'][] = ' * ' . $k3 . ' - ' . $v3['type']; } } } // if we are in no commit mode we exit if (!in_array($options['mode'], ['commit', 'drop'])) { break; } // generating sql foreach ($total_per_db_link as $k => $v) { if ($v == 0) { continue; } $ddl_object = $db_factory[$k]['ddl_object']; foreach ($schema_diff[$k] as $k2 => $v2) { foreach ($v2 as $k3 => $v3) { // we need to make fk constraints last to sort MySQL issues if ($k2 == 'new_constraints' && $v3['type'] == 'constraint_new' && $v3['data']['type'] == 'fk') { $schema_diff[$k][$k2 . '_fks'][$k3]['sql'] = $ddl_object->render_sql($v3['type'], $v3); } else { $schema_diff[$k][$k2][$k3]['sql'] = $ddl_object->render_sql($v3['type'], $v3, ['mode' => $options['mode']]); } } } } // print_r($schema_diff); // exit; // executing sql foreach ($total_per_db_link as $k => $v) { if ($v == 0) { continue; } $db_object = new db($k); // if we are dropping we need to disable foregn key checks if ($options['mode'] == 'drop') { if ($db_object->backend == 'mysqli') { $db_object->query('SET foreign_key_checks = 0;'); // we also need to unset sequences unset($schema_diff[$k]['delete_sequences']); } } foreach ($schema_diff[$k] as $k2 => $v2) { foreach ($v2 as $k3 => $v3) { if (empty($v3['sql'])) { continue; } if (is_array($v3['sql'])) { $temp = $v3['sql']; } else { $temp = [$v3['sql']]; } foreach ($temp as $v4) { $temp_result = $db_object->query($v4); if (!$temp_result['success']) { array_merge3($result['error'], $temp_result['error']); goto error; } } } } } // if we got here - we are ok $result['success'] = true; } while (0); import_data: // we need to import data if (!empty($object_import) && $options['mode'] == 'commit') { $result['hint'][] = ''; foreach ($object_import as $k => $v) { $data_object = new $k(); $data_result = $data_object->process(); if (!$data_result['success']) { throw new Exception(implode("\n", $data_result['error'])); } $result['hint'] = array_merge($result['hint'], $data_result['hint']); } } // relation if ($flag_relation && $options['mode'] == 'commit') { $result['hint'][] = ''; $model2 = factory::model('numbers_data_relations_model_relation_attributes'); // insert new models if (!empty($object_relations)) { foreach ($object_relations as $k => $v) { $result_insert = $model2->save($v, ['pk' => ['rn_relattr_code'], 'ignore_not_set_fields' => true]); } $result['hint'][] = ' * Imported relation models!'; } // we need to process forms foreach ($dep['data']['submodule_dirs'] as $v) { $dir = $v . 'model/form/'; if (!file_exists($dir)) { continue; } $files = helper_file::iterate($dir, ['only_extensions' => ['php']]); foreach ($files as $v2) { $model_name = str_replace(['../libraries/vendor/', '.php'], '', $v2); $model_name = str_replace('/', '_', $model_name); $model = new $model_name(['skip_processing' => true]); if (empty($model->form_object->misc_settings['option_models'])) { continue; } // loop though fields foreach ($model->form_object->misc_settings['option_models'] as $k3 => $v3) { $object_forms[$model_name . '::' . $k3] = ['rn_relfrmfld_form_code' => $model_name, 'rn_relfrmfld_form_name' => $model->title, 'rn_relfrmfld_field_code' => $k3, 'rn_relfrmfld_field_name' => $v3['field_name'], 'rn_relfrmfld_relattr_id' => $v3['model'], 'rn_relfrmfld_inactive' => 0]; } } } if (!empty($object_forms)) { // load all relation models $data = $model2->get(['pk' => ['rn_relattr_model']]); $model = factory::model('numbers_data_relations_model_relation_formfields'); foreach ($object_forms as $k => $v) { if (empty($data[$v['rn_relfrmfld_relattr_id']])) { continue; } $v['rn_relfrmfld_relattr_id'] = $data[$v['rn_relfrmfld_relattr_id']]['rn_relattr_id']; $result_insert = $model->save($v, ['pk' => ['rn_relfrmfld_form_code', 'rn_relfrmfld_field_code'], 'ignore_not_set_fields' => true]); } $result['hint'][] = ' * Imported relation form fields!'; } // todo: import models //print_r2($object_attributes); if (!empty($object_attributes)) { $model = factory::model('numbers_data_relations_model_attribute_models'); foreach ($object_attributes as $k => $v) { $result_insert = $model->save($v, ['pk' => ['rn_attrmdl_code'], 'ignore_not_set_fields' => true]); } $result['hint'][] = ' * Imported attribute models!'; } } // we need to generate documentation $system_documentation = application::get('system_documentation'); if (!empty($system_documentation) && $options['mode'] == 'commit') { $model = factory::model($system_documentation['model']); /* print_r2($object_documentation); $documentation_result = $model->update($object_documentation, $system_documentation); if (!$documentation_result['success']) { $result['error'] = array_merge($result['error'], $documentation_result['error']); } */ } error: return $result; }
/** * 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(); } }
/** * Constructing database object * * @param string $db_link */ public function __construct($db_link) { $this->db_link = $db_link; // keywords overrides $this->sql_keywords = array_merge_hard($this->sql_keywords, $this->sql_keywords_overrides); }