summaryrefslogtreecommitdiffstats
path: root/codebase
diff options
context:
space:
mode:
Diffstat (limited to 'codebase')
-rw-r--r--codebase/base_connector.php44
-rw-r--r--codebase/data_connector.php215
-rw-r--r--codebase/grid_connector.php8
-rw-r--r--codebase/scheduler_connector.php118
-rw-r--r--codebase/strategy.php403
-rw-r--r--codebase/tree_connector.php65
-rw-r--r--codebase/treedatagroup_connector.php89
-rw-r--r--codebase/treedatamultitable_connector.php186
-rw-r--r--codebase/treegrid_connector.php71
-rw-r--r--codebase/treegridgroup_connector.php116
-rw-r--r--codebase/treegridmultitable_connector.php132
-rw-r--r--codebase/treegroup_connector.php116
-rw-r--r--codebase/treemultitable_connector.php133
13 files changed, 889 insertions, 807 deletions
diff --git a/codebase/base_connector.php b/codebase/base_connector.php
index 451c61d..48039a6 100644
--- a/codebase/base_connector.php
+++ b/codebase/base_connector.php
@@ -6,6 +6,7 @@
require_once("tools.php");
require_once("db_common.php");
require_once("dataprocessor.php");
+require_once("strategy.php");
require_once("update.php");
//enable buffering to catch and ignore any custom output before XML generation
@@ -290,18 +291,20 @@ class Connector {
@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($db,$type=false, $item_type=false, $data_type=false){
+ public function __construct($db,$type=false, $item_type=false, $data_type=false, $render_type = false){
$this->exec_time=microtime(true);
if (!$type) $type="MySQL";
if (class_exists($type."DBDataWrapper",false)) $type.="DBDataWrapper";
if (!$item_type) $item_type="DataItem";
if (!$data_type) $data_type="DataProcessor";
+ if (!$render_type) $render_type="RenderStrategy";
$this->names=array(
"db_class"=>$type,
"item_class"=>$item_type,
"data_class"=>$data_type,
+ "render_class"=>$render_type
);
$this->config = new DataConfig();
@@ -312,6 +315,7 @@ class Connector {
if (!class_exists($this->names["db_class"],false))
throw new Exception("DB class not found: ".$this->names["db_class"]);
$this->sql = new $this->names["db_class"]($db,$this->config);
+ $this->render = new $this->names["render_class"]($this);
$this->db=$db;//saved for options connectors, if any
@@ -332,7 +336,7 @@ class Connector {
}
public function get_request(){
- return new DataRequestConfig($this->config);
+ return new DataRequestConfig($this->request);
}
@@ -365,7 +369,7 @@ class Connector {
$this->request->set_source($table);
}
- protected function uuid(){
+ public function uuid(){
return time()."x".$this->id_seed++;
}
@@ -415,6 +419,7 @@ class Connector {
EventMaster::trigger_static("connectorInit",$this);
$this->parse_request();
+ $this->set_relation();
if ($this->live_update !== false && $this->updating!==false) {
$this->live_update->get_updates();
@@ -422,8 +427,7 @@ class Connector {
if ($this->editing){
$dp = new $this->names["data_class"]($this,$this->config,$this->request);
$dp->process($this->config,$this->request);
- }
- else {
+ } else {
if (!$this->access->check("read")){
LogMaster::log("Access control: read operation blocked");
echo "Access denied";
@@ -437,12 +441,25 @@ class Connector {
$this->event->trigger("beforeFilter",$wrap);
$wrap->store();
- $this->output_as_xml( $this->sql->select($this->request) );
+ $this->output_as_xml($this->get_resource());
}
}
$this->end_run();
}
-
+
+
+ /*! empty call which used for tree-logic
+ * to prevent code duplicating
+ */
+ protected function set_relation() {}
+
+ /*! gets resource for rendering
+ */
+ protected function get_resource() {
+ return $this->sql->select($this->request);
+ }
+
+
/*! prevent SQL injection through column names
replace dangerous chars in field names
@param str
@@ -551,18 +568,7 @@ class Connector {
process commands, output requested data as XML
*/
protected function render_set($res){
- $output="";
- $index=0;
- $this->event->trigger("beforeRenderSet",$this,$res,$this->config);
- while ($data=$this->sql->get_next($res)){
- $data = new $this->names["item_class"]($data,$this->config,$index);
- if ($data->get_id()===false)
- $data->set_id($this->uuid());
- $this->event->trigger("beforeRender",$data);
- $output.=$data->to_xml().$this->data_separator;
- $index++;
- }
- return $output;
+ return $this->render->render_set($res, $this->names["item_class"], $this->dload, $this->data_separator);
}
/*! output fetched data as XML
diff --git a/codebase/data_connector.php b/codebase/data_connector.php
index d66e64b..130d217 100644
--- a/codebase/data_connector.php
+++ b/codebase/data_connector.php
@@ -87,11 +87,12 @@ class DataConnector extends Connector{
@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){
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
if (!$item_type) $item_type="CommonDataItem";
if (!$data_type) $data_type="CommonDataProcessor";
$section = array();
- parent::__construct($res,$type,$item_type,$data_type);
+ if (!$render_type) $render_type="RenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
protected $sections;
@@ -121,6 +122,9 @@ class DataConnector extends Connector{
$this->editing = true;
}
} else {
+ if (isset($_GET["dhx_colls"]))
+ $this->fill_collections($_GET["dhx_colls"]);
+
if (isset($_GET['editing']) && isset($_POST['ids']))
$this->editing = true;
@@ -150,6 +154,55 @@ class JSONDataConnector extends DataConnector{
parent::__construct($res,$type,$item_type,$data_type);
}
+ /*! 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;
+ }
+
+
+ protected function fill_collections($list){
+ $names=explode(",",$list);
+ $options=array();
+ for ($i=0; $i < sizeof($names); $i++) {
+ $name = $this->resolve_parameter($names[$i]);
+ if (!array_key_exists($name,$this->options)){
+ $this->options[$name] = new JSONDistinctOptionsConnector($this->get_connection(),$this->names["db_class"]);
+ $c = new DataConfig($this->config);
+ $r = new DataRequestConfig($this->request);
+ $c->minimize($name);
+
+ $this->options[$name]->render_connector($c,$r);
+ }
+
+ $option="\"{$name}\":[";
+ if (!is_string($this->options[$name]))
+ $option.=substr($this->options[$name]->render(),0,-2);
+ else
+ $option.=$this->options[$name];
+ $option.="]";
+ $options[] = $option;
+ }
+ $this->extra_output .= implode(",", $options);
+ }
+
+ protected function resolve_parameter($name){
+ if (intval($name).""==$name)
+ return $this->config->text[intval($name)]["db_name"];
+ return $name;
+ }
+
protected function output_as_xml($res){
$start = "[\n";
$end = substr($this->render_set($res),0,-2)."\n]";
@@ -196,6 +249,50 @@ class JSONCommonDataItem extends DataItem{
}
}
+
+/*! wrapper around options collection, used for comboboxes and filters
+**/
+class JSONOptionsConnector extends JSONDataConnector{
+ protected $init_flag=false;//!< used to prevent rendering while initialization
+ public function __construct($res,$type=false,$item_type=false,$data_type=false){
+ if (!$item_type) $item_type="JSONCommonDataItem";
+ if (!$data_type) $data_type=""; //has not sense, options not editable
+ parent::__construct($res,$type,$item_type,$data_type);
+ }
+ /*! render self
+ process commands, return data as XML, not output data to stdout, ignore parameters in incoming request
+ @return
+ data as XML string
+ */
+ public function render(){
+ if (!$this->init_flag){
+ $this->init_flag=true;
+ return "";
+ }
+ $res = $this->sql->select($this->request);
+ return $this->render_set($res);
+ }
+}
+
+
+class JSONDistinctOptionsConnector extends JSONOptionsConnector{
+ /*! render self
+ process commands, return data as XML, not output data to stdout, ignore parameters in incoming request
+ @return
+ data as XML string
+ */
+ public function render(){
+ if (!$this->init_flag){
+ $this->init_flag=true;
+ return "";
+ }
+ $res = $this->sql->get_variants($this->config->text[0]["db_name"],$this->request);
+ return $this->render_set($res);
+ }
+}
+
+
+
class TreeCommonDataItem extends CommonDataItem{
protected $kids=-1;
@@ -223,116 +320,62 @@ class TreeCommonDataItem extends CommonDataItem{
class TreeDataConnector extends DataConnector{
- protected $id_swap = array();
- public function __construct($res,$type=false,$item_type=false,$data_type=false){
- if (!$item_type) $item_type="TreeCommonDataItem";
- if (!$data_type) $data_type="CommonDataProcessor";
- parent::__construct($res,$type,$item_type,$data_type);
+ protected $parent_name = 'parent';
- $this->event->attach("afterInsert",array($this,"parent_id_correction_a"));
- $this->event->attach("beforeProcessing",array($this,"parent_id_correction_b"));
- }
-
- protected function xml_start(){
- return "<data parent='".$this->request->get_relation()."'>";
- }
-
- /*! store info about ID changes during insert operation
- @param dataAction
- data action object during insert operation
- */
- public function parent_id_correction_a($dataAction){
- $this->id_swap[$dataAction->get_id()]=$dataAction->get_new_id();
- }
- /*! update ID if it was affected by previous operation
- @param dataAction
- data action object, before any processing operation
- */
- public function parent_id_correction_b($dataAction){
- $relation = $this->config->relation_id["db_name"];
- $value = $dataAction->get_value($relation);
+ /*! constructor
- if (array_key_exists($value,$this->id_swap))
- $dataAction->set_value($relation,$this->id_swap[$value]);
+ 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 provides data rendering
+ */
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
+ if (!$item_type) $item_type="TreeCommonDataItem";
+ if (!$data_type) $data_type="CommonDataProcessor";
+ if (!$render_type) $render_type="TreeRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
//parse GET scoope, all operations with incoming request must be done here
protected function parse_request(){
parent::parse_request();
- if (isset($_GET["parent"]))
- $this->request->set_relation($_GET["parent"]);
+ if (isset($_GET[$this->parent_name]))
+ $this->request->set_relation($_GET[$this->parent_name]);
else
$this->request->set_relation("0");
- }
- protected function render_set($res){
- $output="";
- $index=0;
- while ($data=$this->sql->get_next($res)){
- $data = new $this->names["item_class"]($data,$this->config,$index);
- $this->event->trigger("beforeRender",$data);
- //there is no info about child elements,
- //if we are using dyn. loading - assume that it has,
- //in normal mode just exec sub-render routine
- if ($data->has_kids()===-1 && $this->dload)
- $data->set_kids(true);
- $output.=$data->to_xml_start();
- if ($data->has_kids()===-1 || ( $data->has_kids()==true && !$this->dload)){
- $sub_request = new DataRequestConfig($this->request);
- $sub_request->set_relation($data->get_id());
- $output.=$this->render_set($this->sql->select($sub_request));
- }
- $output.=$data->to_xml_end();
- $index++;
- }
- return $output;
+ $this->request->set_limit(0,0); //netralize default reaction on dyn. loading mode
}
+ /*! renders self as xml, starting part
+ */
+ protected function xml_start(){
+ return "<data parent='".$this->request->get_relation()."'>";
+ }
}
class JSONTreeDataConnector extends TreeDataConnector{
- public function __construct($res,$type=false,$item_type=false,$data_type=false){
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type){
if (!$item_type) $item_type="JSONTreeCommonDataItem";
if (!$data_type) $data_type="CommonDataProcessor";
- parent::__construct($res,$type,$item_type,$data_type);
-
- $this->event->attach("afterInsert",array($this,"parent_id_correction_a"));
- $this->event->attach("beforeProcessing",array($this,"parent_id_correction_b"));
+ if (!$render_type) $render_type="JSONTreeRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
- protected function render_set($res){
- $output=array();
- $index=0;
- while ($data=$this->sql->get_next($res)){
- $data = new $this->names["item_class"]($data,$this->config,$index);
- $this->event->trigger("beforeRender",$data);
- //there is no info about child elements,
- //if we are using dyn. loading - assume that it has,
- //in normal mode just exec sub-render routine
- if ($data->has_kids()===-1 && $this->dload)
- $data->set_kids(true);
- $record = &$data->to_xml_start();
- if ($data->has_kids()===-1 || ( $data->has_kids()==true && !$this->dload)){
- $sub_request = new DataRequestConfig($this->request);
- $sub_request->set_relation($data->get_id());
- $temp = &$this->render_set($this->sql->select($sub_request));
- if (sizeof($temp))
- $record["data"] = $temp;
- }
- $output[] = $record;
- $index++;
- }
- return $output;
- }
-
protected function output_as_xml($res){
$data = array();
$data["parent"] = $this->request->get_relation();
$data["data"] = $this->render_set($res);
-
$out = new OutputWriter(json_encode($data), "");
$out->set_type("json");
$this->event->trigger("beforeOutput", $this, $out);
diff --git a/codebase/grid_connector.php b/codebase/grid_connector.php
index b9edc7a..a54799e 100644
--- a/codebase/grid_connector.php
+++ b/codebase/grid_connector.php
@@ -112,7 +112,8 @@ class GridDataItem extends DataItem{
foreach ($cattrs as $k => $v)
$str.=" ".$k."='".$this->xmlentities($v)."'";
}
- $str.="><![CDATA[".$this->data[$name]."]]></cell>";
+ $value = isset($this->data[$name]) ? $this->data[$name] : '';
+ $str.="><![CDATA[".$value."]]></cell>";
}
foreach ($this->userdata as $key => $value)
$str.="<userdata name='".$key."'><![CDATA[".$value."]]></userdata>";
@@ -145,10 +146,11 @@ class GridConnector extends Connector{
@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){
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
if (!$item_type) $item_type="GridDataItem";
if (!$data_type) $data_type="GridDataProcessor";
- parent::__construct($res,$type,$item_type,$data_type);
+ if (!$render_type) $render_type="RenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
diff --git a/codebase/scheduler_connector.php b/codebase/scheduler_connector.php
index c36c83f..f9921b1 100644
--- a/codebase/scheduler_connector.php
+++ b/codebase/scheduler_connector.php
@@ -31,7 +31,7 @@ class SchedulerDataItem extends DataItem{
class SchedulerConnector extends Connector{
protected $extra_output="";//!< extra info which need to be sent to client side
- private $options=array();//!< hash of OptionsConnector
+ protected $options=array();//!< hash of OptionsConnector
/*! assign options collection to the column
@@ -86,11 +86,14 @@ class SchedulerConnector extends Connector{
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){
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
if (!$item_type) $item_type="SchedulerDataItem";
if (!$data_type) $data_type="SchedulerDataProcessor";
- parent::__construct($res,$type,$item_type,$data_type);
+ if (!$render_type) $render_type="RenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
//parse GET scoope, all operations with incoming request must be done here
@@ -122,4 +125,113 @@ class SchedulerDataProcessor extends DataProcessor{
}
}
+
+class JSONSchedulerDataItem extends SchedulerDataItem{
+ /*! 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['end_date'] = $this->data[$this->config->text[1]["name"]];
+ $obj['text'] = $this->data[$this->config->text[2]["name"]];
+ for ($i=3; $i<sizeof($this->config->text); $i++){
+ $extra = $this->config->text[$i]["name"];
+ $obj[$extra]=$this->data[$extra];
+ }
+ return $obj;
+ }
+}
+
+
+class JSONSchedulerConnector extends SchedulerConnector {
+
+ protected $data_separator = ",";
+
+ /*! 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="JSONSchedulerDataItem";
+ if (!$data_type) $data_type="SchedulerDataProcessor";
+ 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();
+ return ', "collections": {'.$this->extra_output.'} }';
+ }
+
+
+ /*! 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(){
+ $options = array();
+ foreach ($this->options as $k=>$v) {
+ $name = $k;
+ $option="\"{$name}\":[";
+ if (!is_string($this->options[$name]))
+ $option.=substr($this->options[$name]->render(),0,-2);
+ 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){
+ $data=$this->xml_start();
+ $data.=$this->render_set($res);
+ $data.=$this->xml_end();
+
+ $out = new OutputWriter($data, "");
+ $out->set_type("json");
+ $this->event->trigger("beforeOutput", $this, $out);
+ $out->output("", true, $this->encoding);
+ }
+}
+
?> \ No newline at end of file
diff --git a/codebase/strategy.php b/codebase/strategy.php
new file mode 100644
index 0000000..fd6b8be
--- /dev/null
+++ b/codebase/strategy.php
@@ -0,0 +1,403 @@
+<?php
+
+class RenderStrategy {
+
+ protected $conn = null;
+
+ public function __construct($conn) {
+ $this->conn = $conn;
+ }
+
+ /*! render from DB resultset
+ @param res
+ DB resultset
+ process commands, output requested data as XML
+ */
+ public function render_set($res, $name, $dload, $sep){
+ $output="";
+ $index=0;
+ $conn = $this->conn;
+ $conn->event->trigger("beforeRenderSet",$conn,$res,$conn->get_config());
+ while ($data=$conn->sql->get_next($res)){
+ $data = new $name($data,$conn->get_config(),$index);
+ if ($data->get_id()===false)
+ $data->set_id($conn->uuid());
+ $conn->event->trigger("beforeRender",$data);
+ $output.=$data->to_xml().$sep;
+ $index++;
+ }
+ return $output;
+ }
+
+}
+
+class JSONRenderStrategy {
+
+ /*! render from DB resultset
+ @param res
+ DB resultset
+ process commands, output requested data as json
+ */
+ public function render_set($res, $name, $dload, $sep){
+ $output=array();
+ $index=0;
+ $conn = $this->conn;
+ $conn->event->trigger("beforeRenderSet",$conn,$res,$conn->get_config());
+ while ($data=$conn->sql->get_next($res)){
+ $data = new $name($data,$conn->get_config(),$index);
+ if ($data->get_id()===false)
+ $data->set_id($conn->uuid());
+ $conn->event->trigger("beforeRender",$data);
+ $output[]=$data->to_xml();
+ $index++;
+ }
+ return json_encode($output);
+ }
+
+}
+
+class TreeRenderStrategy extends RenderStrategy {
+
+ protected $id_swap = array();
+
+ public function __construct($conn) {
+ parent::__construct($conn);
+ $conn->event->attach("afterInsert",array($this,"parent_id_correction_a"));
+ $conn->event->attach("beforeProcessing",array($this,"parent_id_correction_b"));
+ }
+
+ public function render_set($res, $name, $dload, $sep){
+ $output="";
+ $index=0;
+ $conn = $this->conn;
+ while ($data=$conn->sql->get_next($res)){
+ $data = new $name($data,$conn->get_config(),$index);
+ $conn->event->trigger("beforeRender",$data);
+ //there is no info about child elements,
+ //if we are using dyn. loading - assume that it has,
+ //in normal mode juse exec sub-render routine
+ if ($data->has_kids()===-1 && $dload)
+ $data->set_kids(true);
+ $output.=$data->to_xml_start();
+ if ($data->has_kids()===-1 || ( $data->has_kids()==true && !$dload)){
+ $sub_request = new DataRequestConfig($conn->get_request());
+ $sub_request->set_relation($data->get_id());
+ $output.=$this->render_set($conn->sql->select($sub_request), $name, $dload, $sep);
+ }
+ $output.=$data->to_xml_end();
+ $index++;
+ }
+ return $output;
+ }
+
+ /*! store info about ID changes during insert operation
+ @param dataAction
+ data action object during insert operation
+ */
+ public function parent_id_correction_a($dataAction){
+ $this->id_swap[$dataAction->get_id()]=$dataAction->get_new_id();
+ }
+
+ /*! update ID if it was affected by previous operation
+ @param dataAction
+ data action object, before any processing operation
+ */
+ public function parent_id_correction_b($dataAction){
+ $relation = $this->conn->get_config()->relation_id["db_name"];
+ $value = $dataAction->get_value($relation);
+
+ if (array_key_exists($value,$this->id_swap))
+ $dataAction->set_value($relation,$this->id_swap[$value]);
+ }
+}
+
+
+
+class JSONTreeRenderStrategy extends TreeRenderStrategy {
+
+ public function render_set($res, $name, $dload, $sep){
+ $output=array();
+ $index=0;
+ $conn = $this->conn;
+ while ($data=$conn->sql->get_next($res)){
+ $data = new $name($data,$conn->get_config(),$index);
+ $conn->event->trigger("beforeRender",$data);
+ //there is no info about child elements,
+ //if we are using dyn. loading - assume that it has,
+ //in normal mode just exec sub-render routine
+ if ($data->has_kids()===-1 && $dload)
+ $data->set_kids(true);
+ $record = $data->to_xml_start();
+ if ($data->has_kids()===-1 || ( $data->has_kids()==true && !$dload)){
+ $sub_request = new DataRequestConfig($conn->get_request());
+ $sub_request->set_relation($data->get_id());
+ $temp = $this->render_set($conn->sql->select($sub_request), $name, $dload, $sep);
+ if (sizeof($temp))
+ $record["data"] = $temp;
+ }
+ $output[] = $record;
+ $index++;
+ }
+ return $output;
+ }
+
+}
+
+
+class MultitableTreeRenderStrategy extends TreeRenderStrategy {
+
+ private $level = 0;
+ private $max_level = null;
+ protected $sep = "#";
+
+ public function __construct($conn) {
+ parent::__construct($conn);
+ $conn->event->attach("beforeProcessing", Array($this, 'id_translate_before'));
+ $conn->event->attach("afterProcessing", Array($this, 'id_translate_after'));
+ }
+
+ public function set_separator($sep) {
+ $this->sep = $sep;
+ }
+
+ public function render_set($res, $name, $dload, $sep){
+ $output="";
+ $index=0;
+ $conn = $this->conn;
+ $config = $conn->get_config();
+ while ($data=$conn->sql->get_next($res)){
+ $data[$config->id['name']] = $this->level_id($data[$config->id['name']]);
+ $data = new $name($data,$config,$index);
+ $conn->event->trigger("beforeRender",$data);
+ if (($this->max_level !== null)&&($conn->get_level() == $this->max_level)) {
+ $data->set_kids(false);
+ } else {
+ if ($data->has_kids()===-1)
+ $data->set_kids(true);
+ }
+ $output.=$data->to_xml_start();
+ $output.=$data->to_xml_end();
+ $index++;
+ }
+ return $output;
+ }
+
+
+ public function level_id($id, $level = null) {
+ return ($level === null ? $this->level : $level).$this->sep.$id;
+ }
+
+
+ /*! remove level prefix from id, parent id and set new id before processing
+ @param action
+ DataAction object
+ */
+ public function id_translate_before($action) {
+ $id = $action->get_id();
+ $id = $this->parse_id($id, false);
+ $action->set_id($id);
+ $action->set_value('tr_id', $id);
+ $action->set_new_id($id);
+ $pid = $action->get_value($this->conn->get_config()->relation_id['db_name']);
+ $pid = $this->parse_id($pid, false);
+ $action->set_value($this->conn->get_config()->relation_id['db_name'], $pid);
+ }
+
+
+ /*! add level prefix in id and new id after processing
+ @param action
+ DataAction object
+ */
+ public function id_translate_after($action) {
+ $id = $action->get_id();
+ $action->set_id($this->level_id($id));
+ $id = $action->get_new_id();
+ $action->success($this->level_id($id));
+ }
+
+
+ public function get_level($parent_name) {
+ if ($this->level) return $this->level;
+ if (!isset($_GET[$parent_name])) {
+ if (isset($_POST['ids'])) {
+ $ids = explode(",",$_POST["ids"]);
+ $id = $this->parse_id($ids[0]);
+ $this->level--;
+ }
+ $this->conn->get_request()->set_relation(false);
+ } else {
+ $id = $this->parse_id($_GET[$parent_name]);
+ $_GET[$parent_name] = $id;
+ }
+ return $this->level;
+ }
+
+
+ public function is_max_level() {
+ if (($this->max_level !== null) && ($this->level >= $this->max_level))
+ return true;
+ return false;
+ }
+ public function set_max_level($max_level) {
+ $this->max_level = $max_level;
+ }
+ public function parse_id($id, $set_level = true) {
+ $parts = explode('#', urldecode($id));
+ if (count($parts) === 2) {
+ $level = $parts[0] + 1;
+ $id = $parts[1];
+ } else {
+ $level = 0;
+ $id = '';
+ }
+ if ($set_level) $this->level = $level;
+ return $id;
+ }
+
+}
+
+
+class JSONMultitableTreeRenderStrategy extends MultitableTreeRenderStrategy {
+
+ public function render_set($res, $name, $dload, $sep){
+ $output=array();
+ $index=0;
+ $conn = $this->conn;
+ $config = $conn->get_config();
+ while ($data=$conn->sql->get_next($res)){
+ $data[$config->id['name']] = $this->level_id($data[$config->id['name']]);
+ $data = new $name($data,$config,$index);
+ $conn->event->trigger("beforeRender",$data);
+
+ if ($this->is_max_level()) {
+ $data->set_kids(false);
+ } else {
+ if ($data->has_kids()===-1)
+ $data->set_kids(true);
+ }
+ $record = $data->to_xml_start($output);
+ $output[] = $record;
+ $index++;
+ }
+ return $output;
+ }
+
+}
+
+
+class GroupRenderStrategy extends RenderStrategy {
+
+ private $id_postfix = '__{group_param}';
+
+ public function __construct($conn) {
+ parent::__construct($conn);
+ $conn->event->attach("beforeProcessing", Array($this, 'check_id'));
+ $conn->event->attach("onInit", Array($this, 'replace_postfix'));
+ }
+
+ public function render_set($res, $name, $dload, $sep){
+ $output="";
+ $index=0;
+ $conn = $this->conn;
+ $config = $conn->get_config();
+ while ($data=$conn->sql->get_next($res)){
+ if (isset($data[$config->id['name']])) {
+ $has_kids = false;
+ } else {
+ $data[$config->id['name']] = $data['value'].$this->id_postfix;
+ $data[$config->text[0]['name']] = $data['value'];
+ $has_kids = true;
+ }
+ $data = new $name($data,$config,$index);
+ $conn->event->trigger("beforeRender",$data);
+ if ($has_kids === false) {
+ $data->set_kids(false);
+ }
+
+ if ($data->has_kids()===-1 && $dload)
+ $data->set_kids(true);
+ $output.=$data->to_xml_start();
+ if (($data->has_kids()===-1 || ( $data->has_kids()==true && !$dload))&&($has_kids == true)){
+ $sub_request = new DataRequestConfig($conn->get_request());
+ $sub_request->set_relation(str_replace($this->id_postfix, "", $data->get_id()));
+ $output.=$this->render_set($conn->sql->select($sub_request), $name, $dload, $sep);
+ }
+ $output.=$data->to_xml_end();
+ $index++;
+ }
+ return $output;
+ }
+
+ public function check_id($action) {
+ if (isset($_GET['editing'])) {
+ $config = $this->conn->get_config();
+ $id = $action->get_id();
+ $pid = $action->get_value($config->relation_id['name']);
+ $pid = str_replace($this->id_postfix, "", $pid);
+ $action->set_value($config->relation_id['name'], $pid);
+ if (!empty($pid)) {
+ return $action;
+ } else {
+ $action->error();
+ $action->set_response_text("This record can't be updated!");
+ return $action;
+ }
+ } else {
+ return $action;
+ }
+ }
+
+ public function replace_postfix() {
+ if (isset($_GET['id'])) {
+ $_GET['id'] = str_replace($this->id_postfix, "", $_GET['id']);
+ }
+ }
+
+ public function get_postfix() {
+ return $this->id_postfix;
+ }
+
+}
+
+
+class JSONGroupRenderStrategy extends GroupRenderStrategy {
+
+ public function render_set($res, $name, $dload, $sep){
+ $output=array();
+ $index=0;
+ $conn = $this->conn;
+ $config = $conn->get_config();
+ while ($data=$conn->sql->get_next($res)){
+ if (isset($data[$config->id['name']])) {
+ $has_kids = false;
+ } else {
+ $data[$config->id['name']] = $data['value'].$this->id_postfix;
+ $data[$config->text[0]['name']] = $data['value'];
+ $has_kids = true;
+ }
+ $data = new $name($data,$config,$index);
+ $conn->event->trigger("beforeRender",$data);
+ if ($has_kids === false) {
+ $data->set_kids(false);
+ }
+
+ if ($data->has_kids()===-1 && $dload)
+ $data->set_kids(true);
+ $record = $data->to_xml_start();
+ if (($data->has_kids()===-1 || ( $data->has_kids()==true && !$dload))&&($has_kids == true)){
+ $sub_request = new DataRequestConfig($conn->get_request());
+ $sub_request->set_relation(str_replace($this->id_postfix, "", $data->get_id()));
+ $temp = $this->render_set($conn->sql->select($sub_request), $name, $dload, $sep);
+ if (sizeof($temp))
+ $record["data"] = $temp;
+ }
+ $output[] = $record;
+ $index++;
+ }
+ return $output;
+ }
+
+}
+
+
+?> \ No newline at end of file
diff --git a/codebase/tree_connector.php b/codebase/tree_connector.php
index dff0867..850de0d 100644
--- a/codebase/tree_connector.php
+++ b/codebase/tree_connector.php
@@ -160,8 +160,8 @@ require_once("filesystem_item.php");
/*! Connector for the dhtmlxtree
**/
class TreeConnector extends Connector{
- private $id_swap = array();
-
+ protected $parent_name = 'id';
+
/*! constructor
Here initilization of all Masters occurs, execution timer initialized
@@ -173,71 +173,28 @@ class TreeConnector extends Connector{
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 provides data rendering
*/
- public function __construct($res,$type=false,$item_type=false,$data_type=false){
+ public function __construct($res,$type=false,$item_type=false,$data_type=false, $render_type=false){
if (!$item_type) $item_type="TreeDataItem";
if (!$data_type) $data_type="TreeDataProcessor";
- parent::__construct($res,$type,$item_type,$data_type);
-
- $this->event->attach("afterInsert",array($this,"parent_id_correction_a"));
- $this->event->attach("beforeProcessing",array($this,"parent_id_correction_b"));
- }
-
- /*! store info about ID changes during insert operation
- @param dataAction
- data action object during insert operation
- */
- public function parent_id_correction_a($dataAction){
- $this->id_swap[$dataAction->get_id()]=$dataAction->get_new_id();
+ if (!$render_type) $render_type="TreeRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
- /*! update ID if it was affected by previous operation
- @param dataAction
- data action object, before any processing operation
- */
- public function parent_id_correction_b($dataAction){
- $relation = $this->config->relation_id["db_name"];
- $value = $dataAction->get_value($relation);
-
- if (array_key_exists($value,$this->id_swap))
- $dataAction->set_value($relation,$this->id_swap[$value]);
- }
-
-
+
+ //parse GET scoope, all operations with incoming request must be done here
public function parse_request(){
parent::parse_request();
- if (isset($_GET["id"]))
- $this->request->set_relation($_GET["id"]);
+ if (isset($_GET[$this->parent_name]))
+ $this->request->set_relation($_GET[$this->parent_name]);
else
$this->request->set_relation("0");
$this->request->set_limit(0,0); //netralize default reaction on dyn. loading mode
}
-
-
- protected function render_set($res){
- $output="";
- $index=0;
- while ($data=$this->sql->get_next($res)){
- $data = new $this->names["item_class"]($data,$this->config,$index);
- $this->event->trigger("beforeRender",$data);
- //there is no info about child elements,
- //if we are using dyn. loading - assume that it has,
- //in normal mode juse exec sub-render routine
- if ($data->has_kids()===-1 && $this->dload)
- $data->set_kids(true);
- $output.=$data->to_xml_start();
- if ($data->has_kids()===-1 || ( $data->has_kids()==true && !$this->dload)){
- $sub_request = new DataRequestConfig($this->request);
- $sub_request->set_relation($data->get_id());
- $output.=$this->render_set($this->sql->select($sub_request));
- }
- $output.=$data->to_xml_end();
- $index++;
- }
- return $output;
- }
/*! renders self as xml, starting part
*/
public function xml_start(){
diff --git a/codebase/treedatagroup_connector.php b/codebase/treedatagroup_connector.php
new file mode 100644
index 0000000..336915a
--- /dev/null
+++ b/codebase/treedatagroup_connector.php
@@ -0,0 +1,89 @@
+<?php
+/*
+ @author dhtmlx.com
+ @license GPL, see license.txt
+*/
+require_once("data_connector.php");
+
+class TreeDataGroupConnector extends TreeDataConnector{
+
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
+ if (!$render_type) $render_type="GroupRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
+ }
+
+ /*! if not isset $_GET[id] then it's top level
+ */
+ protected function set_relation() {
+ if (!isset($_GET[$this->parent_name])) $this->request->set_relation(false);
+ }
+
+ /*! if it's first level then distinct level
+ * else select by parent
+ */
+ protected function get_resource() {
+ $resource = null;
+ if (isset($_GET[$this->parent_name]))
+ $resource = $this->sql->select($this->request);
+ else
+ $resource = $this->sql->get_variants($this->config->relation_id['name'], $this->request);
+ return $resource;
+ }
+
+
+ /*! renders self as xml, starting part
+ */
+ public function xml_start(){
+ if (isset($_GET[$this->parent_name])) {
+ return "<data parent='".$_GET[$this->parent_name].$this->render->get_postfix()."'>";
+ } else {
+ return "<data parent='0'>";
+ }
+ }
+
+}
+
+
+
+
+class JSONTreeDataGroupConnector extends JSONTreeDataConnector{
+
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
+ if (!$render_type) $render_type="JSONGroupRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
+ }
+
+ /*! if not isset $_GET[id] then it's top level
+ */
+ protected function set_relation() {
+ if (!isset($_GET[$this->parent_name])) $this->request->set_relation(false);
+ }
+
+ /*! if it's first level then distinct level
+ * else select by parent
+ */
+ protected function get_resource() {
+ $resource = null;
+ if (isset($_GET[$this->parent_name]))
+ $resource = $this->sql->select($this->request);
+ else
+ $resource = $this->sql->get_variants($this->config->relation_id['name'], $this->request);
+ return $resource;
+ }
+
+
+ /*! renders self as xml, starting part
+ */
+ public function xml_start(){
+ if (isset($_GET[$this->parent_name])) {
+ return "<data parent='".$_GET[$this->parent_name].$this->render->get_postfix()."'>";
+ } else {
+ return "<data parent='0'>";
+ }
+ }
+
+}
+
+
+
+?> \ No newline at end of file
diff --git a/codebase/treedatamultitable_connector.php b/codebase/treedatamultitable_connector.php
index 3e116b6..79cc9a4 100644
--- a/codebase/treedatamultitable_connector.php
+++ b/codebase/treedatamultitable_connector.php
@@ -3,167 +3,47 @@
@author dhtmlx.com
@license GPL, see license.txt
*/
-require_once("tree_connector.php");
+require_once("data_connector.php");
class TreeDataMultitableConnector extends TreeDataConnector{
- protected $level = 0;
- protected $max_level = null;
+ protected $parent_name = 'parent';
- public function __construct($res,$type=false,$item_type=false,$data_type=false){
- $data_type="TreeDataProcessor";
- parent::__construct($res,$type,$item_type,$data_type);
- $this->event->attach("beforeProcessing", Array($this, 'id_translate_before'));
- $this->event->attach("afterProcessing", Array($this, 'id_translate_after'));
- }
-
-
- //parse GET scoope, all operations with incoming request must be done here
- protected function parse_request(){
- parent::parse_request();
-
- if (isset($_GET["parent"]))
- $this->request->set_relation($this->parse_id($_GET["parent"], true));
- else
- $this->request->set_relation("0");
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
+ if (!$data_type) $data_type="TreeDataProcessor";
+ if (!$render_type) $render_type="MultitableTreeRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
public function render(){
- $this->event->trigger("onInit", $this);
- EventMaster::trigger_static("connectorInit",$this);
-
- $this->parse_request();
$this->dload = true;
-
- if ($this->live_update !== false && $this->updating!==false) {
- $this->live_update->get_updates();
- } else {
- if ($this->editing){
- $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->event->trigger("beforeSort",$wrap);
- $wrap->store();
-
- $wrap = new FilterInterface($this->request);
- $this->event->trigger("beforeFilter",$wrap);
- $wrap->store();
-
- if (!isset($_GET['parent']))
- $this->request->set_relation(false);
- $this->output_as_xml( $this->sql->select($this->request) );
- }
- }
- $this->end_run();
+ return parent::render();
}
- protected function render_set($res){
- $output="";
- $index=0;
- while ($data=$this->sql->get_next($res)){
- $data[$this->config->id['name']] = $this->level_id($data[$this->config->id['name']]);
- $data = new $this->names["item_class"]($data,$this->config,$index);
- $this->event->trigger("beforeRender",$data);
-
- if (($this->max_level !== null)&&($this->level == $this->max_level)) {
- $data->set_kids(false);
- } else {
- if ($data->has_kids()===-1)
- $data->set_kids(true);
- }
- $output.=$data->to_xml_start();
- $output.=$data->to_xml_end();
- $index++;
- }
- return $output;
+ /*! sets relation for rendering */
+ protected function set_relation() {
+ if (!isset($_GET[$this->parent_name]))
+ $this->request->set_relation(false);
}
public function xml_start(){
- if (isset($_GET['parent'])) {
- return "<data parent='".$_GET['parent']."'>";
+ if (isset($_GET[$this->parent_name])) {
+ return "<data parent='".$this->render->level_id($_GET[$this->parent_name], $this->render->get_level() - 1)."'>";
} else {
return "<data parent='0'>";
}
}
-
- public function get_level() {
- if (isset($_GET['parent']))
- $this->parse_id($_GET['parent']);
- else if (isset($_POST['ids'])) {
- $ids = explode(",",$_POST["ids"]);
- if (isset($ids[0])) $this->parse_id($ids[0]);
- $this->level -= 1;
- }
- return $this->level;
- }
-
- public function parse_id($id, $set_level = true) {
- $parts = explode('#', $id);
- if (count($parts) === 2) {
- $level = $parts[0] + 1;
- $id = $parts[1];
- } else {
- $level = 0;
- $id = '';
- }
- if ($set_level) $this->level = $level;
- return $id;
- }
-
- public function level_id($id) {
- return $this->level.'#'.$id;
- }
-
/*! set maximum level of tree
@param max_level
maximum level
*/
public function setMaxLevel($max_level) {
- $this->max_level = $max_level;
- }
-
-
- protected function is_max_level() {
- if (($this->max_level !== null) && ($this->level >= $this->max_level))
- return true;
- return false;
-
+ $this->render->set_max_level($max_level);
}
-
-
- /*! remove level prefix from id, parent id and set new id before processing
- @param action
- DataAction object
- */
- public function id_translate_before($action) {
- $id = $action->get_id();
- $id = $this->parse_id($id, false);
- $action->set_id($id);
- $action->set_value('tr_id', $id);
- $action->set_new_id($id);
- $pid = $action->get_value($this->config->relation_id['db_name']);
- $pid = $this->parse_id($pid, false);
- $action->set_value($this->config->relation_id['db_name'], $pid);
- }
-
- /*! add level prefix in id and new id after processing
- @param action
- DataAction object
- */
- public function id_translate_after($action) {
- $id = $action->get_id();
- $action->set_id($this->level_id($id));
- $id = $action->get_new_id();
- $action->success($this->level_id($id));
+ public function get_level() {
+ return $this->render->get_level($this->parent_name);
}
}
@@ -175,39 +55,19 @@ class TreeDataMultitableConnector extends TreeDataConnector{
class JSONTreeDataMultitableConnector extends TreeDataMultitableConnector{
- public function __construct($res,$type=false,$item_type=false,$data_type=false){
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
if (!$item_type) $item_type="JSONTreeCommonDataItem";
if (!$data_type) $data_type="CommonDataProcessor";
- parent::__construct($res,$type,$item_type,$data_type);
-
- $this->event->attach("beforeProcessing", Array($this, 'id_translate_before'));
- $this->event->attach("afterProcessing", Array($this, 'id_translate_after'));
- }
-
- protected function render_set($res){
- $output=array();
- $index=0;
- while ($data=$this->sql->get_next($res)){
- $data[$this->config->id['name']] = $this->level_id($data[$this->config->id['name']]);
- $data = new $this->names["item_class"]($data,$this->config,$index);
- $this->event->trigger("beforeRender",$data);
-
- if ($this->is_max_level()) {
- $data->set_kids(false);
- } else {
- if ($data->has_kids()===-1)
- $data->set_kids(true);
- }
- $record = $data->to_xml_start($output);
- $output[] = $record;
- $index++;
- }
- return $output;
+ if (!$render_type) $render_type="JSONMultitableTreeRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
protected function output_as_xml($res){
$data = array();
- $data["parent"] = isset($_GET['parent']) ? $_GET['parent'] : '0';
+ if (isset($_GET['parent']))
+ $data["parent"] = $this->render->level_id($_GET[$this->parent_name], $this->render->get_level() - 1);
+ else
+ $data["parent"] = "0";
$data["data"] = $this->render_set($res);
$out = new OutputWriter(json_encode($data), "");
diff --git a/codebase/treegrid_connector.php b/codebase/treegrid_connector.php
index 308fcf4..f074879 100644
--- a/codebase/treegrid_connector.php
+++ b/codebase/treegrid_connector.php
@@ -52,8 +52,8 @@ class TreeGridDataItem extends GridDataItem{
/*! Connector for dhtmlxTreeGrid
**/
class TreeGridConnector extends GridConnector{
- private $id_swap = array();
-
+ protected $parent_name = 'id';
+
/*! constructor
Here initilization of all Masters occurs, execution timer initialized
@@ -65,73 +65,28 @@ class TreeGridConnector extends GridConnector{
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 provides data rendering
*/
- public function __construct($res,$type=false,$item_type=false,$data_type=false){
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
if (!$item_type) $item_type="TreeGridDataItem";
if (!$data_type) $data_type="TreeGridDataProcessor";
- parent::__construct($res,$type,$item_type,$data_type);
-
- $this->event->attach("afterInsert",array($this,"parent_id_correction_a"));
- $this->event->attach("beforeProcessing",array($this,"parent_id_correction_b"));
+ if (!$render_type) $render_type="TreeRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
- /*! store info about ID changes during insert operation
- @param dataAction
- data action object during insert operation
- */
- public function parent_id_correction_a($dataAction){
- $this->id_swap[$dataAction->get_id()]=$dataAction->get_new_id();
- }
- /*! update ID if it was affected by previous operation
- @param dataAction
- data action object, before any processing operation
- */
- public function parent_id_correction_b($dataAction){
- $relation = $this->config->relation_id["db_name"];
- $value = $dataAction->get_value($relation);
-
- if (array_key_exists($value,$this->id_swap))
- $dataAction->set_value($relation,$this->id_swap[$value]);
- }
-
- /*! process treegrid specific options in incoming request
- */
+ /*! process treegrid specific options in incoming request */
public function parse_request(){
parent::parse_request();
-
- if (isset($_GET["id"]))
- $this->request->set_relation($_GET["id"]);
+
+ if (isset($_GET[$this->parent_name]))
+ $this->request->set_relation($_GET[$this->parent_name]);
else
$this->request->set_relation("0");
-
+
$this->request->set_limit(0,0); //netralize default reaction on dyn. loading mode
}
-
- /*! process treegrid specific options in incoming request
- */
- protected function render_set($res){
- $output="";
- $index=0;
- while ($data=$this->sql->get_next($res)){
- $data = new $this->names["item_class"]($data,$this->config,$index);
- $this->event->trigger("beforeRender",$data);
- //there is no info about child elements,
- //if we are using dyn. loading - assume that it has,
- //in normal mode juse exec sub-render routine
- if ($data->has_kids()===-1 && $this->dload)
- $data->set_kids(true);
- $output.=$data->to_xml_start();
- if ($data->has_kids()===-1 || ( $data->has_kids()==true && !$this->dload)){
- $sub_request = new DataRequestConfig($this->request);
- $sub_request->set_relation($data->get_id());
- $output.=$this->render_set($this->sql->select($sub_request));
- }
- $output.=$data->to_xml_end();
- $index++;
- }
- return $output;
- }
-
+
/*! renders self as xml, starting part
*/
protected function xml_start(){
diff --git a/codebase/treegridgroup_connector.php b/codebase/treegridgroup_connector.php
index b8c725e..cd8fdf2 100644
--- a/codebase/treegridgroup_connector.php
+++ b/codebase/treegridgroup_connector.php
@@ -7,116 +7,40 @@ require_once("treegrid_connector.php");
class TreeGridGroupConnector extends TreeGridConnector{
- private $id_postfix = '__{group_param}';
-
- public function __construct($res,$type=false,$item_type=false,$data_type=false){
- parent::__construct($res,$type,$item_type,$data_type);
- $this->event->attach("beforeProcessing", Array($this, 'check_id'));
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
+ if (!$render_type) $render_type="GroupRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
-
- public function render(){
- if (isset($_GET['id'])) {
- $_GET['id'] = str_replace($this->id_postfix, "", $_GET['id']);
- }
- $this->parse_request();
- if (!isset($_GET['id'])) {
- $this->request->set_relation(false);
- }
-
- if (isset($_GET["editing"]))
- $this->editing=true;
- else if (isset($_POST["ids"])){
- $this->editing=true;
- } else {
- $this->editing = false;
- }
-
- if ($this->editing){
- $dp = new $this->names["data_class"]($this,$this->config,$this->request);
- $dp->process($this->config,$this->request);
- }
- else {
- $wrap = new SortInterface($this->request);
- $this->event->trigger("beforeSort",$wrap);
- $wrap->store();
-
- $wrap = new FilterInterface($this->request);
- $this->event->trigger("beforeFilter",$wrap);
- $wrap->store();
-
- if (isset($_GET['id'])) {
- $this->output_as_xml( $this->sql->select($this->request) );
- } else {
- $relation_id = $this->config->relation_id['name'];
- $this->output_as_xml( $this->sql->get_variants($this->config->relation_id['name'], $this->request));
- }
- }
- $this->end_run();
+ /*! if not isset $_GET[id] then it's top level
+ */
+ protected function set_relation() {
+ if (!isset($_GET[$this->parent_name])) $this->request->set_relation(false);
}
-
- protected function render_set($res){
- $output="";
- $index=0;
- $records = Array();
- while ($data=$this->sql->get_next($res)){
- if (isset($data[$this->config->id['name']])) {
- $has_kids = false;
- } else {
- $data[$this->config->id['name']] = $data['value'].$this->id_postfix;
- $data[$this->config->text[0]['name']] = $data['value'];
- $has_kids = true;
- }
- $data = new $this->names["item_class"]($data,$this->config,$index);
- $this->event->trigger("beforeRender",$data);
- if ($has_kids === false) {
- $data->set_kids(false);
- }
-
- if ($data->has_kids()===-1 && $this->dload)
- $data->set_kids(true);
- $output.=$data->to_xml_start();
- if (($data->has_kids()===-1 || ( $data->has_kids()==true && !$this->dload))&&($has_kids == true)){
- $sub_request = new DataRequestConfig($this->request);
- $sub_request->set_relation(str_replace($this->id_postfix, "", $data->get_id()));
- $output.=$this->render_set($this->sql->select($sub_request));
- }
- $output.=$data->to_xml_end();
- $index++;
- }
- return $output;
+ /*! if it's first level then distinct level
+ * else select by parent
+ */
+ protected function get_resource() {
+ $resource = null;
+ if (isset($_GET[$this->parent_name]))
+ $resource = $this->sql->select($this->request);
+ else
+ $resource = $this->sql->get_variants($this->config->relation_id['name'], $this->request);
+ return $resource;
}
/*! renders self as xml, starting part
*/
protected function xml_start(){
- if (isset($_GET['id'])) {
- return "<rows parent='".$_GET['id'].$this->id_postfix."'>";
+ if (isset($_GET[$this->parent_name])) {
+ return "<rows parent='".$_GET[$this->parent_name].$this->render->get_postfix()."'>";
} else {
return "<rows parent='0'>";
}
}
-
-
- public function check_id($action) {
- if (isset($_GET['editing'])) {
- $id = $action->get_id();
- $pid = $action->get_value($this->config->relation_id['name']);
- $pid = str_replace($this->id_postfix, "", $pid);
- $action->set_value($this->config->relation_id['name'], $pid);
- if (strpos($id, $this->id_postfix) == false) {
- return $action;
- } else {
- $action->error();
- $action->set_response_text("This record can't be updated!");
- return $action;
- }
- } else {
- return $action;
- }
- }
+
}
?> \ No newline at end of file
diff --git a/codebase/treegridmultitable_connector.php b/codebase/treegridmultitable_connector.php
index 8d16bda..af32ca2 100644
--- a/codebase/treegridmultitable_connector.php
+++ b/codebase/treegridmultitable_connector.php
@@ -7,144 +7,45 @@ require_once("treegrid_connector.php");
class TreeGridMultitableConnector extends TreeGridConnector{
- private $level = 0;
- private $max_level = null;
-
- public function __construct($res,$type=false,$item_type=false,$data_type=false){
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
$data_type="TreeGridMultitableDataProcessor";
- parent::__construct($res,$type,$item_type,$data_type);
- $this->event->attach("beforeProcessing", Array($this, 'id_translate_before'));
- $this->event->attach("afterProcessing", Array($this, 'id_translate_after'));
+ if (!$render_type) $render_type="MultitableTreeRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
+ $this->render->set_separator("%23");
}
public function render(){
- $this->parse_request();
$this->dload = true;
- if ((isset($_GET["editing"]))||(isset($_POST["ids"]))) {
- $this->editing=true;
- } else {
- $this->editing = false;
- }
-
- if ($this->editing){
- $dp = new $this->names["data_class"]($this,$this->config,$this->request);
- $dp->process($this->config,$this->request);
- } else {
- $wrap = new SortInterface($this->request);
- $this->event->trigger("beforeSort",$wrap);
- $wrap->store();
-
- $wrap = new FilterInterface($this->request);
- $this->event->trigger("beforeFilter",$wrap);
- $wrap->store();
-
- if (isset($_GET['id'])) {
- $this->output_as_xml( $this->sql->select($this->request) );
- } else {
- $this->request->set_relation(false);
- $this->output_as_xml( $this->sql->select($this->request) );
- }
- }
- $this->end_run();
+ return parent::render();
}
-
- protected function render_set($res){
- $output="";
- $index=0;
- $records = Array();
- while ($data=$this->sql->get_next($res)){
- $data[$this->config->id['name']] = $this->level.'%23'.$data[$this->config->id['name']];
- $data = new $this->names["item_class"]($data,$this->config,$index);
- $this->event->trigger("beforeRender",$data);
- if (($this->max_level !== null)&&($this->level == $this->max_level)) {
- $data->set_kids(false);
- } else {
- if ($data->has_kids()===-1)
- $data->set_kids(true);
- }
- $output.=$data->to_xml_start();
- $output.=$data->to_xml_end();
- $index++;
- }
- return $output;
+ /*! sets relation for rendering */
+ protected function set_relation() {
+ if (!isset($_GET['id']))
+ $this->request->set_relation(false);
}
-
public function xml_start(){
if (isset($_GET['id'])) {
- return "<rows parent='".($this->level - 1).'%23'.$_GET['id']."'>";
- } else {
- return "<rows parent=''>";
- }
- }
-
-
- public function get_level() {
- if (!isset($_GET['id'])) {
- if (isset($_POST['ids'])) {
- $ids = explode(",",$_POST["ids"]);
- $id = $this->parseId($ids[0]);
- $this->level--;
- }
- $this->request->set_relation(false);
+ return "<rows parent='".$this->render->level_id($_GET['id'], $this->render->get_level() - 1)."'>";
} else {
- $id = $this->parseId($_GET['id']);
- $_GET['id'] = $id;
- }
- return $this->level;
- }
-
-
- public function parseId($id, $set_level = true) {
- $result = Array();
- preg_match('/^(.+)((#)|(%23))/', $id, $result);
- if ($set_level === true) {
- $this->level = $result[1] + 1;
+ return "<rows parent='0'>";
}
- preg_match('/^(.+)((#)|(%23))(.*)$/', $id, $result);
- $id = $result[5];
- return $id;
}
-
/*! set maximum level of tree
@param max_level
maximum level
*/
public function setMaxLevel($max_level) {
- $this->max_level = $max_level;
+ $this->render->set_max_level($max_level);
}
-
- /*! remove level prefix from id, parent id and set new id before processing
- @param action
- DataAction object
- */
- public function id_translate_before($action) {
- $this->request->set_relation(false);
- $id = $action->get_id();
- $id = $this->parseId($id, false);
- $action->set_id($id);
- $action->set_value('gr_id', $id);
- $action->set_new_id($id);
- $pid = $action->get_value($this->config->relation_id['db_name']);
- $pid = $this->parseId($pid, false);
- $action->set_value($this->config->relation_id['db_name'], $pid);
+ public function get_level() {
+ return $this->render->get_level($this->parent_name);
}
- /*! add level prefix in id and new id after processing
- @param action
- DataAction object
- */
- public function id_translate_after($action) {
- $id = $action->get_id();
- $action->set_id(($this->level).'%23'.$id);
- $id = $action->get_new_id();
- $action->success(($this->level).'%23'.$id);
- }
-
}
@@ -153,7 +54,10 @@ class TreeGridMultitableDataProcessor extends DataProcessor {
function name_data($data){
if ($data=="gr_pid")
return $this->config->relation_id["name"];
- preg_match('/^c(\d+)$/', $data, $data_num);
+ if ($data=="gr_id")
+ return $this->config->id["name"];
+ preg_match('/^c([%\d]+)$/', $data, $data_num);
+ if (!isset($data_num[1])) return $data;
$data_num = $data_num[1];
if (isset($this->config->data[$data_num]["db_name"])) {
return $this->config->data[$data_num]["db_name"];
diff --git a/codebase/treegroup_connector.php b/codebase/treegroup_connector.php
index 16db63c..5266d0b 100644
--- a/codebase/treegroup_connector.php
+++ b/codebase/treegroup_connector.php
@@ -7,112 +7,40 @@ require_once("tree_connector.php");
class TreeGroupConnector extends TreeConnector{
- private $id_postfix = '__{group_param}';
-
- public function __construct($res,$type=false,$item_type=false,$data_type=false){
- parent::__construct($res,$type,$item_type,$data_type);
- $this->event->attach("beforeProcessing", Array($this, 'check_id'));
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
+ if (!$render_type) $render_type="GroupRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
-
- public function render(){
- if (isset($_GET['id'])) {
- $_GET['id'] = str_replace($this->id_postfix, "", $_GET['id']);
- }
- $this->parse_request();
- if (!isset($_GET['id'])) {
- $this->request->set_relation(false);
- }
-
- if (isset($_GET["editing"]))
- $this->editing=true;
- else if (isset($_POST["ids"])){
- $this->editing=true;
- } else {
- $this->editing = false;
- }
-
- if ($this->editing){
- $dp = new $this->names["data_class"]($this,$this->config,$this->request);
- $dp->process($this->config,$this->request);
- }
- else {
- $wrap = new SortInterface($this->request);
- $this->event->trigger("beforeSort",$wrap);
- $wrap->store();
-
- $wrap = new FilterInterface($this->request);
- $this->event->trigger("beforeFilter",$wrap);
- $wrap->store();
-
- if (isset($_GET['id'])) {
- $this->output_as_xml( $this->sql->select($this->request) );
- } else {
- $relation_id = $this->config->relation_id['name'];
- $this->output_as_xml( $this->sql->get_variants($this->config->relation_id['name'], $this->request));
- }
- }
- $this->end_run();
+ /*! if not isset $_GET[id] then it's top level
+ */
+ protected function set_relation() {
+ if (!isset($_GET[$this->parent_name])) $this->request->set_relation(false);
}
- protected function render_set($res){
- $output="";
- $index=0;
- $records = Array();
- while ($data=$this->sql->get_next($res)){
- if (isset($data[$this->config->id['name']])) {
- $has_kids = false;
- } else {
- $data[$this->config->id['name']] = $data['value'].$this->id_postfix;
- $data[$this->config->text[0]['name']] = $data['value'];
- $has_kids = true;
- }
- $data = new $this->names["item_class"]($data,$this->config,$index);
- $this->event->trigger("beforeRender",$data);
- if ($has_kids === false) {
- $data->set_kids(false);
- }
-
- if ($data->has_kids()===-1 && $this->dload)
- $data->set_kids(true);
- $output.=$data->to_xml_start();
- if (($data->has_kids()===-1 || ( $data->has_kids()==true && !$this->dload))&&($has_kids == true)){
- $sub_request = new DataRequestConfig($this->request);
- $sub_request->set_relation(str_replace($this->id_postfix, "", $data->get_id()));
- $output.=$this->render_set($this->sql->select($sub_request));
- }
- $output.=$data->to_xml_end();
- $index++;
- }
- return $output;
+ /*! if it's first level then distinct level
+ * else select by parent
+ */
+ protected function get_resource() {
+ $resource = null;
+ if (isset($_GET[$this->parent_name]))
+ $resource = $this->sql->select($this->request);
+ else
+ $resource = $this->sql->get_variants($this->config->relation_id['name'], $this->request);
+ return $resource;
}
+
+ /*! renders self as xml, starting part
+ */
public function xml_start(){
- if (isset($_GET['id'])) {
- return "<tree id='".$_GET['id'].$this->id_postfix."'>";
+ if (isset($_GET[$this->parent_name])) {
+ return "<tree id='".$_GET[$this->parent_name].$this->render->get_postfix()."'>";
} else {
return "<tree id='0'>";
}
}
-
- public function check_id($action) {
- if (isset($_GET['editing'])) {
- $id = $action->get_id();
- $pid = $action->get_value($this->config->relation_id['name']);
- $pid = str_replace($this->id_postfix, "", $pid);
- $action->set_value($this->config->relation_id['name'], $pid);
- if (strpos($id, $this->id_postfix) == false) {
- return $action;
- } else {
- $action->error();
- $action->set_response_text("This record can't be updated!");
- return $action;
- }
- } else {
- return $action;
- }
- }
}
?> \ No newline at end of file
diff --git a/codebase/treemultitable_connector.php b/codebase/treemultitable_connector.php
index f081689..c33f4a7 100644
--- a/codebase/treemultitable_connector.php
+++ b/codebase/treemultitable_connector.php
@@ -7,146 +7,45 @@ require_once("tree_connector.php");
class TreeMultitableConnector extends TreeConnector{
- private $level = 0;
- private $max_level = null;
+ protected $parent_name = 'id';
- public function __construct($res,$type=false,$item_type=false,$data_type=false){
- $data_type="TreeDataProcessor";
- parent::__construct($res,$type,$item_type,$data_type);
- $this->event->attach("beforeProcessing", Array($this, 'id_translate_before'));
- $this->event->attach("afterProcessing", Array($this, 'id_translate_after'));
+ public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
+ if (!$data_type) $data_type="TreeDataProcessor";
+ if (!$render_type) $render_type="MultitableTreeRenderStrategy";
+ parent::__construct($res,$type,$item_type,$data_type,$render_type);
}
-
public function render(){
- $this->parse_request();
$this->dload = true;
- if ((isset($_GET["editing"]))||(isset($_POST["ids"]))) {
- $this->editing=true;
- } else {
- $this->editing = false;
- }
-
- if ($this->editing){
- $dp = new $this->names["data_class"]($this,$this->config,$this->request);
- $dp->process($this->config,$this->request);
- } else {
- $wrap = new SortInterface($this->request);
- $this->event->trigger("beforeSort",$wrap);
- $wrap->store();
-
- $wrap = new FilterInterface($this->request);
- $this->event->trigger("beforeFilter",$wrap);
- $wrap->store();
-
- if (isset($_GET['id'])) {
- $this->output_as_xml( $this->sql->select($this->request) );
- } else {
- $this->request->set_relation(false);
- $this->output_as_xml( $this->sql->select($this->request) );
- }
- }
- $this->end_run();
+ return parent::render();
}
- protected function render_set($res){
- $output="";
- $index=0;
- $records = Array();
- while ($data=$this->sql->get_next($res)){
- $data[$this->config->id['name']] = $this->level.'#'.$data[$this->config->id['name']];
- $data = new $this->names["item_class"]($data,$this->config,$index);
- $this->event->trigger("beforeRender",$data);
- if (($this->max_level !== null)&&($this->level == $this->max_level)) {
- $data->set_kids(false);
- } else {
- if ($data->has_kids()===-1)
- $data->set_kids(true);
- }
- $output.=$data->to_xml_start();
- $output.=$data->to_xml_end();
- $index++;
- }
- return $output;
+ /*! sets relation for rendering */
+ protected function set_relation() {
+ if (!isset($_GET[$this->parent_name]))
+ $this->request->set_relation(false);
}
public function xml_start(){
- if (isset($_GET['id'])) {
- return "<tree id='".($this->level - 1).'#'.$_GET['id']."'>";
+ if (isset($_GET[$this->parent_name])) {
+ return "<tree id='".($this->render->level_id($_GET[$this->parent_name], $this->render->get_level() - 1))."'>";
} else {
return "<tree id='0'>";
}
}
-
- public function get_level() {
- if (!isset($_GET['id'])) {
- if (isset($_POST['ids'])) {
- $ids = explode(",",$_POST["ids"]);
- $id = $this->parseId($ids[0]);
- $this->level--;
- }
- $this->request->set_relation(false);
- } else {
- $id = $this->parseId($_GET['id']);
- $_GET['id'] = $id;
- }
- return $this->level;
- }
-
-
- public function parseId($id, $set_level = true) {
- $result = Array();
- preg_match('/^(.+)#/', $id, $result);
- if ($set_level === true) {
- $this->level = $result[1] + 1;
- }
- preg_match('/^(.+)#(.*)$/', $id, $result);
- if (isset($result[2])) {
- $id = $result[2];
- } else {
- $id = '';
- }
- return $id;
- }
-
-
/*! set maximum level of tree
@param max_level
maximum level
*/
public function setMaxLevel($max_level) {
- $this->max_level = $max_level;
+ $this->render->set_max_level($max_level);
}
-
- /*! remove level prefix from id, parent id and set new id before processing
- @param action
- DataAction object
- */
- public function id_translate_before($action) {
- $id = $action->get_id();
- $id = $this->parseId($id, false);
- $action->set_id($id);
- $action->set_value('tr_id', $id);
- $action->set_new_id($id);
- $pid = $action->get_value($this->config->relation_id['db_name']);
- $pid = $this->parseId($pid, false);
- $action->set_value($this->config->relation_id['db_name'], $pid);
- }
-
-
- /*! add level prefix in id and new id after processing
- @param action
- DataAction object
- */
- public function id_translate_after($action) {
- $id = $action->get_id();
- $action->set_id(($this->level).'#'.$id);
- $id = $action->get_new_id();
- $action->success(($this->level).'#'.$id);
+ public function get_level() {
+ return $this->render->get_level($this->parent_name);
}
-
+
}
?> \ No newline at end of file