summaryrefslogtreecommitdiffstats
path: root/codebase/connector
diff options
context:
space:
mode:
authorAlexKlimenkov <shurick.klimenkov@gmail.com>2017-01-31 18:38:36 +0300
committerAlexKlimenkov <shurick.klimenkov@gmail.com>2017-01-31 18:38:36 +0300
commitae92cf850550a9be965db867ba4bfb5651a18e5f (patch)
treebbf70ce45cc6e608def6e9a81570febe4528208b /codebase/connector
parent2e509c1f562c4f471d766c9b3532370f847f0839 (diff)
downloadscheduler-ae92cf850550a9be965db867ba4bfb5651a18e5f.zip
scheduler-ae92cf850550a9be965db867ba4bfb5651a18e5f.tar.gz
scheduler-ae92cf850550a9be965db867ba4bfb5651a18e5f.tar.bz2
[update] version 4.4.0
Diffstat (limited to 'codebase/connector')
-rw-r--r--codebase/connector/base_connector.php58
-rw-r--r--codebase/connector/combo_connector.php2
-rw-r--r--codebase/connector/db_common.php13
-rw-r--r--codebase/connector/db_phpcake.php139
-rw-r--r--codebase/connector/db_phpcake2.php85
-rw-r--r--codebase/connector/db_phpci.php10
-rw-r--r--codebase/connector/db_phpci2.php65
-rw-r--r--codebase/connector/db_phpyii.php168
-rw-r--r--codebase/connector/db_phpyii1.php91
-rw-r--r--codebase/connector/gantt_connector.php215
-rw-r--r--codebase/connector/mixed_connector.php63
-rw-r--r--codebase/connector/scheduler_connector.php1
-rw-r--r--codebase/connector/update.php124
13 files changed, 767 insertions, 267 deletions
diff --git a/codebase/connector/base_connector.php b/codebase/connector/base_connector.php
index 26f1f8b..cb44b15 100644
--- a/codebase/connector/base_connector.php
+++ b/codebase/connector/base_connector.php
@@ -282,38 +282,38 @@ class DataItem{
Can be used on its own to provide raw data.
**/
class Connector {
+
+ private $id_seed=0; //!< default value, used to generate auto-IDs
+ private $db; //!< db connection resource
+
protected $config;//DataConfig instance
protected $request;//DataRequestConfig instance
protected $names;//!< hash of names for used classes
protected $encoding="utf-8";//!< assigned encoding (UTF-8 by default)
protected $editing=false;//!< flag of edit mode ( response for dataprocessor )
+ protected $updating=false;//!< flag of update mode ( response for data-update )
+ protected $dload;//!< flag of dyn. loading mode
+ protected $data_separator = "\n";
+ protected $live_update = false; // actions table name for autoupdating
+ protected $live_update_data_type = "DataUpdate";
+ protected $extra_output="";//!< extra info which need to be sent to client side
+ protected $options=array();//!< hash of OptionsConnector
+ protected $as_string = false; // render() returns string, don't send result in response
+ protected $simple = false; // render only data without any other info
+ protected $filters;
+ protected $sorts;
+ protected $mix;
+ protected $order = false;
public static $filter_var="dhx_filter";
public static $sort_var="dhx_sort";
public static $kids_var="dhx_kids";
- public $model=false;
-
- private $updating=false;//!< flag of update mode ( response for data-update )
- private $db; //!< db connection resource
- protected $dload;//!< flag of dyn. loading mode
- public $access; //!< AccessMaster instance
- protected $data_separator = "\n";
-
- public $sql; //DataWrapper instance
- public $event; //EventMaster instance
- public $limit=false;
-
- private $id_seed=0; //!< default value, used to generate auto-IDs
- protected $live_update = false; // actions table name for autoupdating
- protected $extra_output="";//!< extra info which need to be sent to client side
- protected $options=array();//!< hash of OptionsConnector
- protected $as_string = false; // render() returns string, don't send result in response
- protected $simple = false; // render only data without any other info
- protected $filters;
- protected $sorts;
- protected $mix;
- protected $order = false;
+ public $model=false;
+ public $access; //!< AccessMaster instance
+ public $sql; //DataWrapper instance
+ public $event; //EventMaster instance
+ public $limit=false;
/*! constructor
@@ -419,7 +419,7 @@ class Connector {
$id = $info["key"];
}
$this->config->init($id,$fields,$extra,$relation_id);
- if (strpos(trim($table), " ")!==false)
+ if (is_string($table) && strpos(trim($table), " ")!==false)
$this->request->parse_sql($table);
else
$this->request->set_source($table);
@@ -700,6 +700,9 @@ class Connector {
*/
public function set_encoding($encoding){
$this->encoding=$encoding;
+ if ($this->live_update !== false) {
+ $this->live_update->set_encoding($this->encoding);
+ }
}
/*! enable or disable dynamic loading mode
@@ -810,6 +813,10 @@ class Connector {
$this->options[$name]=$options;
}
+ public function get_options() {
+ return $this->options;
+ }
+
public function insert($data) {
$action = new DataAction('inserted', false, $data);
@@ -850,9 +857,10 @@ class Connector {
@param url
url used for update notifications
*/
- public function enable_live_update($table, $url=false){
- $this->live_update = new DataUpdate($this->sql, $this->config, $this->request, $table,$url);
+ public function enable_live_update($table, $url=false, $origin_table = false){
+ $this->live_update = new $this->live_update_data_type($this->sql, $this->config, $this->request, $table,$url, array("connector" => $this, "table" => $origin_table));
$this->live_update->set_event($this->event,$this->names["item_class"]);
+ $this->live_update->set_encoding($this->encoding);
$this->event->attach("beforeOutput", Array($this->live_update, "version_output"));
$this->event->attach("beforeFiltering", Array($this->live_update, "get_updates"));
$this->event->attach("beforeProcessing", Array($this->live_update, "check_collision"));
diff --git a/codebase/connector/combo_connector.php b/codebase/connector/combo_connector.php
index 8fb5416..0e2fb85 100644
--- a/codebase/connector/combo_connector.php
+++ b/codebase/connector/combo_connector.php
@@ -25,7 +25,7 @@ class ComboDataItem extends DataItem{
function to_xml_start(){
if ($this->skip) return "";
- return "<option ".($this->selected?"selected='true'":"")."value='".$this->xmlentities($this->get_id())."'><![CDATA[".$this->data[$this->config->text[0]["name"]]."]]>";
+ return "<option ".($this->selected?"selected='true' ":"")."value='".$this->xmlentities($this->get_id())."'><![CDATA[".$this->data[$this->config->text[0]["name"]]."]]>";
}
/*! return self as XML string, ending part
*/
diff --git a/codebase/connector/db_common.php b/codebase/connector/db_common.php
index f6391d2..eddc7ad 100644
--- a/codebase/connector/db_common.php
+++ b/codebase/connector/db_common.php
@@ -8,6 +8,8 @@ require_once("tools.php");
/*! manager of data request
**/
class DataRequestConfig{
+
+ private $action_mode = "";
private $filters; //!< array of filtering rules
private $relation=false; //!< ID or other element used for linking hierarchy
private $sort_by; //!< sorting field
@@ -52,6 +54,7 @@ class DataRequestConfig{
$this->relation =$proto->get_relation();
$this->user = $proto->user;
$this->version = $proto->version;
+ $this->action_mode = $proto->action_mode;
}
/*! convert self to string ( for logs )
@@ -69,6 +72,15 @@ class DataRequestConfig{
return $str;
}
+ public function set_action_mode($action_mode) {
+ $this->action_mode = $action_mode;
+ return $this;
+ }
+
+ public function get_action_mode() {
+ return $this->action_mode;
+ }
+
/*! returns set of filtering rules
@return
set of filtering rules
@@ -205,7 +217,6 @@ class DataRequestConfig{
if (is_string($value))
$value = trim($value);
$this->source = $value;
- if (!$this->source) throw new Exception("Source of data can't be empty");
}
/*! sets data limits
diff --git a/codebase/connector/db_phpcake.php b/codebase/connector/db_phpcake.php
index 4df0289..92b5134 100644
--- a/codebase/connector/db_phpcake.php
+++ b/codebase/connector/db_phpcake.php
@@ -11,75 +11,76 @@ require_once("db_common.php");
if you plan to use it for Oracle - use Oracle connection type instead
**/
-class PHPCakeDBDataWrapper extends ArrayDBDataWrapper{
- public function select($sql){
- $source = $sql->get_source();
- if (is_array($source)) //result of find
- $res = $source;
- else
- $res = $this->connection->find("all");
-
- $temp = array();
- if (sizeof($res)){
- $name = get_class($this->connection);
- for ($i=sizeof($res)-1; $i>=0; $i--)
- $temp[]=&$res[$i][$name];
- }
- return new ArrayQueryWrapper($temp);
- }
-
- protected function getErrorMessage(){
- $errors = $this->connection->invalidFields();
- $text = array();
- foreach ($errors as $key => $value){
- $text[] = $key." - ".$value[0];
- }
- return implode("\n", $text);
- }
-
- public function insert($data,$source){
- $name = get_class($this->connection);
- $save = array();
- $temp_data = $data->get_data();
- unset($temp_data[$this->config->id['db_name']]);
- unset($temp_data["!nativeeditor_status"]);
- $save[$name] = $temp_data;
-
- if ($this->connection->save($save)){
- $data->success($this->connection->getLastInsertID());
- } else {
- $data->set_response_attribute("details", $this->getErrorMessage());
- $data->invalid();
- }
- }
- public function delete($data,$source){
- $id = $data->get_id();
- $this->connection->delete($id);
- $data->success();
- }
- public function update($data,$source){
- $name = get_class($this->connection);
- $save = array();
- $save[$name] = &$data->get_data();
-
- if ($this->connection->save($save)){
- $data->success();
- } else {
- $data->set_response_attribute("details", $this->getErrorMessage());
- $data->invalid();
- }
- }
-
-
- public function escape($str){
- throw new Exception("Not implemented");
- }
- public function query($str){
- throw new Exception("Not implemented");
- }
- public function get_new_id(){
- throw new Exception("Not implemented");
- }
+class PHPCakeDBDataWrapper extends ArrayDBDataWrapper {
+
+ public function select($source) {
+ $sourceData = $source->get_source();
+ if(is_array($sourceData)) //result of find
+ $query = $sourceData;
+ else
+ $query = $sourceData->find("all");
+
+ $temp = array();
+ foreach($query as $row)
+ $temp[] = $row->toArray();
+
+ return new ArrayQueryWrapper($temp);
+ }
+
+ protected function getErrorMessage() {
+ $errors = $this->connection->invalidFields();
+ $text = array();
+ foreach ($errors as $key => $value){
+ $text[] = $key." - ".$value[0];
+ }
+ return implode("\n", $text);
+ }
+
+ public function insert($data, $source) {
+ $sourceData = $source->get_source();
+ $obj = $sourceData->newEntity();
+ $obj = $this->fillModel($obj, $data);
+ $savedResult = $source->get_source()->save($obj);
+ $data->success($savedResult->get($this->config->id["db_name"]));
+ }
+
+ public function delete($data, $source) {
+ $sourceData = $source->get_source();
+ $obj = $sourceData->get($data->get_id());
+ $source->get_source()->delete($obj);
+ }
+
+ public function update($data, $source) {
+ $sourceData = $source->get_source();
+ $obj = $sourceData->get($data->get_id());
+ $obj = $this->fillModel($obj, $data);
+ $sourceData->save($obj);
+ }
+
+ private function fillModel($obj, $data) {
+ //Map data to model object.
+ for($i = 0; $i < count($this->config->text); $i++) {
+ $step=$this->config->text[$i];
+ $obj->set($step["name"], $data->get_value($step["name"]));
+ }
+
+ if($relation = $this->config->relation_id["db_name"])
+ $obj->set($relation, $data->get_value($relation));
+
+ return $obj;
+ }
+
+ public function escape($str){
+ throw new Exception("Not implemented");
+ }
+
+ public function query($str){
+ throw new Exception("Not implemented");
+ }
+
+ public function get_new_id(){
+ throw new Exception("Not implemented");
+ }
}
?> \ No newline at end of file
diff --git a/codebase/connector/db_phpcake2.php b/codebase/connector/db_phpcake2.php
new file mode 100644
index 0000000..76a941d
--- /dev/null
+++ b/codebase/connector/db_phpcake2.php
@@ -0,0 +1,85 @@
+<?php
+/*
+ @author dhtmlx.com
+ @license GPL, see license.txt
+*/
+require_once("db_common.php");
+
+//DataProcessor::$action_param ="dhx_editor_status";
+
+/*! Implementation of DataWrapper for PDO
+
+if you plan to use it for Oracle - use Oracle connection type instead
+**/
+class PHPCake2DBDataWrapper extends ArrayDBDataWrapper{
+ public function select($sql){
+ $source = $sql->get_source();
+ if (is_array($source)) //result of find
+ $res = $source;
+ else
+ $res = $this->connection->find("all");
+
+ $temp = array();
+ if (sizeof($res)){
+ $name = get_class($this->connection);
+ for ($i=sizeof($res)-1; $i>=0; $i--)
+ $temp[]=&$res[$i][$name];
+ }
+ return new ArrayQueryWrapper($temp);
+ }
+
+ protected function getErrorMessage(){
+ $errors = $this->connection->invalidFields();
+ $text = array();
+ foreach ($errors as $key => $value){
+ $text[] = $key." - ".$value[0];
+ }
+ return implode("\n", $text);
+ }
+
+ public function insert($data,$source){
+ $name = get_class($this->connection);
+ $save = array();
+ $temp_data = $data->get_data();
+ unset($temp_data[$this->config->id['db_name']]);
+ unset($temp_data["!nativeeditor_status"]);
+ $save[$name] = $temp_data;
+
+ if ($this->connection->save($save)){
+ $data->success($this->connection->getLastInsertID());
+ } else {
+ $data->set_response_attribute("details", $this->getErrorMessage());
+ $data->invalid();
+ }
+ }
+ public function delete($data,$source){
+ $id = $data->get_id();
+ $this->connection->delete($id);
+ $data->success();
+ }
+ public function update($data,$source){
+ $name = get_class($this->connection);
+ $save = array();
+ $save[$name] = &$data->get_data();
+
+ if ($this->connection->save($save)){
+ $data->success();
+ } else {
+ $data->set_response_attribute("details", $this->getErrorMessage());
+ $data->invalid();
+ }
+ }
+
+
+ public function escape($str){
+ throw new Exception("Not implemented");
+ }
+ public function query($str){
+ throw new Exception("Not implemented");
+ }
+ public function get_new_id(){
+ throw new Exception("Not implemented");
+ }
+}
+
+?> \ No newline at end of file
diff --git a/codebase/connector/db_phpci.php b/codebase/connector/db_phpci.php
index e38d831..15ed95f 100644
--- a/codebase/connector/db_phpci.php
+++ b/codebase/connector/db_phpci.php
@@ -44,16 +44,24 @@ class PHPCIDBDataWrapper extends DBDataWrapper{
}
class PHPCIResultSet{
+ private $is_result_done = false;
private $res;
private $start;
private $count;
public function __construct($res){
+ if(is_bool($res)) {
+ $this->$is_result_done = true;
+ return $this;
+ }
$this->res = $res;
$this->start = $res->current_row;
- $this->count = $res->num_rows;
+ $this->count = $res->num_rows();
}
public function next(){
+ if($this->is_result_done)
+ return null;
+
if ($this->start != $this->count){
return $this->res->row($this->start++,'array');
} else {
diff --git a/codebase/connector/db_phpci2.php b/codebase/connector/db_phpci2.php
new file mode 100644
index 0000000..e963211
--- /dev/null
+++ b/codebase/connector/db_phpci2.php
@@ -0,0 +1,65 @@
+<?php
+/*
+ @author dhtmlx.com
+ @license GPL, see license.txt
+*/
+require_once("db_common.php");
+
+/*! Implementation of DataWrapper for PDO
+
+if you plan to use it for Oracle - use Oracle connection type instead
+**/
+class PHPCI2DBDataWrapper extends DBDataWrapper{
+ private $last_result;//!< store result or last operation
+
+ public function query($sql){
+ LogMaster::log($sql);
+
+ $res=$this->connection->query($sql);
+ if ($res===false) {
+ throw new Exception("CI - sql execution failed");
+ }
+
+ if (is_object($res))
+ return new PHPCIResultSet($res);
+ return new ArrayQueryWrapper(array());
+ }
+
+ public function get_next($res){
+ $data = $res->next();
+ return $data;
+ }
+
+ public function get_new_id(){
+ return $this->connection->insert_id();
+ }
+
+ public function escape($str){
+ return $this->connection->escape_str($str);
+ }
+
+ public function escape_name($data){
+ return $this->connection->protect_identifiers($data);
+ }
+}
+
+class PHPCIResultSet{
+ private $res;
+ private $start;
+ private $count;
+
+ public function __construct($res){
+ $this->res = $res;
+ $this->start = $res->current_row;
+ $this->count = $res->num_rows;
+ }
+ public function next(){
+ if ($this->start != $this->count){
+ return $this->res->row($this->start++,'array');
+ } else {
+ $this->res->free_result();
+ return null;
+ }
+ }
+}
+?> \ No newline at end of file
diff --git a/codebase/connector/db_phpyii.php b/codebase/connector/db_phpyii.php
index 616d7f3..1d8d5d1 100644
--- a/codebase/connector/db_phpyii.php
+++ b/codebase/connector/db_phpyii.php
@@ -6,86 +6,94 @@
require_once("db_common.php");
-class PHPYiiDBDataWrapper extends ArrayDBDataWrapper{
- public function select($sql){
- if (is_array($this->connection)) //result of findAll
- $res = $this->connection;
- else
- $res = $this->connection->findAll();
-
- $temp = array();
- if (sizeof($res)){
- foreach ($res as $obj)
- $temp[]=$obj->getAttributes();
- }
- return new ArrayQueryWrapper($temp);
- }
-
- protected function getErrorMessage(){
- $errors = $this->connection->invalidFields();
- $text = array();
- foreach ($errors as $key => $value){
- $text[] = $key." - ".$value[0];
- }
- return implode("\n", $text);
- }
- public function insert($data,$source){
- $name = get_class($this->connection);
- $obj = new $name();
-
- $this->fill_model_and_save($obj, $data);
- }
- public function delete($data,$source){
- $obj = $this->connection->findByPk($data->get_id());
- if ($obj->delete()){
- $data->success();
- $data->set_new_id($obj->getPrimaryKey());
- } else {
- $data->set_response_attribute("details", $this->errors_to_string($obj->getErrors()));
- $data->invalid();
- }
- }
- public function update($data,$source){
- $obj = $this->connection->findByPk($data->get_id());
- $this->fill_model_and_save($obj, $data);
- }
-
- protected function fill_model_and_save($obj, $data){
- $values = $data->get_data();
-
- //map data to model object
- for ($i=0; $i < sizeof($this->config->text); $i++){
- $step=$this->config->text[$i];
- $obj->setAttribute($step["name"], $data->get_value($step["name"]));
- }
- if ($relation = $this->config->relation_id["db_name"])
- $obj->setAttribute($relation, $data->get_value($relation));
-
- //save model
- if ($obj->save()){
- $data->success();
- $data->set_new_id($obj->getPrimaryKey());
- } else {
- $data->set_response_attribute("details", $this->errors_to_string($obj->getErrors()));
- $data->invalid();
- }
- }
-
- protected function errors_to_string($errors){
- $text = array();
- foreach($errors as $value)
- $text[]=implode("\n", $value);
- return implode("\n",$text);
- }
- public function escape($str){
- throw new Exception("Not implemented");
- }
- public function query($str){
- throw new Exception("Not implemented");
- }
- public function get_new_id(){
- throw new Exception("Not implemented");
- }
+class PHPYiiDBDataWrapper extends ArrayDBDataWrapper {
+
+ public function select($source) {
+ $sourceData = $source->get_source();
+ if(is_array($sourceData)) //result of find
+ $res = $sourceData;
+ else
+ $res = $sourceData->find()->all();
+
+ $temp = array();
+ if(sizeof($res)) {
+ foreach($res as $obj)
+ $temp[] = $obj->getAttributes();
+ }
+ return new ArrayQueryWrapper($temp);
+ }
+
+ protected function getErrorMessage() {
+ $errors = $this->connection->getErrors();
+ $text = array();
+ foreach($errors as $key => $value)
+ $text[] = $key." - ".$value[0];
+
+ return implode("\n", $text);
+ }
+ public function insert($data, $source) {
+ $name = get_class($source->get_source());
+ $obj = new $name();
+ $this->fill_model_and_save($obj, $data);
+ }
+
+ public function delete($data, $source) {
+ $obj = $source->get_source()->findOne($data->get_id());
+ if($obj->delete()) {
+ $data->success();
+ $data->set_new_id($obj->getPrimaryKey());
+ }
+ else {
+ $data->set_response_attribute("details", $this->errors_to_string($obj->getErrors()));
+ $data->invalid();
+ }
+ }
+
+ public function update($data, $source) {
+ $obj = $source->get_source()->findOne($data->get_id());
+ $this->fill_model_and_save($obj, $data);
+ }
+
+ protected function fill_model_and_save($obj, $data) {
+ //Map data to model object.
+ for($i=0; $i < sizeof($this->config->text); $i++) {
+ $step=$this->config->text[$i];
+ $obj->setAttribute($step["name"], $data->get_value($step["name"]));
+ }
+
+ if($relation = $this->config->relation_id["db_name"])
+ $obj->setAttribute($relation, $data->get_value($relation));
+
+ //Save model.
+ if($obj->save()) {
+ $data->success();
+ $data->set_new_id($obj->getPrimaryKey());
+ }
+ else {
+ $data->set_response_attribute("details", $this->errors_to_string($obj->getErrors()));
+ $data->invalid();
+ }
+ }
+
+ protected function errors_to_string($errors) {
+ $text = array();
+ foreach($errors as $value)
+ $text[] = implode("\n", $value);
+
+ return implode("\n",$text);
+ }
+
+ public function escape($str) {
+ throw new Exception("Not implemented");
+ }
+
+ public function query($str) {
+ throw new Exception("Not implemented");
+ }
+
+ public function get_new_id() {
+ throw new Exception("Not implemented");
+ }
}
?> \ No newline at end of file
diff --git a/codebase/connector/db_phpyii1.php b/codebase/connector/db_phpyii1.php
new file mode 100644
index 0000000..bbbd943
--- /dev/null
+++ b/codebase/connector/db_phpyii1.php
@@ -0,0 +1,91 @@
+<?php
+/*
+ @author dhtmlx.com
+ @license GPL, see license.txt
+*/
+
+require_once("db_common.php");
+
+class PHPYii1DBDataWrapper extends ArrayDBDataWrapper{
+ public function select($sql){
+ if (is_array($this->connection)) //result of findAll
+ $res = $this->connection;
+ else
+ $res = $this->connection->findAll();
+
+ $temp = array();
+ if (sizeof($res)){
+ foreach ($res as $obj)
+ $temp[]=$obj->getAttributes();
+ }
+ return new ArrayQueryWrapper($temp);
+ }
+
+ protected function getErrorMessage(){
+ $errors = $this->connection->invalidFields();
+ $text = array();
+ foreach ($errors as $key => $value){
+ $text[] = $key." - ".$value[0];
+ }
+ return implode("\n", $text);
+ }
+ public function insert($data,$source){
+ $name = get_class($this->connection);
+ $obj = new $name();
+
+ $this->fill_model_and_save($obj, $data);
+ }
+ public function delete($data,$source){
+ $obj = $this->connection->findByPk($data->get_id());
+ if ($obj->delete()){
+ $data->success();
+ $data->set_new_id($obj->getPrimaryKey());
+ } else {
+ $data->set_response_attribute("details", $this->errors_to_string($obj->getErrors()));
+ $data->invalid();
+ }
+ }
+ public function update($data,$source){
+ $obj = $this->connection->findByPk($data->get_id());
+ $this->fill_model_and_save($obj, $data);
+ }
+
+ protected function fill_model_and_save($obj, $data){
+ $values = $data->get_data();
+
+ //map data to model object
+ for ($i=0; $i < sizeof($this->config->text); $i++){
+ $step=$this->config->text[$i];
+ $obj->setAttribute($step["name"], $data->get_value($step["name"]));
+ }
+ if ($relation = $this->config->relation_id["db_name"])
+ $obj->setAttribute($relation, $data->get_value($relation));
+
+ //save model
+ if ($obj->save()){
+ $data->success();
+ $data->set_new_id($obj->getPrimaryKey());
+ } else {
+ $data->set_response_attribute("details", $this->errors_to_string($obj->getErrors()));
+ $data->invalid();
+ }
+ }
+
+ protected function errors_to_string($errors){
+ $text = array();
+ foreach($errors as $value)
+ $text[]=implode("\n", $value);
+ return implode("\n",$text);
+ }
+ public function escape($str){
+ throw new Exception("Not implemented");
+ }
+ public function query($str){
+ throw new Exception("Not implemented");
+ }
+ public function get_new_id(){
+ throw new Exception("Not implemented");
+ }
+}
+
+?> \ No newline at end of file
diff --git a/codebase/connector/gantt_connector.php b/codebase/connector/gantt_connector.php
index 3577835..9bd9422 100644
--- a/codebase/connector/gantt_connector.php
+++ b/codebase/connector/gantt_connector.php
@@ -31,15 +31,36 @@ class GanttDataItem extends DataItem{
}
}
+class GanttLinkDataItem extends DataItem {
+
+ public function to_xml_start(){
+ $str="<item id='".$this->xmlentities($this->get_id())."'";
+ 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.">";
+ }
+
+}
/*! 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
- protected $links_mode = false;
-
/*! assign options collection to the column
@@ -87,8 +108,14 @@ class GanttConnector extends Connector{
function parse_request(){
parent::parse_request();
- if (isset($_GET["gantt_mode"]) && $_GET["gantt_mode"] == "links")
- $this->links_mode = true;
+ $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"]))
@@ -119,11 +146,70 @@ class GanttConnector extends Connector{
}
}
- public function render_links($table,$id="",$fields=false,$extra=false,$relation_id=false) {
+ 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
@@ -174,6 +260,7 @@ class JSONGanttDataItem extends GanttDataItem{
class JSONGanttConnector extends GanttConnector {
protected $data_separator = ",";
+ protected $live_update_data_type = "JSONGanttDataUpdate";
/*! constructor
@@ -267,66 +354,25 @@ class JSONGanttConnector extends GanttConnector {
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);
}
+}
- /*! 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->links_mode && 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;
- }
+class GanttLinksConnector extends OptionsConnector {
+ protected $live_update_data_type = "GanttDataUpdate";
- }
- }
- $this->end_run();
+ 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);
}
-}
-
-class GanttLinksConnector extends OptionsConnector {
public function render(){
if (!$this->init_flag){
$this->init_flag=true;
@@ -345,6 +391,7 @@ class GanttLinksConnector extends OptionsConnector {
class JSONGanttLinksConnector extends JSONOptionsConnector {
+ protected $live_update_data_type = "JSONGanttDataUpdate";
public function render(){
if (!$this->init_flag){
$this->init_flag=true;
@@ -361,4 +408,60 @@ class JSONGanttLinksConnector extends JSONOptionsConnector {
}
}
+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));
+ }
+}
+
?> \ No newline at end of file
diff --git a/codebase/connector/mixed_connector.php b/codebase/connector/mixed_connector.php
index 461d6ec..bbef8d4 100644
--- a/codebase/connector/mixed_connector.php
+++ b/codebase/connector/mixed_connector.php
@@ -7,22 +7,53 @@ require_once("base_connector.php");
class MixedConnector extends Connector {
- protected $connectors = array();
-
- public function add($name, $conn) {
- $this->connectors[$name] = $conn;
- }
-
- public function render() {
- $result = "{";
- $parts = array();
- foreach($this->connectors as $name => $conn) {
- $conn->asString(true);
- $parts[] = "\"".$name."\":".($conn->render())."\n";
- }
- $result .= implode(",\n", $parts)."}";
- echo $result;
- }
+ private $_data_type = null;
+
+ function __construct($dataType = "json") {
+ $this->_data_type = $dataType;
+ }
+
+ protected $attributes = array();
+ protected $connectors = array();
+
+ public function add($name, $conn) {
+ $this->connectors[$name] = $conn;
+ $conn->simple = true;
+ }
+
+ public function render() {
+ if($this->_data_type == "json")
+ $this->render_json();
+ else
+ $this->render_xml();
+ }
+
+ private function render_json() {
+ $result = "{";
+ $parts = array();
+ foreach($this->connectors as $name => $conn) {
+ $conn->asString(true);
+ $parts[] = "\"".$name."\":".($conn->render())."\n";
+ }
+ $result .= implode(",\n", $parts)."}";
+ echo $result;
+ }
+
+ private function render_xml() {
+ $result = "";
+ $parts = array();
+
+ foreach($this->connectors as $name => $conn) {
+ $conn->asString(true);
+ $parts[] = "<".$name.">".($conn->render())."</".$name.">\n";
+ }
+ $result .= implode("", $parts);
+ $this->output_as_xml($result);
+ }
+
+ protected function output_as_xml($res) {
+ echo "<?xml version='1.0' encoding='".$this->encoding."' ?>".$this->xml_start().$res.$this->xml_end();
+ }
}
?> \ No newline at end of file
diff --git a/codebase/connector/scheduler_connector.php b/codebase/connector/scheduler_connector.php
index ee0cd20..b7049db 100644
--- a/codebase/connector/scheduler_connector.php
+++ b/codebase/connector/scheduler_connector.php
@@ -136,6 +136,7 @@ class JSONSchedulerDataItem extends SchedulerDataItem{
class JSONSchedulerConnector extends SchedulerConnector {
protected $data_separator = ",";
+ protected $live_update_data_type = "JSONDataUpdate";
/*! constructor
diff --git a/codebase/connector/update.php b/codebase/connector/update.php
index dacc211..4f8ec6e 100644
--- a/codebase/connector/update.php
+++ b/codebase/connector/update.php
@@ -43,7 +43,7 @@ class DataItemUpdate extends DataItem {
*/
public function to_xml(){
$str= "<update ";
- $str .= 'status="'.$this->data['type'].'" ';
+ $str .= 'status="'.$this->data['action_table_type'].'" ';
$str .= 'id="'.$this->data['dataId'].'" ';
$str .= 'parent="'.$this->get_parent_id().'"';
$str .= '>';
@@ -56,7 +56,7 @@ class DataItemUpdate extends DataItem {
*/
public function to_xml_start(){
$str="<update ";
- $str .= 'status="'.$this->data['type'].'" ';
+ $str .= 'status="'.$this->data['action_table_type'].'" ';
$str .= 'id="'.$this->data['dataId'].'" ';
$str .= 'parent="'.$this->get_parent_id().'"';
$str .= '>';
@@ -100,17 +100,17 @@ class DataItemUpdate extends DataItem {
}
}
-
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 $sql; //!< DB wrapper object
+ protected $config; //!< DBConfig object
+ protected $request; //!< DBRequestConfig object
+ protected $encoding="utf-8";
+ protected $event;
+ protected $item_class;
+ protected $demu;
//protected $config;//!< DataConfig instance
//protected $request;//!< DataRequestConfig instance
@@ -124,13 +124,14 @@ class DataUpdate{
@param request
DataRequestConfig object
*/
- function __construct($sql, $config, $request, $table, $url){
+ function __construct($sql, $config, $request, $table, $url, $options){
$this->config= $config;
$this->request= $request;
$this->sql = $sql;
$this->table=$table;
$this->url=$url;
$this->demu = false;
+ $this->options = $options;
}
public function set_demultiplexor($path){
@@ -141,16 +142,24 @@ class DataUpdate{
$this->event = $master;
$this->item_class = $name;
}
+
+ public function set_encoding($encoding){
+ $this->encoding = $encoding;
+ }
- private function select_update($actions_table, $join_table, $id_field_name, $version, $user) {
- $sql = "SELECT * FROM {$actions_table}";
+ protected function select_update($actions_table, $join_table, $id_field_name, $version, $user) {
+
+ if ($this->options["table"] !== false)
+ $join_table = $this->options["table"];
+
+ $sql = "SELECT $join_table.*, {$actions_table}.id, {$actions_table}.dataId, {$actions_table}.type as action_table_type, {$actions_table}.user 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() {
+ protected 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);
@@ -168,8 +177,9 @@ class DataUpdate{
file_get_contents($this->demu);
}
-
-
+ public function get_table() {
+ return $this->table;
+ }
/*! records operations in actions_table
@param action
@@ -180,6 +190,10 @@ class DataUpdate{
$dataId = $this->sql->escape($action->get_new_id());
$user = $this->sql->escape($this->request->get_user());
if ($type!="error" && $type!="invalid" && $type !="collision") {
+ $action_mode = $this->request->get_action_mode();
+ if(!empty($action_mode))
+ $type .= "#".$action_mode;
+
$this->log_update_action($this->table, $dataId, $type, $user);
}
}
@@ -213,8 +227,8 @@ class DataUpdate{
$output = $this->render_set($this->sql->select($sub_request), $this->item_class);
ob_clean();
- header("Content-type:text/xml");
-
+ header("Content-type:text/xml; charset=".$this->encoding);
+
echo $this->updates_start();
echo $this->get_version();
echo $output;
@@ -262,5 +276,79 @@ class DataUpdate{
}
}
}
+
+
+class JSONDataItemUpdate extends DataItemUpdate {
+
+ public function to_xml() {
+ return array(
+ "status" => $this->data["action_table_type"],
+ "id" => $this->data["dataId"],
+ "parent" => $this->get_parent_id(),
+ "data" => $this->child->to_xml()
+ );
+ }
+
+}
+
+class JSONDataUpdate extends DataUpdate {
+
+ /*! adds action version in output XML as userdata
+*/
+ public function version_output($conn, $out) {
+ $outJson = json_decode($out->__toString(), true);
+ if(!isset($outJson["userdata"]))
+ $outJson["userdata"] = array();
+
+ $outJson["userdata"] = array_merge($outJson["userdata"], $this->get_version());
+ $out->reset();
+ $out->add(json_encode($outJson));
+ }
+
+ /*! return action version in XMl format
+ */
+ public function get_version() {
+ $version = array("version" => $this->get_update_max_version());
+ return $version;
+ }
+
+ 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);
+
+ if(!isset($output["userdata"]))
+ $output["userdata"] = array();
+
+ $output["userdata"] = array_merge($output["userdata"], $this->get_version());
+ $this->output(json_encode($output));
+ }
+
+ protected function render_set($res, $name){
+ $output = array();
+ $index = 0;
+ while($data = $this->sql->get_next($res)) {
+ $data = new JSONDataItemUpdate($data, $this->config, $index, $name);
+ $this->event->trigger("beforeRender", $data);
+ array_push($output, $data->to_xml());
+ $index++;
+ }
+
+ return array("updates" => $output);
+ }
+
+ protected function output($res){
+ $out = new OutputWriter($res, "");
+ $out->set_type("json");
+ $this->event->trigger("beforeOutput", $this, $out);
+ $out->output("", true, $this->encoding);
+ }
+
+}
-?> \ No newline at end of file
+?>