<?php
/*
 * @version			$Id: index.php 10381 2008-06-01 03:35:53Z $
 * @package			Carteasy
 * @copyright		Copyright (C) 2005 - 2011 Wlanium
 * @license			proprietary
 * @author			Thomas Bartelt
 * Carteasy is a web shop system
 */

class Main {

	protected $db;

	public function __construct($base_object) {
		$this->db = $base_object->db;
	}

	public function get_list_items($setting) {
		// init rewrite functions
		$rewrite_indexes = array();
		$format_indexes = array();
		$count_fields = count($this->list_table_config['list_fields']);
		for ($i=0;$i<$count_fields;$i++) {
			if (isset($this->list_table_config['list_fields'][$i]['rewrite_function'])) {
				$this->list_table_config['list_fields'][$i]['rewrite_function'] = $this->{$this->list_table_config['list_fields'][$i]['rewrite_function']}();
				$rewrite_indexes[] = $i;
			}
			if ($setting['data_format'] == 1 && isset($this->list_table_config['list_fields'][$i]['format'])) {
				$format_indexes[] = $i;
			}
		}

		$data = array();
		$filter_sql = '';
		// search
		if (isset($setting['search_string']) && $setting['search_string'] != '') {
			$count_search_fields = count($this->list_table_config['search_fields']);
			for ($i=0;$i<$count_search_fields;$i++) {
				if ($i == 0) {
					$filter_sql .= $this->list_table_config['search_fields'][$i]." like '%".$setting['search_string']."%'";
				} else {
					$filter_sql .= " || ".$this->list_table_config['search_fields'][$i]." like '%".$setting['search_string']."%'";
				}
			}
			if ($filter_sql) {
				$filter_sql = '('.$filter_sql.')';
			}
		}


		// list filter
		$list_filter = '';
		if (isset($this->list_table_config['list_filter']) && $this->list_table_config['list_filter']) {
			foreach ($this->list_table_config['list_filter'] as $filter_item) {
				if (isset($setting['list_filter'][$filter_item['db_field']])) {
					if (isset($filter_item['relational_operator'])) {
						if ($list_filter) {
							$list_filter .= " AND ".$filter_item['db_field']." ".$filter_item['relational_operator']." '".$setting['list_filter'][$filter_item['db_field']]."'";
						} else {
							$list_filter .= $filter_item['db_field']." ".$filter_item['relational_operator']." '".$setting['list_filter'][$filter_item['db_field']]."'";
						}
					} else {
						if ($list_filter) {
							$list_filter .= " AND ".$filter_item['db_field']." ".$setting['list_filter'][$filter_item['db_field']];
						} else {
							$list_filter .= $filter_item['db_field']." ".$setting['list_filter'][$filter_item['db_field']];
						}
					}
				}
			}

			if ($list_filter) {
				$list_filter = '('.$list_filter.')';
			}

		}

		if (isset($this->list_table_config['permanent_filter']) && $this->list_table_config['permanent_filter']) {
			foreach ($this->list_table_config['permanent_filter'] as $filter_item) {
				if ($list_filter) {
					$list_filter .= " AND ";
				}

				if (isset($filter_item['accept_null']) && $filter_item['accept_null'] == 1) {
					$list_filter .= '('.$filter_item['db_field']." ".$filter_item['relational_operator']." '".$filter_item['value']."' OR ".$filter_item['db_field']." IS NULL)";
				} else {
					$list_filter .= $filter_item['db_field']." ".$filter_item['relational_operator']." '".$filter_item['value']."'";
				}
			}

		}

		if ($list_filter) {
			if ($filter_sql) {
				$filter_sql  .= ' AND ('.$list_filter.')';
			} else {
				$filter_sql  = ' ('.$list_filter.') ';
			}
		}

		// group by
		$group_by = '';
		if (isset($this->list_table_config['list_group_by']) && $this->list_table_config['list_group_by']) {
			$group_by = ' GROUP BY '.$this->list_table_config['db_table'].'.'.$this->list_table_config['list_group_by'];
		}

		$select_fields = ' '.$this->list_table_config['db_table'].'.'.$this->list_table_config['db_id_field'].' as object_id';
		$count_fields = count($this->list_table_config['list_fields']);


		// ref tables
		$ref_tables = array();
		for ($i=0;$i<$count_fields;$i++) {
			if (isset($this->list_table_config['list_fields'][$i]['ref_db_table'])) {
				if (isset($this->list_table_config['list_fields'][$i]['function']) && $this->list_table_config['list_fields'][$i]['function'] == 'count') {
					$select_fields .= ', count('.$this->list_table_config['list_fields'][$i]['ref_db_table'].'.'.$this->list_table_config['list_fields'][$i]['db_field'].')';
				} else {
					$select_fields .= ', '.$this->list_table_config['list_fields'][$i]['ref_db_table'].'.'.$this->list_table_config['list_fields'][$i]['db_field'];
				}
				$ref_tables[$this->list_table_config['list_fields'][$i]['ref_db_table']] = $this->list_table_config['db_table'].'.'.$this->list_table_config['list_fields'][$i]['ref_db1_field'].'='.$this->list_table_config['list_fields'][$i]['ref_db_table'].'.'.$this->list_table_config['list_fields'][$i]['ref_db2_field'];
			} else {
				if (isset($this->list_table_config['list_fields'][$i]['function']) && $this->list_table_config['list_fields'][$i]['function'] == 'count') {
					$select_fields .= ', count('.$this->list_table_config['db_table'].'.'.$this->list_table_config['list_fields'][$i]['db_field'].')';
				} else {
					$select_fields .= ', '.$this->list_table_config['db_table'].'.'.$this->list_table_config['list_fields'][$i]['db_field'];
				}
			}
		}
		$ref_tables_string = '';
		foreach ($ref_tables as $key => $value) {
			$ref_tables_string .= ' LEFT JOIN '.$key.' ON '.$value;
		}

		/* old code:
		$ref_tables_string = '';
		$multitable = '';
		foreach ($ref_tables as $key => $value) {
			$ref_tables_string .= ', '.$key;
			if ($multitable) {
				$multitable .= ' AND '.$value;
			} else {
				$multitable .= $value;
			}
		}
		if ($multitable) {
			if ($filter_sql) {
				$filter_sql = $filter_sql.' AND ('.$multitable.')';
			} else {
				$filter_sql = $multitable;
			}
		}
		*/
		if ($filter_sql) {
			$filter_sql = ' WHERE '.$filter_sql;
		}


		// get count items
		$sql = "SELECT COUNT(distinct(".$this->list_table_config['db_table'].'.'.$this->list_table_config['db_id_field'].")) FROM ".$this->list_table_config['db_table'].$ref_tables_string.$filter_sql;
		$result = $this->db->query($sql);
		if ($this->db->error) {
			$log_object = Logger::get_instance();
			$log_object->info('Error in /core/main_class.php->get_list_items()', $this->db->error.', sql:'.$sql);
			$count = 0;
		} else {
			$count = $result->fetch_array();
		}
		$data['count_list_items'] = $count[0];
		$data['count_pages'] = (int)ceil($data['count_list_items'] / $setting['max_list_items']);
		if ($data['count_pages'] < 1) {
			$data['count_pages'] = 1;
		}
		if ($data['count_pages'] < $setting['actual_page']) {
			$setting['actual_page'] = $data['count_pages'];
		}
		if ($setting['actual_page'] < 1) {
			$setting['actual_page'] = 1;
		}


		$sql = "SELECT ".$select_fields." FROM ".$this->list_table_config['db_table'].$ref_tables_string.$filter_sql.$group_by;

		// set order
		if (isset($setting['sort_item']) && $setting['sort_item'] && isset($setting['sort_direction'])) {
			if ($setting['sort_direction'] == 'up') {
				$sql .= " ORDER BY ".$setting['sort_item']." ASC ";
			} else {
				$sql .= " ORDER BY ".$setting['sort_item']." DESC ";
			}
		} else if (isset($this->list_table_config['default_sort_item'])) {
			if (isset($this->list_table_config['default_sort_direction']) && $this->list_table_config['default_sort_direction'] == 'up') {
				$sql .= " ORDER BY ".$this->list_table_config['default_sort_item']." ASC ";
			}
			else {
				$sql .= " ORDER BY ".$this->list_table_config['default_sort_item']." DESC ";
			}
		}

		// set limit
		if (isset($setting['max_list_items']) && isset($setting['actual_page'])) {
			if ($setting['actual_page'] == 1) {
				$sql .= " LIMIT 0, ".$this->db->real_escape_string($setting["max_list_items"]);
			} else {
				$start = (($setting['actual_page'] - 1) * $setting['max_list_items']);
				$sql .= " LIMIT ".$start.', '.$this->db->real_escape_string($setting['max_list_items']);
			}

		}
		$data['actual_page'] = $setting['actual_page'];
		$data['sort_item'] = $setting['sort_item'];
		$data['sort_direction'] = $setting['sort_direction'];
		$result = $this->db->query($sql);
		//echo $sql;exit();
		if ($this->db->error) {
			$log_object = Logger::get_instance();
			$log_object->info('Error in /core/main_class.php->get_list_items()', $this->db->error.', sql:'.$sql);
		}

		$data['list_items'] = array();
		if ($result) {
			while ($row = $result->fetch_assoc()) {
				// rewrite result
				if ($rewrite_indexes) {
					foreach ($rewrite_indexes as $index) {
						$db_field = $this->list_table_config['list_fields'][$index]['db_field'];
						$field_value = isset($row[$db_field]) ? $row[$db_field] : '';
						// Handle NULL/empty values - use '0' key for empty structure_id
						if ($field_value === '' || $field_value === null) {
							$field_value = '0';
						}
						if (isset($this->list_table_config['list_fields'][$index]['rewrite_function'][$field_value])) {
							$row[$db_field] = $this->list_table_config['list_fields'][$index]['rewrite_function'][$field_value];
						}
					}
				}

				// string formating
				if ($format_indexes) {
					foreach ($format_indexes as $index) {
						if (isset($this->list_table_config['list_fields'][$index]['db_field_rename'])) {
							$this->list_table_config['list_fields'][$index]['db_field'] = $this->list_table_config['list_fields'][$index]['db_field_rename'];
						}
						$row[$this->list_table_config['list_fields'][$index]['db_field']] = $this->{$this->list_table_config['list_fields'][$index]['format']}($row[$this->list_table_config['list_fields'][$index]['db_field']]);
					}
				}

				$data['list_items'][] = $row;
			}
		}

		return $data;
	}

	public function load($object_id) {
		$sql = "
			SELECT * 
			FROM ".$this->list_table_config['db_table']."
			WHERE ".$this->list_table_config['db_id_field']."='".$this->db->real_escape_string($object_id)."'";
		$result = $this->db->query($sql);
		if ($this->db->error) {
			$log_object = Logger::get_instance();
			$log_object->info('Error in /core/main_class.php->load()', $this->db->error.', sql:'.$sql);
			return false;
		}
		$data = $result->fetch_array();
		return $data;
	}

	public function save($data, $object_id = false) {
		if ($data) {
			if ($object_id) {
				// get old data
				$old_data = $this->load($object_id);

				// update in database
				$sql = "UPDATE ".$this->list_table_config['db_table']."
				SET ";

				// check data
				$object_data = array();
				$events = array();
				foreach ($this->list_table_config['edit_fields'] as $edit_field) {
					// quote values
					$correct = 0;
					if (isset($edit_field['auto_value'])) {
						$edit_field['auto_value']['func_param']['object_id'] = $object_id;
						$edit_field['auto_value']['func_param']['db_field'] = $edit_field['db_field'];
						$edit_field['auto_value']['func_param']['data'] = $data;
						$data[$edit_field['db_field']] = $this->{$edit_field['auto_value']['function']}($edit_field['auto_value']['func_param']);
					}
					if (isset($data[$edit_field['db_field']]) && !isset($edit_field['function'])) {
						if ($edit_field['type'] == 'text') {
							$sql .= $edit_field['db_field'].'="'.$this->db->real_escape_string($data[$edit_field['db_field']]).'", ';
							$correct = 1;
						} else if ($edit_field['type'] == 'multitext') {
							$sql .= $edit_field['db_field'].'="'.$this->db->real_escape_string($data[$edit_field['db_field']]).'", ';
							$correct = 1;
						} else if ($edit_field['type'] == 'formatedtext') {
							$sql .= $edit_field['db_field'].'="'.$this->db->real_escape_string($data[$edit_field['db_field']]).'", ';
							$correct = 1;
						} else if ($edit_field['type'] == 'int' && $data[$edit_field['db_field']] != '') {
							$sql .= $edit_field['db_field'].'='.$this->db->real_escape_string($data[$edit_field['db_field']]).', ';
							$correct = 1;
						} else if ($edit_field['type'] == 'float' && $data[$edit_field['db_field']] != '') {
							$sql .= $edit_field['db_field'].'='.$this->db->real_escape_string($data[$edit_field['db_field']]).', ';
							$correct = 1;
						}
					}

					// change actions
					if (isset($edit_field['change_function']) && $correct == 1 && $old_data[$edit_field['db_field']] != $data[$edit_field['db_field']]) {
						$events[] = array(
							'action' => 'change',
							'object_id' => $object_id,
							'function' => $edit_field['change_function'],
							'db_field' => $edit_field['db_field'],
							'old_value' => $old_data[$edit_field['db_field']],
							'new_value' => $data[$edit_field['db_field']]
						);
					}
				}
				$sql = substr($sql, 0, -2);
				$sql .= ' WHERE '.$this->list_table_config['db_id_field']."='".$this->db->real_escape_string($object_id)."'";
				$this->db->query($sql);
				if ($this->db->error) {
					$log_object = Logger::get_instance();
					$log_object->info('Error in /core/main_class.php->save() (update)', $this->db->error.', sql:'.$sql);
					return false;
				}
				// event actions
				if ($events) {
					$this->event_actions($events);
				}

				// already saved
				return true;
			} else {
				// create in database
				$sql = "INSERT INTO ".$this->list_table_config['db_table']."
				SET ";

				// check data
				$object_data = array();
				foreach ($this->list_table_config['edit_fields'] as $edit_field) {

					if (isset($edit_field['auto_value'])) {
						$edit_field['auto_value']['func_param']['db_field'] = $edit_field['db_field'];
						$edit_field['auto_value']['func_param']['data'] = $data;
						$data[$edit_field['db_field']] = $this->{$edit_field['auto_value']['function']}($edit_field['auto_value']['func_param']);
					}
					if (isset($data[$edit_field['db_field']]) && !isset($edit_field['function'])) {
						if ($edit_field['type'] == 'text') {
							$sql .= $edit_field['db_field'].'="'.$this->db->real_escape_string($data[$edit_field['db_field']]).'", ';
						} else if ($edit_field['type'] == 'multitext') {
							$sql .= $edit_field['db_field'].'="'.$this->db->real_escape_string($data[$edit_field['db_field']]).'", ';
						} else if ($edit_field['type'] == 'formatedtext') {
							$sql .= $edit_field['db_field'].'="'.$this->db->real_escape_string($data[$edit_field['db_field']]).'", ';
							$correct = 1;
						} else if ($edit_field['type'] == 'int') {
							$sql .= $edit_field['db_field'].'='.$this->db->real_escape_string($data[$edit_field['db_field']]).', ';
						} else if ($edit_field['type'] == 'create_time') {
							$sql .= $edit_field['db_field']."=CURRENT_TIMESTAMP, ";
						} else if ($edit_field['type'] == 'float') {
							$sql .= $edit_field['db_field'].'='.$this->db->real_escape_string($data[$edit_field['db_field']]).', ';
						}
					}
				}
				$sql = substr($sql, 0, -2);
				$this->db->query($sql);
				if ($this->db->error) {
					$log_object = Logger::get_instance();
					$log_object->info('Error in /core/main_class.php->save() (insert)', $this->db->error.', sql:'.$sql);
					return false;
				}
				if ($this->list_table_config['db_id_field'] == 'id') {
					$object_id = $this->db->insert_id;
				} else if (!is_int($data[$this->list_table_config['db_id_field']])) {
					$object_id =  $data[$this->list_table_config['db_id_field']];
				} else {
					$object_id = $this->db->insert_id;
				}

				// event actions
				if (isset($this->list_table_config['new_function'])) {
					$event = array(
						'action' => 'new',
						'object_id' => $object_id,
						'function' => $this->list_table_config['new_function']
					);
					$this->event_actions($event);
				}
				return $object_id;
			}
		} else {
			// no data to save
			$log_object = Logger::get_instance();
			$log_object->info('Error in /core/main_class.php->save()', 'No data to save!');
			return false;
		} 
	}

	public function remove($object_id) {
			$sql = "DELETE FROM ".$this->list_table_config['db_table']."
					WHERE ".$this->list_table_config['db_id_field']."='".$this->db->real_escape_string($object_id)."'";
			$this->db->query($sql);
			if ($this->db->error) {
				$log_object = Logger::get_instance();
				$log_object->info('Error in /core/main_class.php->remove()', $this->db->error.', sql:'.$sql);
				return 0;
			}
			return 1;

			/*delete customer_addresses->customer_id
			delete customer_files->customer_id
			delete tickets->customer_id and tickt_messages->ticket_id and ticket_messages_attachments->ticket_message_id
			delete customer*/
	}

	public function init_edit_fields($object_id) {
		// rewrite indexes
		$rewrite_indexes = array();
		$count_fields = count($this->list_table_config['edit_fields']);
		for ($i=0;$i<$count_fields;$i++) {
			if (isset($this->list_table_config['edit_fields'][$i]['values'])) {
				$this->list_table_config['edit_fields'][$i]['values'] = $this->{$this->list_table_config['edit_fields'][$i]['values']}();
				$rewrite_indexes[] = $i;
			}
		}
		// init languages
		if ($this->list_table_config['edit_toolbar']['language']) {
			$this->list_table_config['edit_toolbar']['language'] = array('de' => 'Deutsch', 'en' => 'English');
		}
		return;
	}

	public function get_all_selectable() {
		$sql = "SELECT ".$this->list_table_config['db_id_field']." AS id, ".$this->list_table_config['db_selectable_field']." AS value FROM ".$this->list_table_config['db_table'];
		$result = $this->db->query($sql);
		if ($this->db->error) {
			$log_object = Logger::get_instance();
			$log_object->info('Error in /core/main_class.php->get_select_array()', $this->db->error.', sql:'.$sql);
		}

		$data = array(0 => '-');
		if ($result) {
			while ($row = $result->fetch_object()) {
				$data[$row->id] = $row->value;
			}
		}
		return $data;
	}

	public function get_all_objects() {
		$sql = "SELECT * FROM ".$this->list_table_config['db_table'];
		$result = $this->db->query($sql);
		if ($this->db->error) {
			$log_object = Logger::get_instance();
			$log_object->info('Error in /core/main_class.php->get_select_array()', $this->db->error.', sql:'.$sql);
		}

		$data = array();
		if ($result) {
			while ($row = $result->fetch_object()) {
				$data[] = $row;
			}
		}
		return $data;
	}

	function get_filter() {
		$data = array();
		if (isset($this->list_table_config['list_filter']) && $this->list_table_config['list_filter']) {
			foreach ($this->list_table_config['list_filter'] as $filter_item) {
				$filter_item['values'] = $this->{$filter_item['values']}();
				$data[] = $filter_item;
			}
		}
		return $data;
	}

	function get_actions() {
		$data = array();
		if (isset($this->list_table_config['list_actions']) && $this->list_table_config['list_actions']) {
			foreach ($this->list_table_config['list_actions'] as $filter_item) {
				$filter_item['values'] = $this->{$filter_item['values']}();
				$data[] = $filter_item;
			}
		}
		return $data;
	}

	private function event_actions($events) {
		foreach ($events as $event) { 
		 	$this->{$event['function']}($event);
		}
		return 1;
	}

	public function short_uri($param) {
		$short_uri = ($param['data'][$param['db_field']]) ? $param['data'][$param['db_field']] : $param['data'][$param['default']];
		$short_uri = str_replace(array('ä', 'Ä', 'ö', 'Ö', 'ü', 'Ü', 'ß'), array('ae', 'Ae', 'oe', 'Oe', 'ue', 'Ue', 'ss'), $short_uri);
		$short_uri = preg_replace("@[^0-9aA-zZ\-]@si", "-", $short_uri);
		$short_uri = preg_replace("@(-{2,})@si", "-", $short_uri);
		$new_uri = '';
		$old_uri = $short_uri;

		if (isset($param['object_id'])) {
			$sql = "SELECT ".$this->list_table_config['db_id_field']." FROM ".$this->list_table_config['db_table']." WHERE ".$param['db_field']." = '".$short_uri."' AND id != ".$param['object_id'];
		} else {
			$sql = "SELECT ".$this->list_table_config['db_id_field']." FROM ".$this->list_table_config['db_table']." WHERE ".$param['db_field']." = '".$short_uri."'";
		}
		$result = $this->db->query($sql);
		if ($this->db->error) {
			$log_object = Logger::get_instance();
			$log_object->info('Error in /core/main_class.php->short_uri()', $this->db->error.', sql:'.$sql);
			return false;
		}
		if ($result->num_rows > 0) {
			if ($param['object_id']) {
				$short_uri .= $param['object_id'];
			} else {
				$short_uri .= rand(10000, 99999);
			}
		}
		return $short_uri;
	}

}
