示例#1
0
 /**
  * Send an email
  *
  * @param array $options
  * @return array
  */
 public function send($options)
 {
     $result = ['success' => false, 'error' => [], 'unique_id' => null];
     // see if we need to validate
     if (empty($options['validated'])) {
         $temp = $this->validate($options);
         if (!$temp['success']) {
             return $temp;
         } else {
             if (!empty($temp['data']['requires_fetching'])) {
                 // we error if we require fetching from database
                 $result['error'][] = 'Fetching of email addresses is required!';
                 return $result;
             } else {
                 $options = $temp['data'];
             }
         }
     }
     // to, cc, bcc
     $recepients = [];
     foreach (['to', 'cc', 'bcc'] as $r) {
         $recepients[$r] = [];
         foreach ($options[$r] as $v) {
             // todo: add recepient name here
             $recepients[$r][] = $v['email'];
         }
         $recepients[$r] = implode(',', $recepients[$r]);
     }
     // crypt object
     $crypt = new crypt();
     // todo: use unique id for tracking
     $result['unique_id'] = $crypt->hash([$recepients, $options['subject'], microtime()]);
     // generating header
     if (isset($options['header'])) {
         $header = $options['header'];
     } else {
         $header = '';
     }
     if (isset($options['from']['name'])) {
         $header .= "From: {$options['from']['name']} <{$options['from']['email']}>\n";
         $header .= "Organization: {$options['from']['name']}\n";
     } else {
         $header .= "From: {$options['from']['email']}\n";
     }
     if (!empty($recepients['bcc'])) {
         $header .= "Bcc: " . $recepients['bcc'] . "\n";
     }
     if (!empty($recepients['cc'])) {
         $header .= "Cc: " . $recepients['cc'] . "\n";
     }
     $header .= "Reply-To: {$options['from']['email']}\n";
     $header .= "Errors-To: {$options['from']['email']}\n";
     $header .= "MIME-Version: 1.0\n";
     $header .= "X-Mailer: PHP/" . phpversion() . "\n";
     // generating body for no attachment and a single message
     if (empty($options['attachments']) && count($options['message']) == 1) {
         $part = reset($options['message']);
         $header .= "Content-Type: {$part['type']};\n charset=\"{$part['charset']}\"\n";
         $header .= "Content-Transfer-Encoding: {$part['encoding']}\n";
         $body = $part['data'];
     } else {
         // has attachments or multiple messages
         $body_text = "";
         $unique_hash = $crypt->hash(mt_rand());
         $body_boundary = "boundary." . $unique_hash;
         $body_header = "";
         $body_header .= "Content-Type: multipart/alternative; boundary=\"{$body_boundary}\"\n";
         $body_header .= "Content-Transfer-Encoding: 7bit\n";
         $body_header .= "Content-Disposition: inline\n";
         // going though messages
         foreach ($options['message'] as $part) {
             $body_text .= "--{$body_boundary}\n";
             $body_text .= "Content-Type: {$part['type']}; charset=\"{$part['charset']}\"\n";
             $body_text .= "Content-Transfer-Encoding: {$part['encoding']}\n\n";
             $body_text .= $this->encode_part($part) . "\n\n";
         }
         $body_text .= "\n--{$body_boundary}--\n";
         // if we have attachments
         $text_part = "\nThis is a multi-part message in MIME format.\n\n";
         if (!empty($options['attachments'])) {
             $attachment_boundary = "boundary." . $unique_hash . ".attachments";
             $header .= "Content-Type: multipart/mixed; boundary=\"{$attachment_boundary}\"";
             $text_part .= "--{$attachment_boundary}\n";
             $text_part .= "{$body_header}\n";
             $text_part .= $body_text;
             // going though them
             foreach ($options['attachments'] as $v) {
                 $text_part .= "--{$attachment_boundary}\n";
                 $text_part .= "Content-Type: {$v['type']}; name=\"{$v['name']}\"\n";
                 $text_part .= "Content-Transfer-Encoding: base64\n";
                 $text_part .= "Content-Disposition: attachment; filename=\"{$v['name']}\"\n\n";
                 $text_part .= $this->encode_part(['data' => $v['data'], 'encoding' => 'base64']);
             }
             $text_part .= "\n--{$attachment_boundary}--\n";
         } else {
             $header .= $body_header;
             $text_part .= $body_text;
         }
         $body = $text_part;
     }
     // trying to deliver
     if (mail($recepients['to'], $options['subject'], $body, $header)) {
         $result['success'] = true;
     } else {
         $result['error'][] = 'Could not deliver mail!';
     }
     return $result;
 }
示例#2
0
 /**
  * Get data as an array of rows
  *
  * @param array $options
  *		no_cache - if we need to skip caching
  *		search - array of search condition
  *		where - array of where conditions
  *		orderby - array of columns to sort by
  *		pk - primary key to be used by query
  *		columns - if we need to get certain columns
  *		limit - set this integer if we need to limit query
  * @return array
  */
 public function get($options = [])
 {
     $data = [];
     $this->acl_get_options = $options;
     // handle acl init
     if (!empty($options['acl'])) {
         $acl_key = get_called_class();
         if (factory::model('object_acl_class', true)->acl_init($acl_key, $data, $this->acl_get_options) === false) {
             return $data;
         }
         $options = $this->acl_get_options;
     }
     $options_query = [];
     // if we are caching
     if (!empty($this->cache) && empty($options['no_cache'])) {
         $options_query['cache'] = true;
     }
     $options_query['cache_tags'] = !empty($this->cache_tags) ? array_values($this->cache_tags) : [];
     $options_query['cache_tags'][] = $this->name;
     $sql = '';
     // pk
     $pk = array_key_exists('pk', $options) ? $options['pk'] : $this->pk;
     // preset columns
     if (!empty($options['__preset'])) {
         $columns = 'DISTINCT ';
         if (!empty($pk) && count($pk) > 1) {
             $temp = $pk;
             unset($temp[array_search('preset_value', $temp)]);
             $columns .= $this->db_object->prepare_expression($temp) . ', ';
         }
         $columns .= "concat_ws(' ', " . $this->db_object->prepare_expression($options['columns']) . ") preset_value";
         $sql .= ' AND coalesce(' . $this->db_object->prepare_expression($options['columns']) . ') IS NOT NULL';
         // if its a preset we cache
         $options_query['cache'] = true;
     } else {
         // regular columns
         if (!empty($options['columns'])) {
             $columns = $this->db_object->prepare_expression($options['columns']);
         } else {
             $columns = '*';
         }
     }
     // where
     $sql .= !empty($options['where']) ? ' AND ' . $this->db_object->prepare_condition($options['where']) : '';
     $sql .= !empty($options['search']) ? ' AND (' . $this->db_object->prepare_condition($options['search'], 'OR') . ')' : '';
     // order by
     $orderby = $options['orderby'] ?? (!empty($this->orderby) ? $this->orderby : null);
     if (!empty($orderby)) {
         $sql .= ' ORDER BY ' . array_key_sort_prepare_keys($orderby, true);
     }
     // limit
     if (!empty($options['limit'])) {
         $sql .= ' LIMIT ' . $options['limit'];
     } else {
         if (!empty($this->limit)) {
             $sql .= ' LIMIT ' . $this->limit;
         }
     }
     // querying
     $sql_full = 'SELECT ' . $columns . ' FROM ' . $this->name . ' a WHERE 1=1' . $sql;
     // memory caching
     if ($this->cache_memory) {
         // hash is query + primary key
         $crypt = new crypt();
         $sql_hash = $crypt->hash($sql_full . serialize($pk));
         if (isset(cache::$memory_storage[$sql_hash])) {
             return cache::$memory_storage[$sql_hash];
         }
     }
     $result = $this->db_object->query($sql_full, $pk, $options_query);
     if (!$result['success']) {
         throw new Exception(implode(", ", $result['error']));
     }
     if ($this->cache_memory) {
         cache::$memory_storage[$sql_hash] =& $result['rows'];
     }
     // single row
     if (!empty($options['single_row'])) {
         $data = current($result['rows']);
     } else {
         $data = $result['rows'];
     }
     // handle acl init
     if (!empty($options['acl'])) {
         if (factory::model('object_acl_class', true)->acl_finish($acl_key, $data, $this->acl_get_options) === false) {
             return $data;
         }
     }
     return $data;
 }
示例#3
0
 /**
  * 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);
 }
示例#4
0
 /**
  * This will run SQL query and return structured data
  *
  * @param string $sql
  * @param mixed $key
  * @param array $options
  * @return array
  */
 public function query($sql, $key = null, $options = [])
 {
     $result = ['success' => false, 'sql' => $sql, 'error' => [], 'errno' => 0, 'num_rows' => 0, 'affected_rows' => 0, 'rows' => [], 'key' => $key, 'structure' => [], 'time' => null, 'last_insert_id' => 0];
     // start time
     $result['time'] = debug::get_microtime();
     // cache id
     $crypt_object = new crypt();
     $cache_id = !empty($options['cache_id']) ? $options['cache_id'] : 'db_query_' . $crypt_object->hash($sql . serialize($key));
     // if we cache this query
     if (!empty($options['cache'])) {
         $cache_object = new cache($this->connect_options['cache_link']);
         $cached_result = $cache_object->get($cache_id);
         if ($cached_result !== false) {
             return $cached_result;
         }
     }
     // quering regular query first
     if (empty($options['multi_query'])) {
         $resource = mysqli_query($this->db_resource, $sql);
         if (!$resource) {
             $this->error_overrides($result, mysqli_errno($this->db_resource), mysqli_error($this->db_resource));
         } else {
             $result['affected_rows'] += mysqli_affected_rows($this->db_resource);
             if ($resource !== true) {
                 $result['num_rows'] += mysqli_num_rows($resource);
                 $result['structure'] = $this->field_structures($resource);
             }
             if ($result['num_rows'] > 0) {
                 while ($rows = mysqli_fetch_assoc($resource)) {
                     // casting types
                     $data = [];
                     foreach ($rows as $k => $v) {
                         $data[$k] = $this->process_value_as_per_type($v, $result['structure'][$k]['type']);
                     }
                     // assigning keys
                     if (!empty($key)) {
                         array_key_set_by_key_name($result['rows'], $key, $data);
                     } else {
                         $result['rows'][] = $data;
                     }
                 }
             }
             if ($resource !== true) {
                 mysqli_free_result($resource);
             }
             $result['success'] = true;
         }
     } else {
         // multi query
         $resource = mysqli_multi_query($this->db_resource, $sql);
         if (!$resource) {
             $result['error'][] = 'Db Link ' . $this->db_link . ': ' . mysqli_error($this->db_resource);
             $result['errno'] = mysqli_errno($this->db_resource);
             // we log this error message
             // todo: process log policy here
             error_log('Query error: ' . implode(' ', $result['error']) . ' [' . $sql . ']');
         } else {
             $result['affected_rows'] += mysqli_affected_rows($this->db_resource);
             do {
                 if ($result_multi = mysqli_store_result($this->db_resource)) {
                     if ($result_multi) {
                         $result['num_rows'] += $num_rows = mysqli_num_rows($result_multi);
                         $result['structure'] = $this->field_structures($result_multi);
                     } else {
                         $num_rows = 0;
                         $result['error'][] = 'Db Link ' . $this->db_link . ': Multi query error!';
                         $result['errno'] = 1;
                         // we log this error message
                         // todo: process log policy here
                         error_log('Query error: ' . implode(' ', $result['error']) . ' [' . $sql . ']');
                     }
                     if ($num_rows > 0) {
                         while ($rows = mysqli_fetch_assoc($result_multi)) {
                             // casting types
                             $data = [];
                             foreach ($rows as $k => $v) {
                                 $data[$k] = $this->process_value_as_per_type($v, $result['structure'][$k]['type']);
                             }
                             // assigning keys
                             if (!empty($key)) {
                                 array_key_set_by_key_name($result['rows'], $key, $data);
                             } else {
                                 $result['rows'][] = $data;
                             }
                         }
                     }
                     mysqli_free_result($result_multi);
                 }
             } while (mysqli_more_results($this->db_resource) && mysqli_next_result($this->db_resource));
             if (empty($result['error'])) {
                 $result['success'] = true;
             }
         }
     }
     // last insert id for auto increment columns
     $result['last_insert_id'] = mysqli_insert_id($this->db_resource);
     // caching if no error
     if (!empty($options['cache']) && empty($result['error'])) {
         $cache_object->set($cache_id, $result, ['tags' => $options['cache_tags'] ?? null]);
     }
     // end time
     $result['time'] = debug::get_microtime() - $result['time'];
     // if we are debugging
     if (debug::$debug) {
         debug::$data['sql'][] = $result;
     }
     return $result;
 }
示例#5
0
 /**
  * This will run SQL query and return structured data
  *
  * @param string $sql
  * @param mixed $key
  * @param array $options
  * @return array
  */
 public function query($sql, $key = null, $options = [])
 {
     $result = ['success' => false, 'sql' => $sql, 'error' => [], 'errno' => 0, 'num_rows' => 0, 'affected_rows' => 0, 'rows' => [], 'key' => $key, 'structure' => [], 'time' => null];
     // start time
     $result['time'] = debug::get_microtime();
     // cache id
     $crypt_object = new crypt();
     $cache_id = !empty($options['cache_id']) ? $options['cache_id'] : 'db_query_' . $crypt_object->hash($sql . serialize($key));
     // if we cache this query
     if (!empty($options['cache'])) {
         $cache_object = new cache($this->connect_options['cache_link']);
         $cached_result = $cache_object->get($cache_id);
         if ($cached_result !== false) {
             return $cached_result;
         }
     }
     // quering
     $resource = @pg_query($this->db_resource, $sql);
     $result['status'] = pg_result_status($resource);
     if (!$resource || $result['status'] > 4) {
         $last_error = pg_last_error($this->db_resource);
         if (empty($last_error)) {
             $errno = 1;
             $error = 'DB Link ' . $this->db_link . ': ' . 'Unspecified error!';
         } else {
             preg_match("|ERROR:\\s(.*?):|i", $last_error, $matches);
             $errno = !empty($matches[1]) ? $matches[1] : 1;
             $error = $last_error;
         }
         $this->error_overrides($result, $errno, $error);
     } else {
         $result['affected_rows'] = pg_affected_rows($resource);
         $result['num_rows'] = pg_num_rows($resource);
         $result['structure'] = $this->field_structures($resource);
         if ($result['num_rows'] > 0) {
             while ($rows = pg_fetch_assoc($resource)) {
                 // transforming pg arrays to php arrays and casting types
                 foreach ($rows as $k => $v) {
                     if ($result['structure'][$k]['type'][0] == '_') {
                         $rows[$k] = $this->pg_parse_array($v);
                     } else {
                         if (in_array($result['structure'][$k]['type'], ['int2', 'int4', 'int8'])) {
                             if (!is_null($v)) {
                                 $rows[$k] = (int) $v;
                             }
                         } else {
                             if (in_array($result['structure'][$k]['type'], ['real', 'double precision'])) {
                                 if (!is_null($v)) {
                                     $rows[$k] = (double) $v;
                                 }
                             } else {
                                 if ($result['structure'][$k]['type'] == 'bytea') {
                                     $rows[$k] = pg_unescape_bytea($v);
                                 } else {
                                     if ($result['structure'][$k]['type'] == 'jsonb') {
                                         // we must get json vallues to PHP format
                                         $rows[$k] = json_encode(json_decode($v, true));
                                     }
                                 }
                             }
                         }
                     }
                 }
                 // assigning keys
                 if (!empty($key)) {
                     array_key_set_by_key_name($result['rows'], $key, $rows);
                 } else {
                     $result['rows'][] = $rows;
                 }
             }
         }
         pg_free_result($resource);
         $result['success'] = true;
     }
     // caching if no error
     if (!empty($options['cache']) && empty($result['error'])) {
         $cache_object->set($cache_id, $result, ['tags' => $options['cache_tags'] ?? []]);
     }
     // end time
     $result['time'] = debug::get_microtime() - $result['time'];
     // if we are debugging
     if (debug::$debug) {
         debug::$data['sql'][] = $result;
     }
     return $result;
 }