示例#1
0
 /**
  * Send an email
  *
  * Usage example:
  *
  * 	$result = mail::send([
  * 		'to' => 'test@localhost',
  *		'cc' => 'cc@localhost',
  *		'bcc' => 'bcc@localhost',
  *		'subject' => 'test subject',
  * 		'message' => 'test message',
  * 		'attachments' => [
  *	 		['path' => 'path to file', 'name' => 'test.txt'],
  * 			['data' => '!!!data!!!', 'name' => 'test.txt', 'type' => 'plain/text']
  * 		]
  * 	]);
  *
  * @param array $options
  */
 public static function send($options)
 {
     $result = ['success' => false, 'error' => []];
     // mail delivery first
     $mail_delivery_class = application::get('flag.global.mail.delivery.submodule', ['class' => 1]);
     if (empty($mail_delivery_class)) {
         throw new Exception('You need to specify mail delivery submodule');
     }
     $mail_delivery_object = new $mail_delivery_class();
     $temp = $mail_delivery_object->send($options);
     if (!$temp['success']) {
         array_merge3($result['error'], $temp['error']);
     } else {
         $result['success'] = true;
     }
     return $result;
 }
示例#2
0
 public static function import($file_name, $model_class, $options = array())
 {
     $result = array('success' => false, 'error' => array());
     do {
         // model
         $model = new $model_class();
         // format
         $format = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
         if (empty(self::$formats[$format]) || !(self::$formats[$format]['type'] == 1 || self::$formats[$format]['type'] == 3)) {
             $result['error'][] = 'Not supported upload format!';
             @unlink($file_name);
             break;
         }
         $file_format = self::$formats[$format];
         // reading file
         switch ($format) {
             case 'xlsx':
                 $file_data = self::xlsx_to_array($file_name, $file_format['excel_code']);
                 break;
             default:
                 $file_data = self::csv_to_array($file_name, $file_format['delimiter'], $file_format['enclosure']);
         }
         // cleaning up
         unlink($file_name);
         // checking
         if ($file_data === false || empty($file_data)) {
             $result['error'][] = 'Error reading or empty file!';
             break;
         }
         // transforming data
         $objects = array();
         $temp = array_shift($file_data);
         $keys = $temp[0];
         unset($temp[0]);
         foreach ($temp as $k => $v) {
             // fix array fields
             foreach ($v as $k2 => $v2) {
                 $v2 = $v2 . '';
                 if (@$v2[0] == '{' && $v2[strlen($v2) - 1] == '}') {
                     $v[$k2] = db::pg_parse_array($v2);
                 }
             }
             $objects[] = array_combine($keys, $v);
         }
         // processing details
         if (!empty($objects) && !empty($file_data)) {
             foreach ($model->details as $k => $v) {
                 $model2 = new $k();
                 if (isset($file_data[$model2->table])) {
                     // if we have details of details
                     $details_of_details = array();
                     $keys_of_details = array();
                     $options_of_details = array();
                     if (isset($model2->details)) {
                         foreach ($model2->details as $k10 => $v10) {
                             $model3 = new $k10();
                             if (isset($file_data[$model3->table])) {
                                 $options_of_details[$model3->table] = $v10['key'];
                                 $details_of_details[$model3->table] = $file_data[$model3->table];
                                 $keys_of_details[$model3->table] = $details_of_details[$model3->table][0];
                                 unset($file_data[$model3->table], $details_of_details[$model3->table][0]);
                             }
                         }
                         // setting keys properly
                         foreach ($details_of_details as $k10 => $v10) {
                             foreach ($v10 as $k11 => $v11) {
                                 $details_of_details[$k10][$k11] = array_combine($keys_of_details[$k10], $v11);
                             }
                         }
                     }
                     // details itself
                     $details = array();
                     $temp = $file_data[$model2->table];
                     $keys = $temp[0];
                     unset($file_data[$model2->table], $temp[0]);
                     foreach ($temp as $k2 => $v2) {
                         // fix array fields
                         foreach ($v2 as $k9 => $v9) {
                             $v9 = $v9 . '';
                             if (@$v9[0] == '{' && $v9[strlen($v9) - 1] == '}') {
                                 $v2[$k9] = db::pg_parse_array($v9);
                             }
                         }
                         // combining keys and values to make an assocoative array
                         $value = array_combine($keys, $v2);
                         // if we have details of details
                         if (!empty($details_of_details)) {
                             foreach ($details_of_details as $k10 => $v10) {
                                 // main keys
                                 $keys10 = array();
                                 foreach ($options_of_details[$k10] as $k12 => $v12) {
                                     $keys10[] = $value[$k12];
                                 }
                                 $keys10 = implode('-', $keys10);
                                 // lopping though all items
                                 foreach ($v10 as $k11 => $v11) {
                                     $keys11 = array();
                                     foreach ($options_of_details[$k10] as $k12 => $v12) {
                                         $keys11[] = $v11[$v12];
                                     }
                                     $keys11 = implode('-', $keys11);
                                     if ($keys10 == $keys11) {
                                         $value[$k10][] = $v11;
                                     }
                                 }
                             }
                         }
                         // putting back into loop
                         $details[] = $value;
                     }
                     // if we have rows
                     if (!empty($details)) {
                         foreach ($objects as $k2 => $v2) {
                             // keys
                             $keys = array();
                             foreach ($v['key'] as $k3 => $v3) {
                                 $keys[] = $v2[$k3];
                             }
                             $keys = implode('-', $keys);
                             foreach ($details as $k3 => $v3) {
                                 $keys2 = array();
                                 foreach ($v['key'] as $k4 => $v4) {
                                     $keys2[] = $v3[$v4];
                                 }
                                 $keys2 = implode('-', $keys2);
                                 if ($keys2 == $keys) {
                                     $objects[$k2][$model2->table][] = $v3;
                                 }
                             }
                         }
                     }
                 }
             }
         }
         // saving
         if (!empty($objects)) {
             if (empty($options['all_objects_as_array'])) {
                 foreach ($objects as $k => $v) {
                     // replacing values in some cases
                     if (!empty($options['replace_values'])) {
                         foreach ($options['replace_values'] as $k2 => $v2) {
                             $v[$k2] = $v2;
                         }
                     }
                     $save_result = $model->save($v);
                     if (!$save_result['success']) {
                         array_merge3($result['error'], $save_result['error']);
                     }
                 }
             } else {
                 foreach ($objects as $k => $v) {
                     // replacing values in some cases
                     if (!empty($options['replace_values'])) {
                         foreach ($options['replace_values'] as $k2 => $v2) {
                             $objects[$k2] = $v2;
                         }
                     }
                 }
                 $save_result = $model->save($objects);
                 if (!$save_result['success']) {
                     array_merge3($result['error'], $save_result['error']);
                 }
             }
         }
         if (empty($result['error'])) {
             $result['success'] = true;
         }
     } while (0);
     return $result;
 }
 /**
  * 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;
 }
示例#4
0
 /**
  * Validate
  *
  * @param array $options
  * @return array
  */
 public function validate($options)
 {
     $result = ['success' => false, 'error' => [], 'data' => ['from' => '', 'subject' => '', 'to' => [], 'message' => [], 'attachments' => [], 'requires_fetching' => false]];
     do {
         // processing from
         if (isset($options['from'])) {
             $from = $options['from'];
         } else {
             $from = application::get('flag.global.mail.from');
         }
         if (empty($from['email'])) {
             $result['error'][] = 'You need to specify from email address!';
         } else {
             $result['data']['from'] = $from;
         }
         // processing subject
         if (isset($options['subject'])) {
             $result['data']['subject'] = $options['subject'];
         }
         // processing message
         if (is_string($options['message'])) {
             $result['data']['message'][] = ['data' => $options['message']];
         } else {
             if (isset($options['message']['data'])) {
                 $result['data']['message'][] = $options['message'];
             } else {
                 $result['data']['message'] = $options['message'];
             }
         }
         // detecting type for each message part
         $flags = [];
         foreach ($result['data']['message'] as $k => $v) {
             // we need to determine mesage type
             if (!isset($v['type'])) {
                 if ($v['data'] == html_entity_decode(strip_tags($v['data']))) {
                     $result['data']['message'][$k]['type'] = 'text/plain';
                     $flags['text'] = 1;
                 } else {
                     $result['data']['message'][$k]['type'] = 'text/html';
                     $flags['html'] = $k;
                 }
             } else {
                 if (!in_array($v['type'], object_type_mail_messages::$data)) {
                     $result['error'][] = 'Unknown type: ' . $v['type'];
                 }
             }
             // charset
             if (!isset($v['charset'])) {
                 $result['data']['message'][$k]['charset'] = 'utf-8';
             }
             // encoding
             if (!isset($v['encoding'])) {
                 $result['data']['message'][$k]['encoding'] = '7bit';
             }
         }
         // if we have html version but does not that text version we autogenerate
         if (isset($flags['html']) && empty($flags['text'])) {
             $temp = str_replace(['<br/>', '<br />', '<br>', '<hr/>', '<hr />', '<hr>'], "\n", $result['data']['message'][$flags['html']]['data']);
             array_unshift($result['data']['message'], ['type' => 'text/plain', 'data' => html_entity_decode(strip_tags($temp)), 'charset' => 'utf-8', 'encoding' => '7bit']);
         }
         // validating receipients
         foreach (['to', 'cc', 'bcc'] as $r) {
             $result['data'][$r] = [];
             if (!isset($options[$r])) {
                 continue;
             }
             // validating
             $temp = $this->validate_recepient($options[$r]);
             if (!$temp['success']) {
                 array_merge3($result['error'], $temp['error']);
             } else {
                 $result['data'][$r] = $temp['data'];
                 if (!empty($temp['requires_fetching'])) {
                     $result['data']['requires_fetching'] = true;
                 }
             }
         }
         // processing attachments
         if (!empty($options['attachments'])) {
             // if we have one attachment
             if (isset($options['attachments']['path']) || isset($options['attachments']['data'])) {
                 $temp = [$options['attachments']];
             } else {
                 $temp = $options['attachments'];
             }
             $finfo = finfo_open(FILEINFO_MIME_TYPE);
             foreach ($temp as $v) {
                 if (isset($v['path'])) {
                     $type = finfo_file($finfo, $v['path']);
                     if ($type === false) {
                         $result['error'][] = 'Unknown attachment type!';
                     } else {
                         $result['data']['attachments'][] = ['type' => $type, 'data' => file_get_contents($v['path']), 'name' => basename($v['path'])];
                     }
                 } else {
                     if (isset($v['data'])) {
                         if (empty($v['type'])) {
                             $result['error'][] = 'Unknown attachment type!';
                         } else {
                             $result['data']['attachments'][] = ['type' => $v['type'], 'data' => $v['data'], 'name' => isset($v['name']) ? $v['name'] : ''];
                         }
                     }
                 }
             }
             finfo_close($finfo);
         }
         // if we have errors we break
         if ($result['error']) {
             break;
         }
         // if we got here, means we are ok
         $result['success'] = 1;
     } while (0);
     // we need to unset data key if we have an error
     if (!$result['success']) {
         unset($result['data']);
     }
     return $result;
 }