skip) return ""; $str=""; $str.="data[$this->config->text[0]["name"]]."]]>"; $str.="<".$this->config->text[1]["name"].">data[$this->config->text[1]["name"]]."]]>config->text[1]["name"].">"; $str.="data[$this->config->text[2]["name"]]."]]>"; for ($i=3; $iconfig->text); $i++){ $extra = $this->config->text[$i]["name"]; $str.="<".$extra.">data[$extra]."]]>"; } if ($this->userdata !== false) foreach ($this->userdata as $key => $value) $str.="<".$key.">"; return $str.""; } } class GanttLinkDataItem extends DataItem { public function to_xml_start(){ $str="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.">"; } } /*! Connector class for dhtmlxGantt **/ class GanttConnector extends Connector{ private $action_mode = ""; public $links_table = ""; protected $live_update_data_type = "GanttDataUpdate"; protected $extra_output="";//!< extra info which need to be sent to client side protected $options=array();//!< hash of OptionsConnector /*! assign options collection to the column @param name name of the column @param options array or connector object */ public function set_options($name,$options){ if (is_array($options)){ $str=""; foreach($options as $k => $v) $str.=""; $options=$str; } $this->options[$name]=$options; } /*! constructor Here initilization of all Masters occurs, execution timer initialized @param res db connection resource @param type string , which hold type of database ( MySQL or Postgre ), optional, instead of short DB name, full name of DataWrapper-based class can be provided @param item_type name of class, which will be used for item rendering, optional, DataItem will be used by default @param data_type name of class which will be used for dataprocessor calls handling, optional, DataProcessor class will be used by default. * @param render_type name of class which will be used for rendering. */ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){ if (!$item_type) $item_type="GanttDataItem"; if (!$data_type) $data_type="GanttDataProcessor"; if (!$render_type) $render_type="RenderStrategy"; parent::__construct($res,$type,$item_type,$data_type,$render_type); $this->event->attach("afterDelete", array($this, "delete_related_links")); $this->event->attach("afterOrder", array($this, "order_set_parent")); } //parse GET scoope, all operations with incoming request must be done here function parse_request(){ parent::parse_request(); $action_links = "links"; if(isset($_GET["gantt_mode"]) && $_GET["gantt_mode"] == $action_links) { $this->action_mode = $action_links; $this->request->set_action_mode($action_links); $this->options[$action_links]->request->set_action_mode($action_links); $this->options[$action_links]->request->set_user($this->request->get_user()); } if (count($this->config->text)){ if (isset($_GET["to"])) $this->request->set_filter($this->config->text[0]["name"],$_GET["to"],"<"); if (isset($_GET["from"])) $this->request->set_filter($this->config->text[1]["name"],$_GET["from"],">"); } } function order_set_parent($action){ $value = $action->get_id(); $parent = $action->get_value("parent"); $table = $this->request->get_source(); $id = $this->config->id["db_name"]; $this->sql->query("UPDATE $table SET parent = $parent WHERE $id = $value"); } function delete_related_links($action){ if (isset($this->options["links"])){ $links = $this->options["links"]; $value = $this->sql->escape($action->get_new_id()); $table = $links->get_request()->get_source(); $this->sql->query("DELETE FROM $table WHERE source = '$value'"); $this->sql->query("DELETE FROM $table WHERE target = '$value'"); } } public function render_links($table,$id="",$fields=false,$extra=false) { $links = new GanttLinksConnector($this->get_connection(),$this->names["db_class"]); if($this->live_update) $links->enable_live_update($this->live_update->get_table()); $links->render_table($table,$id,$fields,$extra); $this->set_options("links", $links); $this->links_table = $table; } /*! render self process commands, output requested data as XML */ public function render(){ $this->event->trigger("onInit", $this); EventMaster::trigger_static("connectorInit",$this); if (!$this->as_string) $this->parse_request(); $this->set_relation(); if ($this->live_update !== false && $this->updating!==false) { $this->live_update->get_updates(); } else { if ($this->editing){ if (($this->action_mode == "links") && isset($this->options["links"])) { $this->options["links"]->save(); } else { $dp = new $this->names["data_class"]($this,$this->config,$this->request); $dp->process($this->config,$this->request); } } else { if (!$this->access->check("read")){ LogMaster::log("Access control: read operation blocked"); echo "Access denied"; die(); } $wrap = new SortInterface($this->request); $this->apply_sorts($wrap); $this->event->trigger("beforeSort",$wrap); $wrap->store(); $wrap = new FilterInterface($this->request); $this->apply_filters($wrap); $this->event->trigger("beforeFilter",$wrap); $wrap->store(); if ($this->model && method_exists($this->model, "get")){ $this->sql = new ArrayDBDataWrapper(); $result = new ArrayQueryWrapper(call_user_func(array($this->model, "get"), $this->request)); $out = $this->output_as_xml($result); } else { $out = $this->output_as_xml($this->get_resource()); if ($out !== null) return $out; } } } $this->end_run(); } } /*! DataProcessor class for Gantt component **/ class GanttDataProcessor extends DataProcessor{ function name_data($data){ if ($data=="start_date") return $this->config->text[0]["name"]; if ($data=="id") return $this->config->id["name"]; if ($data=="duration" && $this->config->text[1]["name"] == "duration") return $this->config->text[1]["name"]; if ($data=="end_date" && $this->config->text[1]["name"] == "end_date") return $this->config->text[1]["name"]; if ($data=="text") return $this->config->text[2]["name"]; return $data; } } class JSONGanttDataItem extends GanttDataItem{ /*! return self as XML string */ function to_xml(){ if ($this->skip) return ""; $obj = array(); $obj['id'] = $this->get_id(); $obj['start_date'] = $this->data[$this->config->text[0]["name"]]; $obj[$this->config->text[1]["name"]] = $this->data[$this->config->text[1]["name"]]; $obj['text'] = $this->data[$this->config->text[2]["name"]]; for ($i=3; $iconfig->text); $i++){ $extra = $this->config->text[$i]["name"]; $obj[$extra]=$this->data[$extra]; } if ($this->userdata !== false) foreach ($this->userdata as $key => $value) $obj[$key]=$value; return $obj; } } class JSONGanttConnector extends GanttConnector { protected $data_separator = ","; protected $live_update_data_type = "JSONGanttDataUpdate"; /*! constructor Here initilization of all Masters occurs, execution timer initialized @param res db connection resource @param type string , which hold type of database ( MySQL or Postgre ), optional, instead of short DB name, full name of DataWrapper-based class can be provided @param item_type name of class, which will be used for item rendering, optional, DataItem will be used by default @param data_type name of class which will be used for dataprocessor calls handling, optional, DataProcessor class will be used by default. */ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){ if (!$item_type) $item_type="JSONGanttDataItem"; if (!$data_type) $data_type="GanttDataProcessor"; if (!$render_type) $render_type="JSONRenderStrategy"; parent::__construct($res,$type,$item_type,$data_type,$render_type); } protected function xml_start() { return '{ "data":'; } protected function xml_end() { $this->fill_collections(); $end = (!empty($this->extra_output)) ? ', "collections": {'.$this->extra_output.'}' : ''; foreach ($this->attributes as $k => $v) $end.=", \"".$k."\":\"".$v."\""; $end .= '}'; return $end; } /*! assign options collection to the column @param name name of the column @param options array or connector object */ public function set_options($name,$options){ if (is_array($options)){ $str=array(); foreach($options as $k => $v) $str[]='{"id":"'.$this->xmlentities($k).'", "value":"'.$this->xmlentities($v).'"}'; $options=implode(",",$str); } $this->options[$name]=$options; } /*! generates xml description for options collections @param list comma separated list of column names, for which options need to be generated */ protected function fill_collections($list=""){ $options = array(); foreach ($this->options as $k=>$v) { $name = $k; $option="\"{$name}\":["; if (!is_string($this->options[$name])){ $data = json_encode($this->options[$name]->render()); $option.=substr($data,1,-1); } else $option.=$this->options[$name]; $option.="]"; $options[] = $option; } $this->extra_output .= implode($this->data_separator, $options); } /*! output fetched data as XML @param res DB resultset */ protected function output_as_xml($res){ $result = $this->render_set($res); if ($this->simple) return $result; $data=$this->xml_start().json_encode($result).$this->xml_end(); if ($this->as_string) return $data; $out = new OutputWriter($data, ""); $out->set_type("json"); $this->event->trigger("beforeOutput", $this, $out); $out->output("", true, $this->encoding); } public function render_links($table,$id="",$fields=false,$extra=false,$relation_id=false) { $links = new JSONGanttLinksConnector($this->get_connection(),$this->names["db_class"]); if($this->live_update) $links->enable_live_update($this->live_update->get_table()); $links->render_table($table,$id,$fields,$extra); $this->set_options("links", $links); } } class GanttLinksConnector extends OptionsConnector { protected $live_update_data_type = "GanttDataUpdate"; public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){ if (!$item_type) $item_type="GanttLinkDataItem"; parent::__construct($res,$type,$item_type,$data_type,$render_type); } public function render(){ if (!$this->init_flag){ $this->init_flag=true; return ""; } $res = $this->sql->select($this->request); return $this->render_set($res); } public function save() { $dp = new $this->names["data_class"]($this,$this->config,$this->request); $dp->process($this->config,$this->request); } } class JSONGanttLinksConnector extends JSONOptionsConnector { protected $live_update_data_type = "JSONGanttDataUpdate"; public function render(){ if (!$this->init_flag){ $this->init_flag=true; return ""; } $res = $this->sql->select($this->request); return $this->render_set($res); } public function save() { $dp = new $this->names["data_class"]($this,$this->config,$this->request); $dp->process($this->config,$this->request); } } class JSONGanttDataUpdate extends JSONDataUpdate { public function get_updates() { $updates = $this->get_data_updates(); //ToDo: Add rendering for data. } private function get_data_updates() { $actions_table = $this->table; $version = $this->request->get_version(); $user = $this->request->get_user(); $select_actions = "SELECT DATAID, TYPE, USER FROM {$actions_table}"; $select_actions .= " WHERE {$actions_table}.ID > '{$version}' AND {$actions_table}.USER <> '{$user}'"; $output = array(); $index = 0; $actions_query = $this->sql->query($select_actions); while($action_data=$this->sql->get_next($actions_query)){ $action_type = $action_data["TYPE"]; $type_parts = explode("#", $action_type); $action_mode = $type_parts[1]; if($action_mode == "links") { $data = $this->select_links_for_action($action_data["DATAID"]); $data = new DataItemUpdate($data, $this->config, $index, $this->item_class); } else { $data = $this->select_task_for_action($action_data["DATAID"]); $data = new DataItemUpdate($data, $this->config, $index, $this->item_class); } array_push($output, $data); $index++; } return $output; } protected function select_task_for_action($taskId) { $tasks_table = $this->request->get_source(); $field_task_id = $this->config->id['db_name']; $select_actions_tasks = "SELECT * FROM {$tasks_table} WHERE {$taskId} = {$tasks_table}.{$field_task_id}"; return $this->sql->get_next($this->sql->query($select_actions_tasks)); } protected function select_links_for_action($taskId) { $links_connector_options = $this->options["connector"]->get_options(); $links_table = $links_connector_options["links"]->get_request()->get_source(); $field_task_id = $this->config->id['db_name']; $select_actions_tasks = "SELECT * FROM {$links_table} WHERE {$taskId} = {$links_table}.{$field_task_id}"; return $this->sql->get_next($this->sql->query($select_actions_tasks)); } } ?>