diff options
Diffstat (limited to 'codebase/Dhtmlx/Connector/Data')
-rw-r--r-- | codebase/Dhtmlx/Connector/Data/CommonDataItem.php | 27 | ||||
-rw-r--r-- | codebase/Dhtmlx/Connector/Data/CommonDataProcessor.php | 55 | ||||
-rw-r--r-- | codebase/Dhtmlx/Connector/Data/DataAction.php | 276 | ||||
-rw-r--r-- | codebase/Dhtmlx/Connector/Data/DataItem.php | 128 | ||||
-rw-r--r-- | codebase/Dhtmlx/Connector/Data/DataItemUpdate.php | 105 | ||||
-rw-r--r-- | codebase/Dhtmlx/Connector/Data/DataProcessor.php | 253 | ||||
-rw-r--r-- | codebase/Dhtmlx/Connector/Data/DataUpdate.php | 163 | ||||
-rw-r--r-- | codebase/Dhtmlx/Connector/Data/GridDataProcessor.php | 23 | ||||
-rw-r--r-- | codebase/Dhtmlx/Connector/Data/JSONCommonDataItem.php | 29 | ||||
-rw-r--r-- | codebase/Dhtmlx/Connector/Data/TreeDataItem.php | 157 | ||||
-rw-r--r-- | codebase/Dhtmlx/Connector/Data/TreeDataProcessor.php | 25 |
11 files changed, 1241 insertions, 0 deletions
diff --git a/codebase/Dhtmlx/Connector/Data/CommonDataItem.php b/codebase/Dhtmlx/Connector/Data/CommonDataItem.php new file mode 100644 index 0000000..523cd08 --- /dev/null +++ b/codebase/Dhtmlx/Connector/Data/CommonDataItem.php @@ -0,0 +1,27 @@ +<?php + +namespace DHTMLX\Connector\Data; +/*! DataItem class for DataView component +**/ +class CommonDataItem extends DataItem{ + /*! return self as XML string + */ + function to_xml(){ + if ($this->skip) return ""; + return $this->to_xml_start().$this->to_xml_end(); + } + + function to_xml_start(){ + $str="<item id='".$this->get_id()."' "; + for ($i=0; $i < sizeof($this->config->text); $i++){ + $name=$this->config->text[$i]["name"]; + $str.=" ".$name."='".$this->xmlentities($this->data[$name])."'"; + } + + if ($this->userdata !== false) + foreach ($this->userdata as $key => $value) + $str.=" ".$key."='".$this->xmlentities($value)."'"; + + return $str.">"; + } +}
\ No newline at end of file diff --git a/codebase/Dhtmlx/Connector/Data/CommonDataProcessor.php b/codebase/Dhtmlx/Connector/Data/CommonDataProcessor.php new file mode 100644 index 0000000..8f00b94 --- /dev/null +++ b/codebase/Dhtmlx/Connector/Data/CommonDataProcessor.php @@ -0,0 +1,55 @@ +<?php +namespace DHTMLX\Connector\Data; + +use DHTMLX\Connector\XSSFilter\ConnectorSecurity; +use DHTMLX\Connector\Tools\LogMaster; + +class CommonDataProcessor extends DataProcessor{ + protected function get_post_values($ids){ + if (isset($_GET['action'])){ + $data = array(); + if (isset($_POST["id"])){ + $dataset = array(); + foreach($_POST as $key=>$value) + $dataset[$key] = ConnectorSecurity::filter($value); + + $data[$_POST["id"]] = $dataset; + } + else + $data["dummy_id"] = $_POST; + return $data; + } + return parent::get_post_values($ids); + } + + protected function get_ids(){ + if (isset($_GET['action'])){ + if (isset($_POST["id"])) + return array($_POST['id']); + else + return array("dummy_id"); + } + return parent::get_ids(); + } + + protected function get_operation($rid){ + if (isset($_GET['action'])) + return $_GET['action']; + return parent::get_operation($rid); + } + + public function output_as_xml($results){ + if (isset($_GET['action'])){ + LogMaster::log("Edit operation finished",$results); + ob_clean(); + $type = $results[0]->get_status(); + if ($type == "error" || $type == "invalid"){ + echo "false"; + } else if ($type=="insert"){ + echo "true\n".$results[0]->get_new_id(); + } else + echo "true"; + } else + return parent::output_as_xml($results); + } +};
\ No newline at end of file diff --git a/codebase/Dhtmlx/Connector/Data/DataAction.php b/codebase/Dhtmlx/Connector/Data/DataAction.php new file mode 100644 index 0000000..8e4b5dd --- /dev/null +++ b/codebase/Dhtmlx/Connector/Data/DataAction.php @@ -0,0 +1,276 @@ +<?php +namespace DHTMLX\Connector\Data; + +use DHTMLX\Connector\Tools\LogMaster; +/*! contain all info related to action and controls customizaton +**/ +class DataAction{ + private $status; //!< cuurent status of record + private $id;//!< id of record + private $data;//!< data hash of record + private $userdata;//!< hash of extra data , attached to record + private $nid;//!< new id value , after operation executed + private $output;//!< custom output to client side code + private $attrs;//!< hash of custtom attributes + private $ready;//!< flag of operation's execution + private $addf;//!< array of added fields + private $delf;//!< array of deleted fields + + + /*! constructor + + @param status + current operation status + @param id + record id + @param data + hash of data + */ + function __construct($status,$id,$data){ + $this->status=$status; + $this->id=$id; + $this->data=$data; + $this->nid=$id; + + $this->output=""; + $this->attrs=array(); + $this->ready=false; + + $this->addf=array(); + $this->delf=array(); + } + + + /*! add custom field and value to DB operation + + @param name + name of field which will be added to DB operation + @param value + value which will be used for related field in DB operation + */ + function add_field($name,$value){ + LogMaster::log("adding field: ".$name.", with value: ".$value); + $this->data[$name]=$value; + $this->addf[]=$name; + } + /*! remove field from DB operation + + @param name + name of field which will be removed from DB operation + */ + function remove_field($name){ + LogMaster::log("removing field: ".$name); + $this->delf[]=$name; + } + + /*! sync field configuration with external object + + @param slave + SQLMaster object + @todo + check , if all fields removed then cancel action + */ + function sync_config($slave){ + foreach ($this->addf as $k => $v) + $slave->add_field($v); + foreach ($this->delf as $k => $v) + $slave->remove_field($v); + } + /*! get value of some record's propery + + @param name + name of record's property ( name of db field or alias ) + @return + value of related property + */ + function get_value($name){ + //die(var_dump($this->data["c0"])); + if (!array_key_exists($name,$this->data)){ + LogMaster::log("Incorrect field name used: ".$name); + LogMaster::log("data",$this->data); + return ""; + } + return $this->data[$name]; + } + /*! set value of some record's propery + + @param name + name of record's property ( name of db field or alias ) + @param value + value of related property + */ + function set_value($name,$value){ + LogMaster::log("change value of: ".$name." as: ".$value); + $this->data[$name]=$value; + } + /*! get hash of data properties + + @return + hash of data properties + */ + function get_data(){ + return $this->data; + } + /*! get some extra info attached to record + deprecated, exists just for backward compatibility, you can use set_value instead of it + @param name + name of userdata property + @return + value of related userdata property + */ + function get_userdata_value($name){ + return $this->get_value($name); + } + /*! set some extra info attached to record + deprecated, exists just for backward compatibility, you can use get_value instead of it + @param name + name of userdata property + @param value + value of userdata property + */ + function set_userdata_value($name,$value){ + return $this->set_value($name,$value); + } + /*! get current status of record + + @return + string with status value + */ + function get_status(){ + return $this->status; + } + /*! assign new status to the record + + @param status + new status value + */ + function set_status($status){ + $this->status=$status; + } + /*! set id + @param id + id value + */ + function set_id($id) { + $this->id = $id; + LogMaster::log("Change id: ".$id); + } + /*! set id + @param id + id value + */ + function set_new_id($id) { + $this->nid = $id; + LogMaster::log("Change new id: ".$id); + } + /*! get id of current record + + @return + id of record + */ + function get_id(){ + return $this->id; + } + /*! sets custom response text + + can be accessed through defineAction on client side. Text wrapped in CDATA, so no extra escaping necessary + @param text + custom response text + */ + function set_response_text($text){ + $this->set_response_xml("<![CDATA[".$text."]]>"); + } + /*! sets custom response xml + + can be accessed through defineAction on client side + @param text + string with XML data + */ + function set_response_xml($text){ + $this->output=$text; + } + /*! sets custom response attributes + + can be accessed through defineAction on client side + @param name + name of custom attribute + @param value + value of custom attribute + */ + function set_response_attribute($name,$value){ + $this->attrs[$name]=$value; + } + /*! check if action finished + + @return + true if action finished, false otherwise + */ + function is_ready(){ + return $this->ready; + } + /*! return new id value + + equal to original ID normally, after insert operation - value assigned for new DB record + @return + new id value + */ + function get_new_id(){ + return $this->nid; + } + + /*! set result of operation as error + */ + function error(){ + $this->status="error"; + $this->ready=true; + } + /*! set result of operation as invalid + */ + function invalid(){ + $this->status="invalid"; + $this->ready=true; + } + /*! confirm successful opeation execution + @param id + new id value, optional + */ + function success($id=false){ + if ($id!==false) + $this->nid = $id; + $this->ready=true; + } + /*! convert DataAction to xml format compatible with client side dataProcessor + @return + DataAction operation report as XML string + */ + function to_xml(){ + $str="<action type='{$this->status}' sid='{$this->id}' tid='{$this->nid}' "; + foreach ($this->attrs as $k => $v) { + $str.=$k."='".$this->xmlentities($v)."' "; + } + $str.=">{$this->output}</action>"; + return $str; + } + + /*! replace xml unsafe characters + + @param string + string to be escaped + @return + escaped string + */ + public function xmlentities($string) { + return str_replace( array( '&', '"', "'", '<', '>', '’' ), array( '&' , '"', ''' , '<' , '>', ''' ), $string); + } + + /*! convert self to string ( for logs ) + + @return + DataAction operation report as plain string + */ + function __toString(){ + return "action:{$this->status}; sid:{$this->id}; tid:{$this->nid};"; + } + + +}
\ No newline at end of file diff --git a/codebase/Dhtmlx/Connector/Data/DataItem.php b/codebase/Dhtmlx/Connector/Data/DataItem.php new file mode 100644 index 0000000..b980d9c --- /dev/null +++ b/codebase/Dhtmlx/Connector/Data/DataItem.php @@ -0,0 +1,128 @@ +<?php + +namespace DHTMLX\Connector\Data; +/*! base class for component item representation +**/ +class DataItem{ + protected $data; //!< hash of data + protected $config;//!< DataConfig instance + protected $index;//!< index of element + protected $skip;//!< flag , which set if element need to be skiped during rendering + protected $userdata; + + /*! constructor + + @param data + hash of data + @param config + DataConfig object + @param index + index of element + */ + function __construct($data,$config,$index){ + $this->config=$config; + $this->data=$data; + $this->index=$index; + $this->skip=false; + $this->userdata=false; + } + + //set userdata for the item + function set_userdata($name, $value){ + if ($this->userdata === false) + $this->userdata = array(); + + $this->userdata[$name]=$value; + } + /*! get named value + + @param name + name or alias of field + @return + value from field with provided name or alias + */ + public function get_value($name){ + return $this->data[$name]; + } + /*! set named value + + @param name + name or alias of field + @param value + value for field with provided name or alias + */ + public function set_value($name,$value){ + return $this->data[$name]=$value; + } + /*! get id of element + @return + id of element + */ + public function get_id(){ + $id = $this->config->id["name"]; + if (array_key_exists($id,$this->data)) + return $this->data[$id]; + return false; + } + /*! change id of element + + @param value + new id value + */ + public function set_id($value){ + $this->data[$this->config->id["name"]]=$value; + } + /*! get index of element + + @return + index of element + */ + public function get_index(){ + return $this->index; + } + /*! mark element for skiping ( such element will not be rendered ) + */ + public function skip(){ + $this->skip=true; + } + + /*! return self as XML string + */ + public function to_xml(){ + return $this->to_xml_start().$this->to_xml_end(); + } + + /*! replace xml unsafe characters + + @param string + string to be escaped + @return + escaped string + */ + public function xmlentities($string) { + return str_replace( array( '&', '"', "'", '<', '>', '’' ), array( '&' , '"', ''' , '<' , '>', ''' ), $string); + } + + /*! return starting tag for self as XML string + */ + public function to_xml_start(){ + $str="<item"; + for ($i=0; $i < sizeof($this->config->data); $i++){ + $name=$this->config->data[$i]["name"]; + $db_name=$this->config->data[$i]["db_name"]; + $str.=" ".$name."='".$this->xmlentities($this->data[$name])."'"; + } + //output custom data + if ($this->userdata !== false) + foreach ($this->userdata as $key => $value){ + $str.=" ".$key."='".$this->xmlentities($value)."'"; + } + + return $str.">"; + } + /*! return ending tag for XML string + */ + public function to_xml_end(){ + return "</item>"; + } +}
\ No newline at end of file diff --git a/codebase/Dhtmlx/Connector/Data/DataItemUpdate.php b/codebase/Dhtmlx/Connector/Data/DataItemUpdate.php new file mode 100644 index 0000000..ad97be2 --- /dev/null +++ b/codebase/Dhtmlx/Connector/Data/DataItemUpdate.php @@ -0,0 +1,105 @@ +<?php + +/* + @author dhtmlx.com + @license GPL, see license.txt +*/ + +/*! DataItemUpdate class for realization Optimistic concurrency control + Wrapper for DataItem object + It's used during outputing updates instead of DataItem object + Create wrapper for every data item with update information. +*/ + +namespace DHTMLX\Connector\Data; + +class DataItemUpdate extends DataItem { + + + /*! constructor + @param data + hash of data + @param config + DataConfig object + @param index + index of element + */ + public function __construct($data,$config,$index,$type){ + $this->config=$config; + $this->data=$data; + $this->index=$index; + $this->skip=false; + $this->child = new $type($data, $config, $index); + } + + /*! returns parent_id (for Tree and TreeGrid components) + */ + public function get_parent_id(){ + if (method_exists($this->child, 'get_parent_id')) { + return $this->child->get_parent_id(); + } else { + return ''; + } + } + + + /*! generate XML on the data hash base + */ + public function to_xml(){ + $str= "<update "; + $str .= 'status="'.$this->data['type'].'" '; + $str .= 'id="'.$this->data['dataId'].'" '; + $str .= 'parent="'.$this->get_parent_id().'"'; + $str .= '>'; + $str .= $this->child->to_xml(); + $str .= '</update>'; + return $str; + } + + /*! return starting tag for XML string + */ + public function to_xml_start(){ + $str="<update "; + $str .= 'status="'.$this->data['type'].'" '; + $str .= 'id="'.$this->data['dataId'].'" '; + $str .= 'parent="'.$this->get_parent_id().'"'; + $str .= '>'; + $str .= $this->child->to_xml_start(); + return $str; + } + + /*! return ending tag for XML string + */ + public function to_xml_end(){ + $str = $this->child->to_xml_end(); + $str .= '</update>'; + return $str; + } + + /*! returns false for outputing only current item without child items + */ + public function has_kids(){ + return false; + } + + /*! sets count of child items + @param value + count of child items + */ + public function set_kids($value){ + if (method_exists($this->child, 'set_kids')) { + $this->child->set_kids($value); + } + } + + /*! sets attribute for item + */ + public function set_attribute($name, $value){ + if (method_exists($this->child, 'set_attribute')) { + LogMaster::log("setting attribute: \nname = {$name}\nvalue = {$value}"); + $this->child->set_attribute($name, $value); + } else { + LogMaster::log("set_attribute method doesn't exists"); + } + } +}
\ No newline at end of file diff --git a/codebase/Dhtmlx/Connector/Data/DataProcessor.php b/codebase/Dhtmlx/Connector/Data/DataProcessor.php new file mode 100644 index 0000000..973753a --- /dev/null +++ b/codebase/Dhtmlx/Connector/Data/DataProcessor.php @@ -0,0 +1,253 @@ +<?php +/*! Base DataProcessor handling +**/ +namespace DHTMLX\Connector\Data; +use DHTMLX\Connector\Tools\LogMaster; +use DHTMLX\Connector\XSSFilter\ConnectorSecurity; +use DHTMLX\Connector\DataStorage\DataConfig; + +class DataProcessor{ + protected $connector;//!< Connector instance + protected $config;//!< DataConfig instance + protected $request;//!< DataRequestConfig instance + static public $action_param ="!nativeeditor_status"; + + /*! constructor + + @param connector + Connector object + @param config + DataConfig object + @param request + DataRequestConfig object + */ + function __construct($connector,$config,$request){ + $this->connector= $connector; + $this->config=$config; + $this->request=$request; + } + + /*! convert incoming data name to valid db name + redirect to Connector->name_data by default + @param data + data name from incoming request + @return + related db_name + */ + function name_data($data){ + return $data; + } + /*! retrieve data from incoming request and normalize it + + @param ids + array of extected IDs + @return + hash of data + */ + protected function get_post_values($ids){ + $data=array(); + for ($i=0; $i < sizeof($ids); $i++) + $data[$ids[$i]]=array(); + + foreach ($_POST as $key => $value) { + $details=explode("_",$key,2); + if (sizeof($details)==1) continue; + + $name=$this->name_data($details[1]); + $data[$details[0]][$name]=ConnectorSecurity::filter($value); + } + + return $data; + } + protected function get_ids(){ + if (!isset($_POST["ids"])) + throw new \Exception("Incorrect incoming data, ID of incoming records not recognized"); + return explode(",",$_POST["ids"]); + } + + protected function get_operation($rid){ + if (!isset($_POST[$rid."_".DataProcessor::$action_param])) + throw new \Exception("Status of record [{$rid}] not found in incoming request"); + return $_POST[$rid."_".DataProcessor::$action_param]; + } + /*! process incoming request ( save|update|delete ) + */ + function process(){ + LogMaster::log("DataProcessor object initialized",$_POST); + + $results=array(); + + $ids=$this->get_ids(); + $rows_data=$this->get_post_values($ids); + $failed=false; + + try{ + if ($this->connector->sql->is_global_transaction()) + $this->connector->sql->begin_transaction(); + + for ($i=0; $i < sizeof($ids); $i++) { + $rid = $ids[$i]; + LogMaster::log("Row data [{$rid}]",$rows_data[$rid]); + $status = $this->get_operation($rid); + + $action=new DataAction($status,$rid,$rows_data[$rid]); + + $results[]=$action; + $this->inner_process($action); + } + + } catch(\Exception $e){ + LogMaster::log($e); + $failed=true; + } + + if ($this->connector->sql->is_global_transaction()){ + if (!$failed) + for ($i=0; $i < sizeof($results); $i++) + if ($results[$i]->get_status()=="error" || $results[$i]->get_status()=="invalid"){ + $failed=true; + break; + } + if ($failed){ + for ($i=0; $i < sizeof($results); $i++) + $results[$i]->error(); + $this->connector->sql->rollback_transaction(); + } + else + $this->connector->sql->commit_transaction(); + } + + $this->output_as_xml($results); + } + + /*! converts status string to the inner mode name + + @param status + external status string + @return + inner mode name + */ + protected function status_to_mode($status){ + switch($status){ + case "updated": + return "update"; + break; + case "inserted": + return "insert"; + break; + case "deleted": + return "delete"; + break; + default: + return $status; + break; + } + } + /*! process data updated request received + + @param action + DataAction object + @return + DataAction object with details of processing + */ + protected function inner_process($action){ + + if ($this->connector->sql->is_record_transaction()) + $this->connector->sql->begin_transaction(); + + + + try{ + + $mode = $this->status_to_mode($action->get_status()); + if (!$this->connector->access->check($mode)){ + LogMaster::log("Access control: {$mode} operation blocked"); + $action->error(); + } else { + $check = $this->connector->event->trigger("beforeProcessing",$action); + + + if (!$action->is_ready()) + $this->check_exts($action,$mode); + if ($mode == "insert" && $action->get_status() != "error" && $action->get_status() != "invalid") + $this->connector->sql->new_record_order($action, $this->request); + + $check = $this->connector->event->trigger("afterProcessing",$action); + } + + } catch (\Exception $e){ + LogMaster::log($e); + $action->set_status("error"); + if ($action) + $this->connector->event->trigger("onDBError", $action, $e); + } + + if ($this->connector->sql->is_record_transaction()){ + if ($action->get_status()=="error" || $action->get_status()=="invalid") + $this->connector->sql->rollback_transaction(); + else + $this->connector->sql->commit_transaction(); + } + + return $action; + } + + /*! check if some event intercepts processing, send data to DataWrapper in other case + + @param action + DataAction object + @param mode + name of inner mode ( will be used to generate event names ) + */ + function check_exts($action,$mode){ + $old_config = new DataConfig($this->config); + + + $this->connector->event->trigger("before".$mode,$action); + if ($action->is_ready()) + LogMaster::log("Event code for ".$mode." processed"); + else { + //check if custom sql defined + $sql = $this->connector->sql->get_sql($mode,$action); + if ($sql){ + $this->connector->sql->query($sql); + } + else{ + $action->sync_config($this->config); + + + if ($this->connector->model && method_exists($this->connector->model, $mode)){ + call_user_func(array($this->connector->model, $mode), $action); + LogMaster::log("Model object process action: ".$mode); + } + if (!$action->is_ready()){ + + $method=array($this->connector->sql,$mode); + if (!is_callable($method)) + throw new \Exception("Unknown dataprocessing action: ".$mode); + call_user_func($method,$action,$this->request); + } + } + } + $this->connector->event->trigger("after".$mode,$action); + + $this->config->copy($old_config); + } + + /*! output xml response for dataprocessor + + @param results + array of DataAction objects + */ + function output_as_xml($results){ + LogMaster::log("Edit operation finished",$results); + ob_clean(); + header("Content-type:text/xml"); + echo "<?xml version='1.0' ?>"; + echo "<data>"; + for ($i=0; $i < sizeof($results); $i++) + echo $results[$i]->to_xml(); + echo "</data>"; + } + +}
\ No newline at end of file diff --git a/codebase/Dhtmlx/Connector/Data/DataUpdate.php b/codebase/Dhtmlx/Connector/Data/DataUpdate.php new file mode 100644 index 0000000..8fc1c46 --- /dev/null +++ b/codebase/Dhtmlx/Connector/Data/DataUpdate.php @@ -0,0 +1,163 @@ +<?php + +class DataUpdate{ + + protected $table; //!< table , where actions are stored + protected $url; //!< url for notification service, optional + protected $sql; //!< DB wrapper object + protected $config; //!< DBConfig object + protected $request; //!< DBRequestConfig object + protected $event; + protected $item_class; + protected $demu; + + //protected $config;//!< DataConfig instance + //protected $request;//!< DataRequestConfig instance + + /*! constructor + + @param connector + Connector object + @param config + DataConfig object + @param request + DataRequestConfig object + */ + function __construct($sql, $config, $request, $table, $url){ + $this->config= $config; + $this->request= $request; + $this->sql = $sql; + $this->table=$table; + $this->url=$url; + $this->demu = false; + } + + public function set_demultiplexor($path){ + $this->demu = $path; + } + + public function set_event($master, $name){ + $this->event = $master; + $this->item_class = $name; + } + + private function select_update($actions_table, $join_table, $id_field_name, $version, $user) { + $sql = "SELECT * FROM {$actions_table}"; + $sql .= " LEFT OUTER JOIN {$join_table} ON "; + $sql .= "{$actions_table}.DATAID = {$join_table}.{$id_field_name} "; + $sql .= "WHERE {$actions_table}.ID > '{$version}' AND {$actions_table}.USER <> '{$user}'"; + return $sql; + } + + private function get_update_max_version() { + $sql = "SELECT MAX(id) as VERSION FROM {$this->table}"; + $res = $this->sql->query($sql); + $data = $this->sql->get_next($res); + + if ($data == false || $data['VERSION'] == false) + return 1; + else + return $data['VERSION']; + } + + private function log_update_action($actions_table, $dataId, $status, $user) { + $sql = "INSERT INTO {$actions_table} (DATAID, TYPE, USER) VALUES ('{$dataId}', '{$status}', '{$user}')"; + $this->sql->query($sql); + if ($this->demu) + file_get_contents($this->demu); + } + + + + + /*! records operations in actions_table + @param action + DataAction object + */ + public function log_operations($action) { + $type = $this->sql->escape($action->get_status()); + $dataId = $this->sql->escape($action->get_new_id()); + $user = $this->sql->escape($this->request->get_user()); + if ($type!="error" && $type!="invalid" && $type !="collision") { + $this->log_update_action($this->table, $dataId, $type, $user); + } + } + + + /*! return action version in XMl format + */ + public function get_version() { + $version = $this->get_update_max_version(); + return "<userdata name='version'>".$version."</userdata>"; + } + + + /*! adds action version in output XML as userdata + */ + public function version_output($conn, $out) { + $out->add($this->get_version()); + } + + + /*! create update actions in XML-format and sends it to output + */ + public function get_updates() { + $sub_request = new DataRequestConfig($this->request); + $version = $this->request->get_version(); + $user = $this->request->get_user(); + + $sub_request->parse_sql($this->select_update($this->table, $this->request->get_source(), $this->config->id['db_name'], $version, $user)); + $sub_request->set_relation(false); + + $output = $this->render_set($this->sql->select($sub_request), $this->item_class); + + ob_clean(); + header("Content-type:text/xml"); + + echo $this->updates_start(); + echo $this->get_version(); + echo $output; + echo $this->updates_end(); + } + + + protected function render_set($res, $name){ + $output=""; + $index=0; + while ($data=$this->sql->get_next($res)){ + $data = new DataItemUpdate($data,$this->config,$index, $name); + $this->event->trigger("beforeRender",$data); + $output.=$data->to_xml(); + $index++; + } + return $output; + } + + /*! returns update start string + */ + protected function updates_start() { + $start = '<updates>'; + return $start; + } + + /*! returns update end string + */ + protected function updates_end() { + $start = '</updates>'; + return $start; + } + + /*! checks if action version given by client is deprecated + @param action + DataAction object + */ + public function check_collision($action) { + $version = $this->sql->escape($this->request->get_version()); + //$user = $this->sql->escape($this->request->get_user()); + $last_version = $this->get_update_max_version(); + if (($last_version > $version)&&($action->get_status() == 'update')) { + $action->error(); + $action->set_status('collision'); + } + } +}
\ No newline at end of file diff --git a/codebase/Dhtmlx/Connector/Data/GridDataProcessor.php b/codebase/Dhtmlx/Connector/Data/GridDataProcessor.php new file mode 100644 index 0000000..9b487eb --- /dev/null +++ b/codebase/Dhtmlx/Connector/Data/GridDataProcessor.php @@ -0,0 +1,23 @@ +<?php +namespace DHTMLX\Connector\Data; + +/*! DataProcessor class for Grid component +**/ +class GridDataProcessor extends DataProcessor{ + + /*! convert incoming data name to valid db name + converts c0..cN to valid field names + @param data + data name from incoming request + @return + related db_name + */ + function name_data($data){ + if ($data == "gr_id") return $this->config->id["name"]; + $parts=explode("c",$data); + if ($parts[0]=="" && ((string)intval($parts[1]))==$parts[1]) + if (sizeof($this->config->text)>intval($parts[1])) + return $this->config->text[intval($parts[1])]["name"]; + return $data; + } +}
\ No newline at end of file diff --git a/codebase/Dhtmlx/Connector/Data/JSONCommonDataItem.php b/codebase/Dhtmlx/Connector/Data/JSONCommonDataItem.php new file mode 100644 index 0000000..4a69068 --- /dev/null +++ b/codebase/Dhtmlx/Connector/Data/JSONCommonDataItem.php @@ -0,0 +1,29 @@ +<?php +namespace DHTMLX\Connector\Data; + +class JSONCommonDataItem extends DataItem{ + /*! return self as XML string + */ + function to_xml(){ + if ($this->skip) return false; + + $data = array( + 'id' => $this->get_id() + ); + for ($i=0; $i<sizeof($this->config->text); $i++){ + $extra = $this->config->text[$i]["name"]; + $data[$extra]=$this->data[$extra]; + if (is_null($data[$extra])) + $data[$extra] = ""; + } + + if ($this->userdata !== false) + foreach ($this->userdata as $key => $value){ + if ($value === null) + $data[$key]=""; + $data[$key]=$value; + } + + return $data; + } +} diff --git a/codebase/Dhtmlx/Connector/Data/TreeDataItem.php b/codebase/Dhtmlx/Connector/Data/TreeDataItem.php new file mode 100644 index 0000000..561d495 --- /dev/null +++ b/codebase/Dhtmlx/Connector/Data/TreeDataItem.php @@ -0,0 +1,157 @@ +<?php + +namespace DHTMLX\Connector\Data; + +class TreeDataItem extends DataItem +{ + private $im0;//!< image of closed folder + private $im1;//!< image of opened folder + private $im2;//!< image of leaf item + private $check;//!< checked state + private $kids = -1;//!< checked state + private $attrs;//!< collection of custom attributes + + function __construct($data, $config, $index) + { + parent::__construct($data, $config, $index); + + $this->im0 = false; + $this->im1 = false; + $this->im2 = false; + $this->check = false; + $this->attrs = array(); + } + + /*! get id of parent record + + @return + id of parent record + */ + function get_parent_id() + { + return $this->data[$this->config->relation_id["name"]]; + } + + /*! get state of items checkbox + + @return + state of item's checkbox as int value, false if state was not defined + */ + function get_check_state() + { + return $this->check; + } + + /*! set state of item's checkbox + + @param value + int value, 1 - checked, 0 - unchecked, -1 - third state + */ + function set_check_state($value) + { + $this->check = $value; + } + + /*! return count of child items + -1 if there is no info about childs + @return + count of child items + */ + function has_kids() + { + return $this->kids; + } + + /*! sets count of child items + @param value + count of child items + */ + function set_kids($value) + { + $this->kids = $value; + } + + /*! set custom attribute + + @param name + name of the attribute + @param value + new value of the attribute + */ + function set_attribute($name, $value) + { + switch ($name) { + case "id": + $this->set_id($value); + break; + case "text": + $this->data[$this->config->text[0]["name"]] = $value; + break; + case "checked": + $this->set_check_state($value); + break; + case "im0": + $this->im0 = $value; + break; + case "im1": + $this->im1 = $value; + break; + case "im2": + $this->im2 = $value; + break; + case "child": + $this->set_kids($value); + break; + default: + $this->attrs[$name] = $value; + } + } + + + /*! assign image for tree's item + + @param img_folder_closed + image for item, which represents folder in closed state + @param img_folder_open + image for item, which represents folder in opened state, optional + @param img_leaf + image for item, which represents leaf item, optional + */ + function set_image($img_folder_closed, $img_folder_open = false, $img_leaf = false) + { + $this->im0 = $img_folder_closed; + $this->im1 = $img_folder_open ? $img_folder_open : $img_folder_closed; + $this->im2 = $img_leaf ? $img_leaf : $img_folder_closed; + } + + /*! return self as XML string, starting part + */ + function to_xml_start() + { + if ($this->skip) return ""; + + $str1 = "<item id='" . $this->get_id() . "' text='" . $this->xmlentities($this->data[$this->config->text[0]["name"]]) . "' "; + if ($this->has_kids() == true) $str1 .= "child='" . $this->has_kids() . "' "; + if ($this->im0) $str1 .= "im0='" . $this->im0 . "' "; + if ($this->im1) $str1 .= "im1='" . $this->im1 . "' "; + if ($this->im2) $str1 .= "im2='" . $this->im2 . "' "; + if ($this->check) $str1 .= "checked='" . $this->check . "' "; + foreach ($this->attrs as $key => $value) + $str1 .= $key . "='" . $this->xmlentities($value) . "' "; + $str1 .= ">"; + if ($this->userdata !== false) + foreach ($this->userdata as $key => $value) + $str1 .= "<userdata name='" . $key . "'><![CDATA[" . $value . "]]></userdata>"; + + return $str1; + } + + /*! return self as XML string, ending part + */ + function to_xml_end() + { + if ($this->skip) return ""; + return "</item>"; + } + +}
\ No newline at end of file diff --git a/codebase/Dhtmlx/Connector/Data/TreeDataProcessor.php b/codebase/Dhtmlx/Connector/Data/TreeDataProcessor.php new file mode 100644 index 0000000..dca6a8f --- /dev/null +++ b/codebase/Dhtmlx/Connector/Data/TreeDataProcessor.php @@ -0,0 +1,25 @@ +<?php +namespace DHTMLX\Connector\Data; + +class TreeDataProcessor extends DataProcessor{ + + function __construct($connector,$config,$request){ + parent::__construct($connector,$config,$request); + $request->set_relation(false); + } + + /*! convert incoming data name to valid db name + converts c0..cN to valid field names + @param data + data name from incoming request + @return + related db_name + */ + function name_data($data){ + if ($data=="tr_pid") + return $this->config->relation_id["db_name"]; + if ($data=="tr_text") + return $this->config->text[0]["db_name"]; + return $data; + } +}
\ No newline at end of file |