db->where('id', $id); return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'customfields')->row(); } return $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'customfields')->result_array(); } /** * Add new custom field * @param mixed $data All $_POST data * @return boolean */ public function add($data, $playground = false) { if (isset($data['disabled'])) { $data['active'] = 0; unset($data['disabled']); } else { $data['active'] = 1; } if (isset($data['show_on_pdf'])) { if (in_array($data['fieldto'], $this->pdf_fields)) { $data['show_on_pdf'] = 1; } else { $data['show_on_pdf'] = 0; } } else { $data['show_on_pdf'] = 0; } if (isset($data['required'])) { $data['required'] = 1; } else { $data['required'] = 0; } if (isset($data['disalow_client_to_edit'])) { $data['disalow_client_to_edit'] = 1; } else { $data['disalow_client_to_edit'] = 0; } if (isset($data['show_on_table'])) { $data['show_on_table'] = 1; } else { $data['show_on_table'] = 0; } if (isset($data['only_admin'])) { $data['only_admin'] = 1; } else { $data['only_admin'] = 0; } if (isset($data['show_on_client_portal'])) { if (in_array($data['fieldto'], $this->client_portal_fields)) { $data['show_on_client_portal'] = 1; } else { $data['show_on_client_portal'] = 0; } } else { $data['show_on_client_portal'] = 0; } if ($data['field_order'] == '') { $data['field_order'] = 0; } $data['slug'] = slug_it($data['fieldto'] . '_' . $data['name'], ['separator' => '_', ]); $slugs_total = total_rows(db_prefix() . ($playground ? 'playground_' : '') . 'customfields', ['slug' => $data['slug']]); if ($slugs_total > 0) { $data['slug'].= '_' . ($slugs_total + 1); } if ($data['fieldto'] == 'company') { $data['show_on_pdf'] = 1; $data['show_on_client_portal'] = 1; $data['show_on_table'] = 1; $data['only_admin'] = 0; $data['disalow_client_to_edit'] = 0; } else if ($data['fieldto'] == 'items') { $data['show_on_pdf'] = 1; $data['show_on_client_portal'] = 1; $data['show_on_table'] = 1; $data['only_admin'] = 0; $data['disalow_client_to_edit'] = 0; } $this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'customfields', $data); $insert_id = $this->db->insert_id(); if ($insert_id) { log_activity('New Custom Field Added [' . $data['name'] . ']'); return $insert_id; } return false; } /** * Update custom field * @param mixed $data All $_POST data * @return boolean */ public function update($data, $id, $playground = false) { $original_field = $this->get($id, $playground); if (isset($data['disabled'])) { $data['active'] = 0; unset($data['disabled']); } else { $data['active'] = 1; } if (isset($data['disalow_client_to_edit'])) { $data['disalow_client_to_edit'] = 1; } else { $data['disalow_client_to_edit'] = 0; } if (isset($data['only_admin'])) { $data['only_admin'] = 1; } else { $data['only_admin'] = 0; } if (isset($data['required'])) { $data['required'] = 1; } else { $data['required'] = 0; } if (isset($data['show_on_pdf'])) { if (in_array($data['fieldto'], $this->pdf_fields)) { $data['show_on_pdf'] = 1; } else { $data['show_on_pdf'] = 0; } } else { $data['show_on_pdf'] = 0; } if ($data['field_order'] == '') { $data['field_order'] = 0; } if (isset($data['show_on_client_portal'])) { if (in_array($data['fieldto'], $this->client_portal_fields)) { $data['show_on_client_portal'] = 1; } else { $data['show_on_client_portal'] = 0; } } else { $data['show_on_client_portal'] = 0; } if (isset($data['show_on_table'])) { $data['show_on_table'] = 1; } else { $data['show_on_table'] = 0; } if (!isset($data['display_inline'])) { $data['display_inline'] = 0; } if (!isset($data['show_on_ticket_form'])) { $data['show_on_ticket_form'] = 0; } if ($data['fieldto'] == 'company') { $data['show_on_pdf'] = 1; $data['show_on_client_portal'] = 1; $data['show_on_table'] = 1; $data['only_admin'] = 0; $data['disalow_client_to_edit'] = 0; } else if ($data['fieldto'] == 'items') { $data['show_on_pdf'] = 1; $data['show_on_client_portal'] = 1; $data['show_on_table'] = 1; $data['only_admin'] = 0; $data['disalow_client_to_edit'] = 0; } $this->db->where('id', $id); $this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'customfields', $data); if ($this->db->affected_rows() > 0) { log_activity('Custom Field Updated [' . $data['name'] . ']'); if ($data['type'] == 'checkbox' || $data['type'] == 'select' || $data['type'] == 'multiselect') { if (trim($data['options']) != trim($original_field->options)) { $options_now = explode(',', $data['options']); foreach ($options_now as $key => $val) { $options_now[$key] = trim($val); } $options_before = explode(',', $original_field->options); foreach ($options_before as $key => $val) { $options_before[$key] = trim($val); } $removed_options_in_use = []; foreach ($options_before as $option) { if (!in_array($option, $options_now) && total_rows(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues', ['fieldid' => $id, 'value' => $option, ])) { array_push($removed_options_in_use, $option); } } if (count($removed_options_in_use) > 0) { $this->db->where('id', $id); $this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'customfields', ['options' => implode(',', $options_now) . ',' . implode(',', $removed_options_in_use), ]); return ['cant_change_option_custom_field' => true, ]; } } } return true; } return false; } /** * @param integer * @return boolean * Delete Custom fields * All values for this custom field will be deleted from database */ public function delete($id, $playground = false) { $this->db->where('id', $id); $this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'customfields'); if ($this->db->affected_rows() > 0) { // Delete the values $this->db->where('fieldid', $id); $this->db->delete(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues'); log_activity('Custom Field Deleted [' . $id . ']'); return true; } return false; } public function get_custom_data($data, $custom_field_type, $id = '', $is_invoice_item = false, $playground = false) { $this->db->where('active', 1); $this->db->where('fieldto', $custom_field_type); $this->db->order_by('field_order', 'asc'); $fields = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'customfields')->result_array(); $customfields = []; if ('' === $id) { foreach ($data as $data_key => $value) { $data[$data_key]['customfields'] = []; $value_id = $value['id'] ?? ''; if ('customers' == $custom_field_type) { $value_id = $value['userid']; } if ('tickets' == $custom_field_type) { $value_id = $value['ticketid']; } if ('staff' == $custom_field_type) { $value_id = $value['staffid']; } foreach ($fields as $key => $field) { $customfields[$key] = new StdClass(); $customfields[$key]->label = $field['name']; if ('items' == $custom_field_type && !$is_invoice_item) { $custom_field_type = 'items_pr'; $value_id = $value['itemid'] ?? $value['id']; } $customfields[$key]->value = $this->custom_fields_model->get_custom_field_value($value_id, $field['id'], $custom_field_type, false, $playground); } $data[$data_key]['customfields'] = $customfields; } } if ('' !== $id && is_numeric($id)) { $data->customfields = new StdClass(); foreach ($fields as $key => $field) { $customfields[$key] = new StdClass(); $customfields[$key]->label = $field['name']; if ('items' == $custom_field_type && !$is_invoice_item) { $custom_field_type = 'items_pr'; } $customfields[$key]->value = $this->custom_fields_model->get_custom_field_value($id, $field['id'], $custom_field_type, false, $playground); } $data->customfields = $customfields; } return $data; } /** * Change custom field status / active / inactive * @param mixed $id customfield id * @param integer $status active or inactive */ public function change_custom_field_status($id, $status, $playground = false) { $this->db->where('id', $id); $this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'customfields', ['active' => $status, ]); log_activity('Custom Field Status Changed [FieldID: ' . $id . ' - Active: ' . $status . ']'); } public function get_relation_data_api($type, $search = '', $playground = false) { $q = ''; if ('' != $search) { $q = $search; $q = trim(urldecode($q)); } $this->load->model('clients_model'); $this->load->model('misc_model'); $this->load->model('payment_modes_model'); $data = []; if ('customer' == $type || 'customers' == $type) { $where_clients = db_prefix() . ($playground ? 'playground_' : '') . 'clients.active=1'; if ($q) { $where_clients .= ' AND ('; $where_clients .= 'company LIKE "%'.$q.'%" OR CONCAT(firstname, " ", lastname) LIKE "%'.$q.'%" OR email LIKE "%'.$q.'%"'; $fields = $this->get_custom_fields('customers', [], false, $playground); foreach ($fields as $key => $value) { $this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues as ctable_'.$key.'', db_prefix() . ($playground ? 'playground_' : '') . 'clients.userid = ctable_'.$key.'.relid and ctable_'.$key.'.fieldto="customers" AND ctable_'.$key.'.fieldid='.$value['id'], 'LEFT'); $where_clients .= ' OR ctable_'.$key.'.value LIKE "%'.$q.'%"'; } $where_clients .= ')'; } $data = $this->clients_model->get('', $where_clients); } else if ('contacts' == $type) { $where_clients = db_prefix() . ($playground ? 'playground_' : '') . 'clients.active=1'; if ($q) { $where_clients .= ' AND ('; $where_clients .= ' company LIKE "%'.$this->db->escape_like_str($q).'%" ESCAPE \'!\' OR CONCAT(firstname, " ", lastname) LIKE "%'.$this->db->escape_like_str($q).'%" ESCAPE \'!\' OR email LIKE "%'.$this->db->escape_like_str($q).'%" ESCAPE \'!\''; $fields = $this->get_custom_fields('contacts', [], false, $playground); foreach ($fields as $key => $value) { $this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues as ctable_'.$key.'', db_prefix() . ($playground ? 'playground_' : '') . 'contacts.id = ctable_'.$key.'.relid and ctable_'.$key.'.fieldto="contacts" AND ctable_'.$key.'.fieldid='.$value['id'], 'LEFT'); $where_clients .= ' OR ctable_'.$key.'.value LIKE "%'.$q.'%"'; } $where_clients .= ') AND '.db_prefix() . ($playground ? 'playground_' : '') . 'clients.active = 1'; } $this->db->select('contacts.id AS id,clients.*,contacts.*'); $this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'clients', ''.db_prefix() . ($playground ? 'playground_' : '') . 'contacts.userid = '.db_prefix() . ($playground ? 'playground_' : '') . 'clients.userid', 'left'); $data = $this->clients_model->get_contacts('', $where_clients, [], $playground); // echo $this->db->last_query(); } else if ('ticket' == $type) { $search = $this->_search_tickets($q, 0, true, $playground); $data = $search['result']; } else if ('lead' == $type || 'leads' == $type) { $search = $this->_search_leads($q, 0, ['junk' => 0,], true, $playground); $data = $search['result']; } else if ('invoice' == $type || 'invoices' == $type) { $search = $this->_search_invoices($q, 0, [], true, $playground); $data = $search['result']; } else if ('invoice_items' == $type) { $fields = $this->get_custom_fields('items', [], false, $playground); $this->db->select('rate, items.id, description as name, long_description as subtext'); $this->db->like('description', $q); $this->db->or_like('long_description', $q); foreach ($fields as $key => $value) { $this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues as ctable_'.$key.'', db_prefix() . ($playground ? 'playground_' : '') . 'items.id = ctable_'.$key.'.relid and ctable_'.$key.'.fieldto="items_pr" AND ctable_'.$key.'.fieldid='.$value['id'], 'LEFT'); $this->db->or_like('ctable_'.$key.'.value', $q); } $items = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'items')->result_array(); foreach ($items as $key => $item) { $items[$key]['subtext'] = strip_tags(mb_substr($item['subtext'], 0, 200)).'...'; $items[$key]['name'] = '('.app_format_number($item['rate']).') '.$item['name']; } $data = $items; } else if ('project' == $type) { $where_projects = ''; if ($this->input->post('customer_id')) { $where_projects .= '(clientid='.$this->input->post('customer_id').' or clientid in (select id from tblleads where client_id='.$this->input->post('customer_id').') )'; } if ($this->input->post('rel_type')) { $where_projects .= ' and rel_type="'.$this->input->post('rel_type').'" '; } $search = $this->misc_model->search_projects($q, 0, $where_projects, $this->input->post('rel_type'), $playground); $data = $search['result']; } else if ('staff' == $type) { $search = $this->misc_model->search_staff($q, 0, $playground); $data = $search['result']; } else if ('tasks' == $type) { $search = $this->misc_model->search_tasks($q, 0, $playground); $data = $search['result']; } else if ('payments' == $type) { $search = $this->payment_modes_model->search($q, 0, $playground); $data = $search['result']; } else if ('proposals' == $type) { $search = $this->misc_model->search_proposals($q, 0, $playground); $data = $search['result']; } else if ('estimates' == $type) { $search = $this->misc_model->search_estimates($q, 0, $playground); $data = $search['result']; } else if ('expenses' == $type) { $search = $this->misc_model->search_expenses($q, 0, $playground); $data = $search['result']; } else if ('creditnotes' == $type) { $search = $this->misc_model->search_credit_notes($q, 0, $playground); $data = $search['result']; } else if ('milestones' == $type) { $where_milestones = ''; if ($q) { $where_milestones .= '(name LIKE "%'.$q.'%" OR id LIKE "%'.$q.'%")'; } $data = $this->misc_model->get_milestones('', $where_milestones, $playground); } return $data; } /** * Check for custom fields, update on $_POST * @param mixed $rel_id the main ID from the table * @param array $custom_fields all custom fields with id and values * @return boolean */ public function handle_custom_fields_post($rel_id, $custom_fields, $is_cf_items = false, $playground = false) { $affectedRows = 0; foreach ($custom_fields as $key => $fields) { foreach ($fields as $field_id => $field_value) { $this->db->where('relid', $rel_id); $this->db->where('fieldid', $field_id); $this->db->where('fieldto', ($is_cf_items ? 'items_pr' : $key)); $row = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues')->row(); if (!is_array($field_value)) { $field_value = trim($field_value); } // Make necessary checkings for fields if (!defined('COPY_CUSTOM_FIELDS_LIKE_HANDLE_POST')) { $this->db->where('id', $field_id); $field_checker = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'customfields')->row(); if ($field_checker->type == 'date_picker') { $field_value = to_sql_date($field_value); } else if ($field_checker->type == 'date_picker_time') { $field_value = to_sql_date($field_value, true); } else if ($field_checker->type == 'textarea') { $field_value = nl2br($field_value); } else if ($field_checker->type == 'checkbox' || $field_checker->type == 'multiselect') { if ($field_checker->disalow_client_to_edit == 1 && is_client_logged_in()) { continue; } if (is_array($field_value)) { $v = 0; foreach ($field_value as $chk) { if ($chk == 'cfk_hidden') { unset($field_value[$v]); } $v++; } $field_value = implode(', ', $field_value); } } } if ($row) { $this->db->where('id', $row->id); $this->db->update(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues', [ 'value' => $field_value, ]); if ($this->db->affected_rows() > 0) { $affectedRows++; } } else { if ($field_value != '') { $this->db->insert(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues', [ 'relid' => $rel_id, 'fieldid' => $field_id, 'fieldto' => $is_cf_items ? 'items_pr' : $key, 'value' => $field_value, ]); $insert_id = $this->db->insert_id(); if ($insert_id) { $affectedRows++; } } } } } if ($affectedRows > 0) { return true; } return false; } /** * Get custom fields * @param string $field_to * @param array $where * @param boolean $exclude_only_admin * @return array */ public function get_custom_fields($field_to, $where = [], $exclude_only_admin = false, $playground = false) { $is_admin = is_admin(); $this->db->where('fieldto', $field_to); if ((is_array($where) && count($where) > 0) || (!is_array($where) && $where != '')) { $this->db->where($where); } if (!$is_admin || $exclude_only_admin == true) { $this->db->where('only_admin', 0); } $this->db->where('active', 1); $this->db->order_by('field_order', 'asc'); $results = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'customfields')->result_array(); foreach ($results as $key => $result) { $results[$key]['name'] = _maybe_translate_custom_field_name(e($result['name']), $result['slug']); } return $results; } /** * Get custom field value * @param mixed $rel_id the main ID from the table, e.q. the customer id, invoice id * @param mixed $field_id_or_slug field id, the custom field ID or custom field slug * @param string $field_to belongs to e.q leads, customers, staff * @param string $format format date values * @return string */ public function get_custom_field_value($rel_id, $field_id_or_slug, $field_to, $format = true, $playground = false) { $this->db->select(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues.value,' . db_prefix() . ($playground ? 'playground_' : '') . 'customfields.type'); $this->db->join(db_prefix() . ($playground ? 'playground_' : '') . 'customfields', db_prefix() . ($playground ? 'playground_' : '') . 'customfields.id=' . db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues.fieldid'); $this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues.relid', $rel_id); if (is_numeric($field_id_or_slug)) { $this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues.fieldid', $field_id_or_slug); } else { $this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'customfields.slug', $field_id_or_slug); } $this->db->where(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues.fieldto', $field_to); $row = $this->db->get(db_prefix() . ($playground ? 'playground_' : '') . 'customfieldsvalues')->row(); $result = ''; if ($row) { $result = $row->value; if ($format == true) { if ($row->type == 'date_picker') { $result = _d($result); } elseif ($row->type == 'date_picker_time') { $result = _dt($result); } } } return $result; } /** * Return field where Shown on PDF is allowed * @return array */ public function get_pdf_allowed_fields() { return $this->pdf_fields; } /** * Return fields where Show on customer portal is allowed * @return array */ public function get_client_portal_allowed_fields() { return $this->client_portal_fields; } /** * Return fields where are editable in customers area * @return array */ public function get_client_editable_fields() { return $this->client_editable_fields; } }