diff --git a/model/DomainHandler.php b/model/DomainHandler.php index 5def567f..4bffe3af 100644 --- a/model/DomainHandler.php +++ b/model/DomainHandler.php @@ -6,59 +6,6 @@ */ class DomainHandler extends PFAHandler { - protected $id = null; - protected $db_table = null; - protected $id_field = null; - protected $struct = array(); - protected $new = 0; # 1 on create, otherwise 0 - protected $values = array(); - protected $values_valid = false; - - public $errormsg = array(); - - # messages used in various functions - # (stored separately to make the functions reuseable) - protected $msg = array(); - - /** - * Constructor: fill $struct etc. - * @param string $new - */ - public function __construct($new = 0) { - if ($new) $this->new = 1; - $this->initStruct(); - $this->initMsg(); - } - - /** - * initialize with $id and check if it is valid - * @param string $id - */ - public function init($id) { - $this->id = strtolower($id); - - $exists = $this->view(false); - - if ($this->new) { - if ($exists) { - $this->errormsg[$this->id_field] = Lang::read($this->msg['error_already_exists']); - return false; - } elseif (!$this->validate_new_id() ) { - # errormsg filled by validate_new_id() - return false; - } else { - return true; - } - } else { # edit mode - if (!$exists) { - $this->errormsg[$this->id_field] = Lang::read($this->msg['error_does_not_exist']); - return false; - } else { - return true; - } - } - } - protected function validate_new_id() { $valid = check_domain($this->id); @@ -146,14 +93,6 @@ class DomainHandler extends PFAHandler { } } - public function getStruct() { - return $this->struct; - } - - public function getId_field() { - return $this->id_field; - } - public function getTransports() { return Config::read('transport_options'); } @@ -164,100 +103,6 @@ class DomainHandler extends PFAHandler { return $transports[$id-1]; } - public function set($values) { - # TODO: make this a generic function for add and edit - - if ($this->new == 1) { - $values[$this->id_field] = $this->id; - } - - # base validation - $this->values = array(); - $this->values_valid = false; - foreach($this->struct as $key=>$row) { - if ($row['editable'] == 0) { # not editable - if ($this->new == 1) { - $this->values[$key] = $row['default']; - } - } else { - if (isset($values[$key])) { - if ($row['type'] != "password" || strlen($values[$key]) > 0 || $this->new == 1) { # skip on empty (aka unchanged) password on edit - $valid = true; # trust input unless validator objects - - # validate based on field type (_inp_$type) - $func="_inp_".$row['type']; - if (method_exists($this, $func) ) { - if (!$this->{$func}($key, $values[$key])) $valid = false; - } else { - # TODO: warning if no validation function exists? - } - - # validate based on field name (_field_$fieldname) - $func="_field_".$key; - if (method_exists($this, $func) ) { - if (!$this->{$func}($key, $values[$key])) $valid = false; - } - - if ($valid) { - $this->values[$key] = $values[$key]; - } - } - } elseif ($this->new) { # new, field not set in input data - $this->errormsg[] = "field $key is missing"; - # echo "MISSING / not set: $key\n"; - } else { # edit, field unchanged - # echo "skipped / not set: $key\n"; - } - } - } - - if (count($this->errormsg) == 0) { - $this->values_valid = true; - } - return $this->values_valid; - } - - /** - * store $this->values in the database - * calls $this->storemore() where additional things can be done - */ - public function store() { - if ($this->values_valid == false) { - $this->errormsg[] = "one or more values are invalid!"; - return false; - } - - $db_values = $this->values; - - foreach(array_keys($db_values) as $key) { - switch ($this->struct[$key]['type']) { # modify field content for some types - case 'bool': - $db_values[$key] = db_get_boolean($db_values[$key]); - break; - # TODO: passwords -> pacrypt() - } - if ($this->struct[$key]['not_in_db'] == 1) unset ($db_values[$key]); # remove 'not in db' columns - if ($this->struct[$key]['dont_write_to_db'] == 1) unset ($db_values[$key]); # remove 'dont_write_to_db' columns - } - - if ($this->new) { - $result = db_insert($this->db_table, $db_values); - } else { - $result = db_update($this->db_table, $this->id_field, $this->id, $db_values); - } - if ($result != 1) { - $this->errormsg[] = Lang::read($this->msg['store_error']) . "\n(" . $this->id . ")\n"; # TODO: change message + use sprintf - return false; - } - - $result = $this->storemore(); - - if ($result) { - db_log ($this->id, $this->msg['logname'], ""); - } - return $result; - } - /** * called by $this->store() after storing $this->values in the database * can be used to update additional tables, call scripts etc. @@ -292,108 +137,6 @@ class DomainHandler extends PFAHandler { return true; # TODO: don't hardcode } - /** - * read_from_db - * @param array or string - condition (an array will be AND'ed using db_where_clause, a string will be directly used) - * @return array - rows - */ - protected function read_from_db($condition) { - $select_cols = array(); - - $yes = escape_string(Lang::read('YES')); - $no = escape_string(Lang::read('NO')); - - # TODO: replace hardcoded %Y-%m-%d with a country-specific date format via *.lang? - # TODO: (not too easy because pgsql uses a different formatstring format :-/ ) - if (Config::read('database_type') == 'pgsql') { - $formatted_date = "TO_DATE(text(###KEY###), 'YYYY-mm-dd')"; - } else { - $formatted_date = "DATE_FORMAT(###KEY###, '%Y-%m-%d')"; - } - - $colformat = array( - 'ts' => "$formatted_date AS ###KEY###, ###KEY### AS _###KEY###", - 'bool' => "CASE ###KEY### WHEN '" . db_get_boolean(true) . "' THEN '1' WHEN '" . db_get_boolean(false) . "' THEN '0' END as ###KEY###," . - "CASE ###KEY### WHEN '" . db_get_boolean(true) . "' THEN '$yes' WHEN '" . db_get_boolean(false) . "' THEN '$no' END as _###KEY###", - ); - - # get list of fields to display - $extrafrom = ""; - foreach($this->struct as $key=>$row) { - if ( $row['display_in_list'] != 0 && $row['not_in_db'] == 0 ) { - if ($row['select'] != '') $key = $row['select']; - - if ($row['extrafrom'] != '') $extrafrom = $extrafrom . " " . $row['extrafrom'] . "\n"; - - if (isset($colformat[$row['type']])) { - $select_cols[] = str_replace('###KEY###', $key, $colformat[$row['type']] ); - } else { - $select_cols[] = $key; - } - - } - } - - $cols = join(',', $select_cols); - $table = table_by_key($this->db_table); - - if (is_array($condition)) { - $where = db_where_clause($condition, $this->struct); - } else { - $where = " WHERE $condition "; - } - - $query = "SELECT $cols FROM $table $extrafrom $where ORDER BY " . $this->id_field; - $result = db_query($query); - - $db_result = array(); - if ($result['rows'] != 0) { - while ($row = db_assoc ($result['result'])) { - $db_result[] = $row; - } - } - - return $db_result; - } - - /** - * get the settings of a domain - * @param array or string $condition - * @return bool - true if at least one domain was found - * The data is stored in $this->return (as associative array of column => value) - */ - public function view($errors=true) { - $result = $this->read_from_db(array($this->id_field => $this->id) ); - if (count($result) == 1) { - $this->return = $result[0]; - return true; - } - - if ($errors) $this->errormsg[] = Lang::read($this->msg['error_does_not_exist']); -# $this->errormsg[] = $result['error']; - return false; - } - - /** - * get a list of one or more domains with all settings - * @param array or string $condition - * @return bool - true if at least one domain was found - * The data is stored in $this->return (as array of rows, each row is an associative array of column => value) - */ - public function getList($condition) { - $result = $this->read_from_db($condition); - if (count($result) >= 1) { - $this->return = $result; - return true; - } - -# $this->errormsg[] = Lang::read($this->msg['error_does_not_exist']); -# $this->errormsg[] = $result['error']; - return false; - } - - - /** * @return true on success false on failure */ diff --git a/model/PFAHandler.php b/model/PFAHandler.php index 1c531b1b..f3bb7f7d 100644 --- a/model/PFAHandler.php +++ b/model/PFAHandler.php @@ -1,6 +1,270 @@ new = 1; + $this->initStruct(); + $this->initMsg(); + } + + /** + * initialize with $id and check if it is valid + * @param string $id + */ + public function init($id) { + $this->id = strtolower($id); + + $exists = $this->view(false); + + if ($this->new) { + if ($exists) { + $this->errormsg[$this->id_field] = Lang::read($this->msg['error_already_exists']); + return false; + } elseif (!$this->validate_new_id() ) { + # errormsg filled by validate_new_id() + return false; + } else { + return true; + } + } else { # edit mode + if (!$exists) { + $this->errormsg[$this->id_field] = Lang::read($this->msg['error_does_not_exist']); + return false; + } else { + return true; + } + } + } + + + + + public function set($values) { + # TODO: make this a generic function for add and edit + + if ($this->new == 1) { + $values[$this->id_field] = $this->id; + } + + # base validation + $this->values = array(); + $this->values_valid = false; + foreach($this->struct as $key=>$row) { + if ($row['editable'] == 0) { # not editable + if ($this->new == 1) { + $this->values[$key] = $row['default']; + } + } else { + if (isset($values[$key])) { + if ($row['type'] != "password" || strlen($values[$key]) > 0 || $this->new == 1) { # skip on empty (aka unchanged) password on edit + $valid = true; # trust input unless validator objects + + # validate based on field type (_inp_$type) + $func="_inp_".$row['type']; + if (method_exists($this, $func) ) { + if (!$this->{$func}($key, $values[$key])) $valid = false; + } else { + # TODO: warning if no validation function exists? + } + + # validate based on field name (_field_$fieldname) + $func="_field_".$key; + if (method_exists($this, $func) ) { + if (!$this->{$func}($key, $values[$key])) $valid = false; + } + + if ($valid) { + $this->values[$key] = $values[$key]; + } + } + } elseif ($this->new) { # new, field not set in input data + $this->errormsg[] = "field $key is missing"; + # echo "MISSING / not set: $key\n"; + } else { # edit, field unchanged + # echo "skipped / not set: $key\n"; + } + } + } + + if (count($this->errormsg) == 0) { + $this->values_valid = true; + } + return $this->values_valid; + } + + /** + * store $this->values in the database + * calls $this->storemore() where additional things can be done + */ + public function store() { + if ($this->values_valid == false) { + $this->errormsg[] = "one or more values are invalid!"; + return false; + } + + $db_values = $this->values; + + foreach(array_keys($db_values) as $key) { + switch ($this->struct[$key]['type']) { # modify field content for some types + case 'bool': + $db_values[$key] = db_get_boolean($db_values[$key]); + break; + # TODO: passwords -> pacrypt() + } + if ($this->struct[$key]['not_in_db'] == 1) unset ($db_values[$key]); # remove 'not in db' columns + if ($this->struct[$key]['dont_write_to_db'] == 1) unset ($db_values[$key]); # remove 'dont_write_to_db' columns + } + + if ($this->new) { + $result = db_insert($this->db_table, $db_values); + } else { + $result = db_update($this->db_table, $this->id_field, $this->id, $db_values); + } + if ($result != 1) { + $this->errormsg[] = Lang::read($this->msg['store_error']) . "\n(" . $this->id . ")\n"; # TODO: change message + use sprintf + return false; + } + + $result = $this->storemore(); + + if ($result) { + db_log ($this->id, $this->msg['logname'], ""); + } + return $result; + } + + + + /** + * read_from_db + * @param array or string - condition (an array will be AND'ed using db_where_clause, a string will be directly used) + * @return array - rows + */ + protected function read_from_db($condition) { + $select_cols = array(); + + $yes = escape_string(Lang::read('YES')); + $no = escape_string(Lang::read('NO')); + + # TODO: replace hardcoded %Y-%m-%d with a country-specific date format via *.lang? + # TODO: (not too easy because pgsql uses a different formatstring format :-/ ) + if (Config::read('database_type') == 'pgsql') { + $formatted_date = "TO_DATE(text(###KEY###), 'YYYY-mm-dd')"; + } else { + $formatted_date = "DATE_FORMAT(###KEY###, '%Y-%m-%d')"; + } + + $colformat = array( + 'ts' => "$formatted_date AS ###KEY###, ###KEY### AS _###KEY###", + 'bool' => "CASE ###KEY### WHEN '" . db_get_boolean(true) . "' THEN '1' WHEN '" . db_get_boolean(false) . "' THEN '0' END as ###KEY###," . + "CASE ###KEY### WHEN '" . db_get_boolean(true) . "' THEN '$yes' WHEN '" . db_get_boolean(false) . "' THEN '$no' END as _###KEY###", + ); + + # get list of fields to display + $extrafrom = ""; + foreach($this->struct as $key=>$row) { + if ( $row['display_in_list'] != 0 && $row['not_in_db'] == 0 ) { + if ($row['select'] != '') $key = $row['select']; + + if ($row['extrafrom'] != '') $extrafrom = $extrafrom . " " . $row['extrafrom'] . "\n"; + + if (isset($colformat[$row['type']])) { + $select_cols[] = str_replace('###KEY###', $key, $colformat[$row['type']] ); + } else { + $select_cols[] = $key; + } + + } + } + + $cols = join(',', $select_cols); + $table = table_by_key($this->db_table); + + if (is_array($condition)) { + $where = db_where_clause($condition, $this->struct); + } else { + $where = " WHERE $condition "; + } + + $query = "SELECT $cols FROM $table $extrafrom $where ORDER BY " . $this->id_field; + $result = db_query($query); + + $db_result = array(); + if ($result['rows'] != 0) { + while ($row = db_assoc ($result['result'])) { + $db_result[] = $row; + } + } + + return $db_result; + } + + /** + * get the settings of a domain + * @param array or string $condition + * @return bool - true if at least one domain was found + * The data is stored in $this->return (as associative array of column => value) + */ + public function view($errors=true) { + $result = $this->read_from_db(array($this->id_field => $this->id) ); + if (count($result) == 1) { + $this->return = $result[0]; + return true; + } + + if ($errors) $this->errormsg[] = Lang::read($this->msg['error_does_not_exist']); +# $this->errormsg[] = $result['error']; + return false; + } + + /** + * get a list of one or more domains with all settings + * @param array or string $condition + * @return bool - true if at least one domain was found + * The data is stored in $this->return (as array of rows, each row is an associative array of column => value) + */ + public function getList($condition) { + $result = $this->read_from_db($condition); + if (count($result) >= 1) { + $this->return = $result; + return true; + } + +# $this->errormsg[] = Lang::read($this->msg['error_does_not_exist']); +# $this->errormsg[] = $result['error']; + return false; + } + + + + public function getStruct() { + return $this->struct; + } + + public function getId_field() { + return $this->id_field; + } + /** * @return return value of previously called method */