summaryrefslogtreecommitdiffstats
path: root/codebase
diff options
context:
space:
mode:
authorStanislav-Wolski <stanislau.wolski@gmail.com>2012-05-23 19:44:42 +0300
committerStanislav-Wolski <stanislau.wolski@gmail.com>2012-05-23 19:44:42 +0300
commit6c5b0c64092ad095d55412b5765c14bd121b508c (patch)
tree9b2e598d9556f72e1eadc89f231074d7e7072085 /codebase
parent97ec6d0772ca2123f54fb0cf558e9fe8a9b72115 (diff)
parent5b2915c991c6fd26503accfc7218256917bff0d3 (diff)
downloadconnector-php-6c5b0c64092ad095d55412b5765c14bd121b508c.zip
connector-php-6c5b0c64092ad095d55412b5765c14bd121b508c.tar.gz
connector-php-6c5b0c64092ad095d55412b5765c14bd121b508c.tar.bz2
Merge branch 'frameworks'
Conflicts: codebase/base_connector.php codebase/data_connector.php codebase/grid_connector.php codebase/scheduler_connector.php
Diffstat (limited to 'codebase')
-rw-r--r--codebase/base_connector.php41
-rw-r--r--codebase/data_connector.php21
-rw-r--r--codebase/dataprocessor.php999
-rw-r--r--codebase/db_common.php23
-rw-r--r--codebase/db_phpcake.php80
-rw-r--r--codebase/db_phpci.php63
-rw-r--r--codebase/db_phpyii.php88
-rw-r--r--codebase/grid_connector.php19
-rw-r--r--codebase/scheduler_connector.php11
-rw-r--r--codebase/tools.php519
-rw-r--r--codebase/tree_connector.php458
11 files changed, 1318 insertions, 1004 deletions
diff --git a/codebase/base_connector.php b/codebase/base_connector.php
index c4cbb5d..2c924a9 100644
--- a/codebase/base_connector.php
+++ b/codebase/base_connector.php
@@ -151,6 +151,8 @@ class DataItem{
protected $config;//!< DataConfig instance
protected $index;//!< index of element
protected $skip;//!< flag , which set if element need to be skiped during rendering
+ protected $userdata;
+
/*! constructor
@param data
@@ -165,6 +167,15 @@ class DataItem{
$this->data=$data;
$this->index=$index;
$this->skip=false;
+ $this->userdata=false;
+ }
+
+ //set userdata for the item
+ function set_userdata($name, $value){
+ if ($this->userdata === false)
+ $this->userdata = array();
+
+ $this->userdata[$name]=$value;
}
/*! get named value
@@ -243,6 +254,12 @@ class DataItem{
$name=$this->config->data[$i]["name"];
$str.=" ".$name."='".$this->xmlentities($this->data[$name])."'";
}
+ //output custom data
+ if ($this->userdata !== false)
+ foreach ($this->userdata as $key => $value){
+ $str.=" ".$key."='".$this->xmlentities($value)."'";
+ }
+
return $str.">";
}
/*! return ending tag for XML string
@@ -266,6 +283,9 @@ class Connector {
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 )
+
+ 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
@@ -278,7 +298,7 @@ class Connector {
private $id_seed=0; //!< default value, used to generate auto-IDs
protected $live_update = false; // actions table name for autoupdating
- protected $options=array();//!< hash of OptionsConnector
+ protected $options = array();
/*! constructor
@@ -341,6 +361,14 @@ class Connector {
}
+ //model is a class, which will be used for all data operations
+ //we expect that it has next methods get, update, insert, delete
+ //if method was not defined - we will use default logic
+ public function useModel($model){
+ $this->model = $model;
+ }
+
+
/*! config connector based on table
@param table
@@ -442,7 +470,13 @@ class Connector {
$this->event->trigger("beforeFilter",$wrap);
$wrap->store();
- $this->output_as_xml($this->get_resource());
+
+ if ($this->model && method_exists($this->model, "get")){
+ $this->sql = new ArrayDBDataWrapper();
+ $result = new ArrayQueryWrapper(call_user_func(array($this->model, "get"), $this->request));
+ $this->output_as_xml($result);
+ } else
+ $this->output_as_xml($this->get_resource());
}
}
$this->end_run();
@@ -683,6 +717,7 @@ class Connector {
$this->options[$name]=$options;
}
+
public function insert($data) {
$action = new DataAction('inserted', false, $data);
$request = new DataRequestConfig();
@@ -775,4 +810,4 @@ class DistinctOptionsConnector extends OptionsConnector{
}
}
-?>
+?> \ No newline at end of file
diff --git a/codebase/data_connector.php b/codebase/data_connector.php
index 6db082d..a5419e0 100644
--- a/codebase/data_connector.php
+++ b/codebase/data_connector.php
@@ -71,6 +71,11 @@ class CommonDataItem extends DataItem{
$name=$this->config->text[$i]["name"];
$str.=" ".$name."='".$this->xmlentities($this->data[$name])."'";
}
+
+ if ($this->userdata !== false)
+ foreach ($this->userdata as $key => $value)
+ $str.=" ".$key."='".$this->xmlentities($value)."'";
+
return $str.">";
}
}
@@ -264,6 +269,11 @@ class JSONCommonDataItem extends DataItem{
$extra = $this->config->text[$i]["name"];
$data[$extra]=$this->data[$extra];
}
+
+ if ($this->userdata !== false)
+ foreach ($this->userdata as $key => $value)
+ $data["key"]=$value;
+
return json_encode($data);
}
}
@@ -322,6 +332,10 @@ class TreeCommonDataItem extends CommonDataItem{
$str.=" ".$name."='".$this->xmlentities($this->data[$name])."'";
}
+ if ($this->userdata !== false)
+ foreach ($this->userdata as $key => $value)
+ $str.=" ".$key."='".$this->xmlentities($value)."'";
+
if ($this->kids === true)
$str .=" dhx_kids='1'";
@@ -416,6 +430,10 @@ class JSONTreeCommonDataItem extends TreeCommonDataItem{
$data[$extra]=$this->data[$extra];
}
+ if ($this->userdata !== false)
+ foreach ($this->userdata as $key => $value)
+ $data["key"]=$value;
+
if ($this->kids === true)
$data["dhx_kids"] = 1;
@@ -428,5 +446,4 @@ class JSONTreeCommonDataItem extends TreeCommonDataItem{
}
-?>
-
+?> \ No newline at end of file
diff --git a/codebase/dataprocessor.php b/codebase/dataprocessor.php
index 8418d40..74852e2 100644
--- a/codebase/dataprocessor.php
+++ b/codebase/dataprocessor.php
@@ -1,496 +1,505 @@
-<?php
-/*
- @author dhtmlx.com
- @license GPL, see license.txt
-*/
-/*! Base DataProcessor handling
-**/
-
-require_once("xss_filter.php");
-
-class DataProcessor{
- protected $connector;//!< Connector instance
- protected $config;//!< DataConfig instance
- protected $request;//!< DataRequestConfig instance
-
- /*! constructor
-
- @param connector
- Connector object
- @param config
- DataConfig object
- @param request
- DataRequestConfig object
- */
- function __construct($connector,$config,$request){
- $this->connector= $connector;
- $this->config=$config;
- $this->request=$request;
- }
-
- /*! convert incoming data name to valid db name
- redirect to Connector->name_data by default
- @param data
- data name from incoming request
- @return
- related db_name
- */
- function name_data($data){
- return $data;
- }
- /*! retrieve data from incoming request and normalize it
-
- @param ids
- array of extected IDs
- @return
- hash of data
- */
- protected function get_post_values($ids){
- $data=array();
- for ($i=0; $i < sizeof($ids); $i++)
- $data[$ids[$i]]=array();
-
- foreach ($_POST as $key => $value) {
- $details=explode("_",$key,2);
- if (sizeof($details)==1) continue;
-
- $name=$this->name_data($details[1]);
- $data[$details[0]][$name]=ConnectorSecurity::filter($value);
- }
-
- return $data;
- }
- protected function get_ids(){
- if (!isset($_POST["ids"]))
- throw new Exception("Incorrect incoming data, ID of incoming records not recognized");
- return explode(",",$_POST["ids"]);
- }
-
- protected function get_operation($rid){
- if (!isset($_POST[$rid."_!nativeeditor_status"]))
- throw new Exception("Status of record [{$rid}] not found in incoming request");
- return $_POST[$rid."_!nativeeditor_status"];
- }
- /*! process incoming request ( save|update|delete )
- */
- function process(){
- LogMaster::log("DataProcessor object initialized",$_POST);
-
- $results=array();
-
- $ids=$this->get_ids();
- $rows_data=$this->get_post_values($ids);
- $failed=false;
-
- try{
- if ($this->connector->sql->is_global_transaction())
- $this->connector->sql->begin_transaction();
-
- for ($i=0; $i < sizeof($ids); $i++) {
- $rid = $ids[$i];
- LogMaster::log("Row data [{$rid}]",$rows_data[$rid]);
- $status = $this->get_operation($rid);
-
- $action=new DataAction($status,$rid,$rows_data[$rid]);
- $results[]=$action;
- $this->inner_process($action);
- }
-
- } catch(Exception $e){
- $failed=true;
- }
-
- if ($this->connector->sql->is_global_transaction()){
- if (!$failed)
- for ($i=0; $i < sizeof($results); $i++)
- if ($results[$i]->get_status()=="error" || $results[$i]->get_status()=="invalid"){
- $failed=true;
- break;
- }
- if ($failed){
- for ($i=0; $i < sizeof($results); $i++)
- $results[$i]->error();
- $this->connector->sql->rollback_transaction();
- }
- else
- $this->connector->sql->commit_transaction();
- }
-
- $this->output_as_xml($results);
- }
-
- /*! converts status string to the inner mode name
-
- @param status
- external status string
- @return
- inner mode name
- */
- protected function status_to_mode($status){
- switch($status){
- case "updated":
- return "update";
- break;
- case "inserted":
- return "insert";
- break;
- case "deleted":
- return "delete";
- break;
- default:
- return $status;
- break;
- }
- }
- /*! process data updated request received
-
- @param action
- DataAction object
- @return
- DataAction object with details of processing
- */
- protected function inner_process($action){
-
- if ($this->connector->sql->is_record_transaction())
- $this->connector->sql->begin_transaction();
-
- try{
-
- $mode = $this->status_to_mode($action->get_status());
- if (!$this->connector->access->check($mode)){
- LogMaster::log("Access control: {$operation} operation blocked");
- $action->error();
- } else {
- $check = $this->connector->event->trigger("beforeProcessing",$action);
- if (!$action->is_ready())
- $this->check_exts($action,$mode);
- $check = $this->connector->event->trigger("afterProcessing",$action);
- }
-
- } catch (Exception $e){
- $action->set_status("error");
- if ($action)
- $this->connector->event->trigger("onDBError", $action, $e);
- }
-
- if ($this->connector->sql->is_record_transaction()){
- if ($action->get_status()=="error" || $action->get_status()=="invalid")
- $this->connector->sql->rollback_transaction();
- else
- $this->connector->sql->commit_transaction();
- }
-
- return $action;
- }
- /*! check if some event intercepts processing, send data to DataWrapper in other case
-
- @param action
- DataAction object
- @param mode
- name of inner mode ( will be used to generate event names )
- */
- function check_exts($action,$mode){
- $old_config = new DataConfig($this->config);
-
- $this->connector->event->trigger("before".$mode,$action);
- if ($action->is_ready())
- LogMaster::log("Event code for ".$mode." processed");
- else {
- //check if custom sql defined
- $sql = $this->connector->sql->get_sql($mode,$action);
- if ($sql){
- $this->connector->sql->query($sql);
- }
- else{
- $action->sync_config($this->config);
- $method=array($this->connector->sql,$mode);
- if (!is_callable($method))
- throw new Exception("Unknown dataprocessing action: ".$mode);
- call_user_func($method,$action,$this->request);
- }
- }
- $this->connector->event->trigger("after".$mode,$action);
-
- $this->config = $old_config;
- }
-
- /*! output xml response for dataprocessor
-
- @param results
- array of DataAction objects
- */
- function output_as_xml($results){
- LogMaster::log("Edit operation finished",$results);
- ob_clean();
- header("Content-type:text/xml");
- echo "<?xml version='1.0' ?>";
- echo "<data>";
- for ($i=0; $i < sizeof($results); $i++)
- echo $results[$i]->to_xml();
- echo "</data>";
- }
-
-}
-
-/*! contain all info related to action and controls customizaton
-**/
-class DataAction{
- private $status; //!< cuurent status of record
- private $id;//!< id of record
- private $data;//!< data hash of record
- private $userdata;//!< hash of extra data , attached to record
- private $nid;//!< new id value , after operation executed
- private $output;//!< custom output to client side code
- private $attrs;//!< hash of custtom attributes
- private $ready;//!< flag of operation's execution
- private $addf;//!< array of added fields
- private $delf;//!< array of deleted fields
-
-
- /*! constructor
-
- @param status
- current operation status
- @param id
- record id
- @param data
- hash of data
- */
- function __construct($status,$id,$data){
- $this->status=$status;
- $this->id=$id;
- $this->data=$data;
- $this->nid=$id;
-
- $this->output="";
- $this->attrs=array();
- $this->ready=false;
-
- $this->addf=array();
- $this->delf=array();
- }
-
-
- /*! add custom field and value to DB operation
-
- @param name
- name of field which will be added to DB operation
- @param value
- value which will be used for related field in DB operation
- */
- function add_field($name,$value){
- LogMaster::log("adding field: ".$name.", with value: ".$value);
- $this->data[$name]=$value;
- $this->addf[]=$name;
- }
- /*! remove field from DB operation
-
- @param name
- name of field which will be removed from DB operation
- */
- function remove_field($name){
- LogMaster::log("removing field: ".$name);
- $this->delf[]=$name;
- }
-
- /*! sync field configuration with external object
-
- @param slave
- SQLMaster object
- @todo
- check , if all fields removed then cancel action
- */
- function sync_config($slave){
- foreach ($this->addf as $k => $v)
- $slave->add_field($v);
- foreach ($this->delf as $k => $v)
- $slave->remove_field($v);
- }
- /*! get value of some record's propery
-
- @param name
- name of record's property ( name of db field or alias )
- @return
- value of related property
- */
- function get_value($name){
- if (!array_key_exists($name,$this->data)){
- LogMaster::log("Incorrect field name used: ".$name);
- LogMaster::log("data",$this->data);
- return "";
- }
- return $this->data[$name];
- }
- /*! set value of some record's propery
-
- @param name
- name of record's property ( name of db field or alias )
- @param value
- value of related property
- */
- function set_value($name,$value){
- LogMaster::log("change value of: ".$name." as: ".$value);
- $this->data[$name]=$value;
- }
- /*! get hash of data properties
-
- @return
- hash of data properties
- */
- function get_data(){
- return $this->data;
- }
- /*! get some extra info attached to record
- deprecated, exists just for backward compatibility, you can use set_value instead of it
- @param name
- name of userdata property
- @return
- value of related userdata property
- */
- function get_userdata_value($name){
- return $this->get_value($name);
- }
- /*! set some extra info attached to record
- deprecated, exists just for backward compatibility, you can use get_value instead of it
- @param name
- name of userdata property
- @param value
- value of userdata property
- */
- function set_userdata_value($name,$value){
- return $this->set_value($name,$value);
- }
- /*! get current status of record
-
- @return
- string with status value
- */
- function get_status(){
- return $this->status;
- }
- /*! assign new status to the record
-
- @param status
- new status value
- */
- function set_status($status){
- $this->status=$status;
- }
- /*! set id
- @param id
- id value
- */
- function set_id($id) {
- $this->id = $id;
- LogMaster::log("Change id: ".$id);
- }
- /*! set id
- @param id
- id value
- */
- function set_new_id($id) {
- $this->nid = $id;
- LogMaster::log("Change new id: ".$id);
- }
- /*! get id of current record
-
- @return
- id of record
- */
- function get_id(){
- return $this->id;
- }
- /*! sets custom response text
-
- can be accessed through defineAction on client side. Text wrapped in CDATA, so no extra escaping necessary
- @param text
- custom response text
- */
- function set_response_text($text){
- $this->set_response_xml("<![CDATA[".$text."]]>");
- }
- /*! sets custom response xml
-
- can be accessed through defineAction on client side
- @param text
- string with XML data
- */
- function set_response_xml($text){
- $this->output=$text;
- }
- /*! sets custom response attributes
-
- can be accessed through defineAction on client side
- @param name
- name of custom attribute
- @param value
- value of custom attribute
- */
- function set_response_attribute($name,$value){
- $this->attrs[$name]=$value;
- }
- /*! check if action finished
-
- @return
- true if action finished, false otherwise
- */
- function is_ready(){
- return $this->ready;
- }
- /*! return new id value
-
- equal to original ID normally, after insert operation - value assigned for new DB record
- @return
- new id value
- */
- function get_new_id(){
- return $this->nid;
- }
-
- /*! set result of operation as error
- */
- function error(){
- $this->status="error";
- $this->ready=true;
- }
- /*! set result of operation as invalid
- */
- function invalid(){
- $this->status="invalid";
- $this->ready=true;
- }
- /*! confirm successful opeation execution
- @param id
- new id value, optional
- */
- function success($id=false){
- if ($id!==false)
- $this->nid = $id;
- $this->ready=true;
- }
- /*! convert DataAction to xml format compatible with client side dataProcessor
- @return
- DataAction operation report as XML string
- */
- function to_xml(){
- $str="<action type='{$this->status}' sid='{$this->id}' tid='{$this->nid}' ";
- foreach ($this->attrs as $k => $v) {
- $str.=$k."='".$v."' ";
- }
- $str.=">{$this->output}</action>";
- return $str;
- }
- /*! convert self to string ( for logs )
-
- @return
- DataAction operation report as plain string
- */
- function __toString(){
- return "action:{$this->status}; sid:{$this->id}; tid:{$this->nid};";
- }
-
-
-}
-
-
+<?php
+/*
+ @author dhtmlx.com
+ @license GPL, see license.txt
+*/
+/*! Base DataProcessor handling
+**/
+
+require_once("xss_filter.php");
+
+class DataProcessor{
+ protected $connector;//!< Connector instance
+ protected $config;//!< DataConfig instance
+ protected $request;//!< DataRequestConfig instance
+ static public $action_param ="!nativeeditor_status";
+
+ /*! constructor
+
+ @param connector
+ Connector object
+ @param config
+ DataConfig object
+ @param request
+ DataRequestConfig object
+ */
+ function __construct($connector,$config,$request){
+ $this->connector= $connector;
+ $this->config=$config;
+ $this->request=$request;
+ }
+
+ /*! convert incoming data name to valid db name
+ redirect to Connector->name_data by default
+ @param data
+ data name from incoming request
+ @return
+ related db_name
+ */
+ function name_data($data){
+ return $data;
+ }
+ /*! retrieve data from incoming request and normalize it
+
+ @param ids
+ array of extected IDs
+ @return
+ hash of data
+ */
+ protected function get_post_values($ids){
+ $data=array();
+ for ($i=0; $i < sizeof($ids); $i++)
+ $data[$ids[$i]]=array();
+
+ foreach ($_POST as $key => $value) {
+ $details=explode("_",$key,2);
+ if (sizeof($details)==1) continue;
+
+ $name=$this->name_data($details[1]);
+ $data[$details[0]][$name]=ConnectorSecurity::filter($value);
+ }
+
+ return $data;
+ }
+ protected function get_ids(){
+ if (!isset($_POST["ids"]))
+ throw new Exception("Incorrect incoming data, ID of incoming records not recognized");
+ return explode(",",$_POST["ids"]);
+ }
+
+ protected function get_operation($rid){
+ if (!isset($_POST[$rid."_".DataProcessor::$action_param]))
+ throw new Exception("Status of record [{$rid}] not found in incoming request");
+ return $_POST[$rid."_".DataProcessor::$action_param];
+ }
+ /*! process incoming request ( save|update|delete )
+ */
+ function process(){
+ LogMaster::log("DataProcessor object initialized",$_POST);
+
+ $results=array();
+
+ $ids=$this->get_ids();
+ $rows_data=$this->get_post_values($ids);
+ $failed=false;
+
+ try{
+ if ($this->connector->sql->is_global_transaction())
+ $this->connector->sql->begin_transaction();
+
+ for ($i=0; $i < sizeof($ids); $i++) {
+ $rid = $ids[$i];
+ LogMaster::log("Row data [{$rid}]",$rows_data[$rid]);
+ $status = $this->get_operation($rid);
+
+ $action=new DataAction($status,$rid,$rows_data[$rid]);
+ $results[]=$action;
+ $this->inner_process($action);
+ }
+
+ } catch(Exception $e){
+ LogMaster::log($e);
+ $failed=true;
+ }
+
+ if ($this->connector->sql->is_global_transaction()){
+ if (!$failed)
+ for ($i=0; $i < sizeof($results); $i++)
+ if ($results[$i]->get_status()=="error" || $results[$i]->get_status()=="invalid"){
+ $failed=true;
+ break;
+ }
+ if ($failed){
+ for ($i=0; $i < sizeof($results); $i++)
+ $results[$i]->error();
+ $this->connector->sql->rollback_transaction();
+ }
+ else
+ $this->connector->sql->commit_transaction();
+ }
+
+ $this->output_as_xml($results);
+ }
+
+ /*! converts status string to the inner mode name
+
+ @param status
+ external status string
+ @return
+ inner mode name
+ */
+ protected function status_to_mode($status){
+ switch($status){
+ case "updated":
+ return "update";
+ break;
+ case "inserted":
+ return "insert";
+ break;
+ case "deleted":
+ return "delete";
+ break;
+ default:
+ return $status;
+ break;
+ }
+ }
+ /*! process data updated request received
+
+ @param action
+ DataAction object
+ @return
+ DataAction object with details of processing
+ */
+ protected function inner_process($action){
+
+ if ($this->connector->sql->is_record_transaction())
+ $this->connector->sql->begin_transaction();
+
+ try{
+
+ $mode = $this->status_to_mode($action->get_status());
+ if (!$this->connector->access->check($mode)){
+ LogMaster::log("Access control: {$operation} operation blocked");
+ $action->error();
+ } else {
+ $check = $this->connector->event->trigger("beforeProcessing",$action);
+ if (!$action->is_ready())
+ $this->check_exts($action,$mode);
+ $check = $this->connector->event->trigger("afterProcessing",$action);
+ }
+
+ } catch (Exception $e){
+ LogMaster::log($e);
+ $action->set_status("error");
+ if ($action)
+ $this->connector->event->trigger("onDBError", $action, $e);
+ }
+
+ if ($this->connector->sql->is_record_transaction()){
+ if ($action->get_status()=="error" || $action->get_status()=="invalid")
+ $this->connector->sql->rollback_transaction();
+ else
+ $this->connector->sql->commit_transaction();
+ }
+
+ return $action;
+ }
+ /*! check if some event intercepts processing, send data to DataWrapper in other case
+
+ @param action
+ DataAction object
+ @param mode
+ name of inner mode ( will be used to generate event names )
+ */
+ function check_exts($action,$mode){
+ $old_config = new DataConfig($this->config);
+
+ $this->connector->event->trigger("before".$mode,$action);
+ if ($action->is_ready())
+ LogMaster::log("Event code for ".$mode." processed");
+ else {
+ //check if custom sql defined
+ $sql = $this->connector->sql->get_sql($mode,$action);
+ if ($sql){
+ $this->connector->sql->query($sql);
+ }
+ else{
+ $action->sync_config($this->config);
+ if ($this->connector->model && method_exists($this->connector->model, $mode)){
+ call_user_func(array($this->connector->model, $mode), $action);
+ LogMaster::log("Model object process action: ".$mode);
+ }
+ if (!$action->is_ready()){
+ $method=array($this->connector->sql,$mode);
+ if (!is_callable($method))
+ throw new Exception("Unknown dataprocessing action: ".$mode);
+ call_user_func($method,$action,$this->request);
+ }
+ }
+ }
+ $this->connector->event->trigger("after".$mode,$action);
+
+ $this->config = $old_config;
+ }
+
+ /*! output xml response for dataprocessor
+
+ @param results
+ array of DataAction objects
+ */
+ function output_as_xml($results){
+ LogMaster::log("Edit operation finished",$results);
+ ob_clean();
+ header("Content-type:text/xml");
+ echo "<?xml version='1.0' ?>";
+ echo "<data>";
+ for ($i=0; $i < sizeof($results); $i++)
+ echo $results[$i]->to_xml();
+ echo "</data>";
+ }
+
+}
+
+/*! contain all info related to action and controls customizaton
+**/
+class DataAction{
+ private $status; //!< cuurent status of record
+ private $id;//!< id of record
+ private $data;//!< data hash of record
+ private $userdata;//!< hash of extra data , attached to record
+ private $nid;//!< new id value , after operation executed
+ private $output;//!< custom output to client side code
+ private $attrs;//!< hash of custtom attributes
+ private $ready;//!< flag of operation's execution
+ private $addf;//!< array of added fields
+ private $delf;//!< array of deleted fields
+
+
+ /*! constructor
+
+ @param status
+ current operation status
+ @param id
+ record id
+ @param data
+ hash of data
+ */
+ function __construct($status,$id,$data){
+ $this->status=$status;
+ $this->id=$id;
+ $this->data=$data;
+ $this->nid=$id;
+
+ $this->output="";
+ $this->attrs=array();
+ $this->ready=false;
+
+ $this->addf=array();
+ $this->delf=array();
+ }
+
+
+ /*! add custom field and value to DB operation
+
+ @param name
+ name of field which will be added to DB operation
+ @param value
+ value which will be used for related field in DB operation
+ */
+ function add_field($name,$value){
+ LogMaster::log("adding field: ".$name.", with value: ".$value);
+ $this->data[$name]=$value;
+ $this->addf[]=$name;
+ }
+ /*! remove field from DB operation
+
+ @param name
+ name of field which will be removed from DB operation
+ */
+ function remove_field($name){
+ LogMaster::log("removing field: ".$name);
+ $this->delf[]=$name;
+ }
+
+ /*! sync field configuration with external object
+
+ @param slave
+ SQLMaster object
+ @todo
+ check , if all fields removed then cancel action
+ */
+ function sync_config($slave){
+ foreach ($this->addf as $k => $v)
+ $slave->add_field($v);
+ foreach ($this->delf as $k => $v)
+ $slave->remove_field($v);
+ }
+ /*! get value of some record's propery
+
+ @param name
+ name of record's property ( name of db field or alias )
+ @return
+ value of related property
+ */
+ function get_value($name){
+ if (!array_key_exists($name,$this->data)){
+ LogMaster::log("Incorrect field name used: ".$name);
+ LogMaster::log("data",$this->data);
+ return "";
+ }
+ return $this->data[$name];
+ }
+ /*! set value of some record's propery
+
+ @param name
+ name of record's property ( name of db field or alias )
+ @param value
+ value of related property
+ */
+ function set_value($name,$value){
+ LogMaster::log("change value of: ".$name." as: ".$value);
+ $this->data[$name]=$value;
+ }
+ /*! get hash of data properties
+
+ @return
+ hash of data properties
+ */
+ function get_data(){
+ return $this->data;
+ }
+ /*! get some extra info attached to record
+ deprecated, exists just for backward compatibility, you can use set_value instead of it
+ @param name
+ name of userdata property
+ @return
+ value of related userdata property
+ */
+ function get_userdata_value($name){
+ return $this->get_value($name);
+ }
+ /*! set some extra info attached to record
+ deprecated, exists just for backward compatibility, you can use get_value instead of it
+ @param name
+ name of userdata property
+ @param value
+ value of userdata property
+ */
+ function set_userdata_value($name,$value){
+ return $this->set_value($name,$value);
+ }
+ /*! get current status of record
+
+ @return
+ string with status value
+ */
+ function get_status(){
+ return $this->status;
+ }
+ /*! assign new status to the record
+
+ @param status
+ new status value
+ */
+ function set_status($status){
+ $this->status=$status;
+ }
+ /*! set id
+ @param id
+ id value
+ */
+ function set_id($id) {
+ $this->id = $id;
+ LogMaster::log("Change id: ".$id);
+ }
+ /*! set id
+ @param id
+ id value
+ */
+ function set_new_id($id) {
+ $this->nid = $id;
+ LogMaster::log("Change new id: ".$id);
+ }
+ /*! get id of current record
+
+ @return
+ id of record
+ */
+ function get_id(){
+ return $this->id;
+ }
+ /*! sets custom response text
+
+ can be accessed through defineAction on client side. Text wrapped in CDATA, so no extra escaping necessary
+ @param text
+ custom response text
+ */
+ function set_response_text($text){
+ $this->set_response_xml("<![CDATA[".$text."]]>");
+ }
+ /*! sets custom response xml
+
+ can be accessed through defineAction on client side
+ @param text
+ string with XML data
+ */
+ function set_response_xml($text){
+ $this->output=$text;
+ }
+ /*! sets custom response attributes
+
+ can be accessed through defineAction on client side
+ @param name
+ name of custom attribute
+ @param value
+ value of custom attribute
+ */
+ function set_response_attribute($name,$value){
+ $this->attrs[$name]=$value;
+ }
+ /*! check if action finished
+
+ @return
+ true if action finished, false otherwise
+ */
+ function is_ready(){
+ return $this->ready;
+ }
+ /*! return new id value
+
+ equal to original ID normally, after insert operation - value assigned for new DB record
+ @return
+ new id value
+ */
+ function get_new_id(){
+ return $this->nid;
+ }
+
+ /*! set result of operation as error
+ */
+ function error(){
+ $this->status="error";
+ $this->ready=true;
+ }
+ /*! set result of operation as invalid
+ */
+ function invalid(){
+ $this->status="invalid";
+ $this->ready=true;
+ }
+ /*! confirm successful opeation execution
+ @param id
+ new id value, optional
+ */
+ function success($id=false){
+ if ($id!==false)
+ $this->nid = $id;
+ $this->ready=true;
+ }
+ /*! convert DataAction to xml format compatible with client side dataProcessor
+ @return
+ DataAction operation report as XML string
+ */
+ function to_xml(){
+ $str="<action type='{$this->status}' sid='{$this->id}' tid='{$this->nid}' ";
+ foreach ($this->attrs as $k => $v) {
+ $str.=$k."='".$v."' ";
+ }
+ $str.=">{$this->output}</action>";
+ return $str;
+ }
+ /*! convert self to string ( for logs )
+
+ @return
+ DataAction operation report as plain string
+ */
+ function __toString(){
+ return "action:{$this->status}; sid:{$this->id}; tid:{$this->nid};";
+ }
+
+
+}
+
+
?> \ No newline at end of file
diff --git a/codebase/db_common.php b/codebase/db_common.php
index 996feda..7d738ee 100644
--- a/codebase/db_common.php
+++ b/codebase/db_common.php
@@ -924,6 +924,29 @@ abstract class DBDataWrapper extends DataWrapper{
}
}
+
+class ArrayDBDataWrapper extends DBDataWrapper{
+ public function get_next($res){
+ if ($res->index < sizeof($res->data))
+ return $res->data[$res->index++];
+ }
+ public function query($sql){
+ throw new Exception("Not implemented");
+ }
+ public function escape($value){
+ throw new Exception("Not implemented");
+ }
+ public function get_new_id(){
+ throw new Exception("Not implemented");
+ }
+}
+
+class ArrayQueryWrapper{
+ public function __construct($data){
+ $this->data = $data;
+ $this->index = 0;
+ }
+}
/*! Implementation of DataWrapper for MySQL
**/
class MySQLDBDataWrapper extends DBDataWrapper{
diff --git a/codebase/db_phpcake.php b/codebase/db_phpcake.php
new file mode 100644
index 0000000..980c9c3
--- /dev/null
+++ b/codebase/db_phpcake.php
@@ -0,0 +1,80 @@
+<?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 PHPCakeDBDataWrapper extends ArrayDBDataWrapper{
+ public function select($sql){
+ $res = $this->connection->find("all");
+ if (sizeof($res)){
+ $name = get_class($this->connection);
+ $temp = array();
+ 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/db_phpci.php b/codebase/db_phpci.php
new file mode 100644
index 0000000..3f4221b
--- /dev/null
+++ b/codebase/db_phpci.php
@@ -0,0 +1,63 @@
+<?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 PHPCIDBDataWrapper 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");
+ }
+
+ return new PHPCIResultSet($res);
+ }
+
+ public function get_next($res){
+ $data = $res->next();
+ return $data;
+ }
+
+ protected 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/db_phpyii.php b/codebase/db_phpyii.php
new file mode 100644
index 0000000..41066ee
--- /dev/null
+++ b/codebase/db_phpyii.php
@@ -0,0 +1,88 @@
+<?php
+/*
+ @author dhtmlx.com
+ @license GPL, see license.txt
+*/
+
+require_once("db_common.php");
+
+class PHPYiiDBDataWrapper extends ArrayDBDataWrapper{
+ public function select($sql){
+ $res = $this->connection->findAll();
+ if (sizeof($res)){
+ $name = get_class($this->connection);
+ $temp = array();
+ 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/grid_connector.php b/codebase/grid_connector.php
index a39e30c..6f41467 100644
--- a/codebase/grid_connector.php
+++ b/codebase/grid_connector.php
@@ -14,14 +14,12 @@ require_once("grid_config.php");
class GridDataItem extends DataItem{
protected $row_attrs;//!< hash of row attributes
protected $cell_attrs;//!< hash of cell attributes
- protected $userdata;
function __construct($data,$name,$index=0){
parent::__construct($data,$name,$index);
$this->row_attrs=array();
$this->cell_attrs=array();
- $this->userdata=array();
}
/*! set color of row
@@ -73,17 +71,6 @@ class GridDataItem extends DataItem{
$this->cell_attrs[$name][$attr]=$value;
}
- /*! set userdata section for the item
-
- @param name
- name of userdata
- @param value
- value of userdata
- */
- function set_userdata($name, $value){
- $this->userdata[$name]=$value;
- }
-
/*! set custom row attribute
@param attr
@@ -115,8 +102,9 @@ class GridDataItem extends DataItem{
$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>";
+ if ($this->userdata !== false)
+ foreach ($this->userdata as $key => $value)
+ $str.="<userdata name='".$key."'><![CDATA[".$value."]]></userdata>";
return $str;
}
@@ -272,5 +260,4 @@ class GridDataProcessor extends DataProcessor{
return $data;
}
}
-
?> \ No newline at end of file
diff --git a/codebase/scheduler_connector.php b/codebase/scheduler_connector.php
index 123d03b..7032fd8 100644
--- a/codebase/scheduler_connector.php
+++ b/codebase/scheduler_connector.php
@@ -22,6 +22,11 @@ class SchedulerDataItem extends DataItem{
$extra = $this->config->text[$i]["name"];
$str.="<".$extra."><![CDATA[".$this->data[$extra]."]]></".$extra.">";
}
+
+ if ($this->userdata !== false)
+ foreach ($this->userdata as $key => $value)
+ $str.="<".$key."><![CDATA[".$value."]]></".$key.">";
+
return $str."</event>";
}
}
@@ -119,6 +124,11 @@ class JSONSchedulerDataItem extends SchedulerDataItem{
$extra = $this->config->text[$i]["name"];
$obj[$extra]=$this->data[$extra];
}
+
+ if ($this->userdata !== false)
+ foreach ($this->userdata as $key => $value)
+ $obj[$key]=$value;
+
return $obj;
}
}
@@ -212,5 +222,4 @@ class JSONSchedulerConnector extends SchedulerConnector {
$out->output("", true, $this->encoding);
}
}
-
?> \ No newline at end of file
diff --git a/codebase/tools.php b/codebase/tools.php
index cefe051..2a0ec01 100644
--- a/codebase/tools.php
+++ b/codebase/tools.php
@@ -1,254 +1,267 @@
-<?php
-/*
- @author dhtmlx.com
- @license GPL, see license.txt
-*/
-
-/*! Class which allows to assign|fire events.
-*/
-class EventMaster{
- private $events;//!< hash of event handlers
- private static $eventsStatic=array();
-
- /*! constructor
- */
- function __construct(){
- $this->events=array();
- }
- /*! Method check if event with such name already exists.
- @param name
- name of event, case non-sensitive
- @return
- true if event with such name registered, false otherwise
- */
- public function exist($name){
- $name=strtolower($name);
- return (isset($this->events[$name]) && sizeof($this->events[$name]));
- }
- /*! Attach custom code to event.
-
- Only on event handler can be attached in the same time. If new event handler attached - old will be detached.
-
- @param name
- name of event, case non-sensitive
- @param method
- function which will be attached. You can use array(class, method) if you want to attach the method of the class.
- */
- public function attach($name,$method){
- $name=strtolower($name);
- if (!array_key_exists($name,$this->events))
- $this->events[$name]=array();
- $this->events[$name][]=$method;
- }
-
- public static function attach_static($name, $method){
- $name=strtolower($name);
- if (!array_key_exists($name,EventMaster::$eventsStatic))
- EventMaster::$eventsStatic[$name]=array();
- EventMaster::$eventsStatic[$name][]=$method;
- }
-
- public static function trigger_static($name, $method){
- $arg_list = func_get_args();
- $name=strtolower(array_shift($arg_list));
-
- if (isset(EventMaster::$eventsStatic[$name]))
- foreach(EventMaster::$eventsStatic[$name] as $method){
- if (is_array($method) && !method_exists($method[0],$method[1]))
- throw new Exception("Incorrect method assigned to event: ".$method[0].":".$method[1]);
- if (!is_array($method) && !function_exists($method))
- throw new Exception("Incorrect function assigned to event: ".$method);
- call_user_func_array($method, $arg_list);
- }
- return true;
- }
-
- /*! Detach code from event
- @param name
- name of event, case non-sensitive
- */
- public function detach($name){
- $name=strtolower($name);
- unset($this->events[$name]);
- }
- /*! Trigger event.
- @param name
- name of event, case non-sensitive
- @param data
- value which will be provided as argument for event function,
- you can provide multiple data arguments, method accepts variable number of parameters
- @return
- true if event handler was not assigned , result of event hangler otherwise
- */
- public function trigger($name,$data){
- $arg_list = func_get_args();
- $name=strtolower(array_shift($arg_list));
-
- if (isset($this->events[$name]))
- foreach($this->events[$name] as $method){
- if (is_array($method) && !method_exists($method[0],$method[1]))
- throw new Exception("Incorrect method assigned to event: ".$method[0].":".$method[1]);
- if (!is_array($method) && !function_exists($method))
- throw new Exception("Incorrect function assigned to event: ".$method);
- call_user_func_array($method, $arg_list);
- }
- return true;
- }
-}
-
-/*! Class which handles access rules.
-**/
-class AccessMaster{
- private $rules,$local;
- /*! constructor
-
- Set next access right to "allowed" by default : read, insert, update, delete
- Basically - all common data operations allowed by default
- */
- function __construct(){
- $this->rules=array("read" => true, "insert" => true, "update" => true, "delete" => true);
- $this->local=true;
- }
- /*! change access rule to "allow"
- @param name
- name of access right
- */
- public function allow($name){
- $this->rules[$name]=true;
- }
- /*! change access rule to "deny"
-
- @param name
- name of access right
- */
- public function deny($name){
- $this->rules[$name]=false;
- }
-
- /*! change all access rules to "deny"
- */
- public function deny_all(){
- $this->rules=array();
- }
-
- /*! check access rule
-
- @param name
- name of access right
- @return
- true if access rule allowed, false otherwise
- */
- public function check($name){
- if ($this->local){
- /*!
- todo
- add referrer check, to prevent access from remote points
- */
- }
- if (!isset($this->rules[$name]) || !$this->rules[$name]){
- return false;
- }
- return true;
- }
-}
-
-/*! Controls error and debug logging.
- Class designed to be used as static object.
-**/
-class LogMaster{
- private static $_log=false;//!< logging mode flag
- private static $_output=false;//!< output error infor to client flag
- private static $session="";//!< all messages generated for current request
-
- /*! convert array to string representation ( it is a bit more readable than var_dump )
-
- @param data
- data object
- @param pref
- prefix string, used for formating, optional
- @return
- string with array description
- */
- private static function log_details($data,$pref=""){
- if (is_array($data)){
- $str=array("");
- foreach($data as $k=>$v)
- array_push($str,$pref.$k." => ".LogMaster::log_details($v,$pref."\t"));
- return implode("\n",$str);
- }
- return $data;
- }
- /*! put record in log
-
- @param str
- string with log info, optional
- @param data
- data object, which will be added to log, optional
- */
- public static function log($str="",$data=""){
- if (LogMaster::$_log){
- $message = $str.LogMaster::log_details($data)."\n\n";
- LogMaster::$session.=$message;
- error_log($message,3,LogMaster::$_log);
- }
- }
-
- /*! get logs for current request
- @return
- string, which contains all log messages generated for current request
- */
- public static function get_session_log(){
- return LogMaster::$session;
- }
-
- /*! error handler, put normal php errors in log file
-
- @param errn
- error number
- @param errstr
- error description
- @param file
- error file
- @param line
- error line
- @param context
- error cntext
- */
- public static function error_log($errn,$errstr,$file,$line,$context){
- LogMaster::log($errstr." at ".$file." line ".$line);
- }
-
- /*! exception handler, used as default reaction on any error - show execution log and stop processing
-
- @param exception
- instance of Exception
- */
- public static function exception_log($exception){
- LogMaster::log("!!!Uncaught Exception\nCode: " . $exception->getCode() . "\nMessage: " . $exception->getMessage());
- if (LogMaster::$_output){
- echo "<pre><xmp>\n";
- echo LogMaster::get_session_log();
- echo "\n</xmp></pre>";
- }
- die();
- }
-
- /*! enable logging
-
- @param name
- path to the log file, if boolean false provided as value - logging will be disabled
- @param output
- flag of client side output, if enabled - session log will be sent to client side in case of an error.
- */
- public static function enable_log($name,$output=false){
- LogMaster::$_log=$name;
- LogMaster::$_output=$output;
- if ($name){
- set_error_handler(array("LogMaster","error_log"),E_ALL);
- set_exception_handler(array("LogMaster","exception_log"));
- LogMaster::log("\n\n====================================\nLog started, ".date("d/m/Y h:m:s")."\n====================================");
- }
- }
-}
-
+<?php
+/*
+ @author dhtmlx.com
+ @license GPL, see license.txt
+*/
+
+/*! Class which allows to assign|fire events.
+*/
+class EventMaster{
+ private $events;//!< hash of event handlers
+ private $master;
+ private static $eventsStatic=array();
+
+ /*! constructor
+ */
+ function __construct(){
+ $this->events=array();
+ $this->master = false;
+ }
+ /*! Method check if event with such name already exists.
+ @param name
+ name of event, case non-sensitive
+ @return
+ true if event with such name registered, false otherwise
+ */
+ public function exist($name){
+ $name=strtolower($name);
+ return (isset($this->events[$name]) && sizeof($this->events[$name]));
+ }
+ /*! Attach custom code to event.
+
+ Only on event handler can be attached in the same time. If new event handler attached - old will be detached.
+
+ @param name
+ name of event, case non-sensitive
+ @param method
+ function which will be attached. You can use array(class, method) if you want to attach the method of the class.
+ */
+ public function attach($name,$method=false){
+ //use class for event handling
+ if ($method === false){
+ $this->master = $name;
+ return;
+ }
+ //use separate functions
+ $name=strtolower($name);
+ if (!array_key_exists($name,$this->events))
+ $this->events[$name]=array();
+ $this->events[$name][]=$method;
+ }
+
+ public static function attach_static($name, $method){
+ $name=strtolower($name);
+ if (!array_key_exists($name,EventMaster::$eventsStatic))
+ EventMaster::$eventsStatic[$name]=array();
+ EventMaster::$eventsStatic[$name][]=$method;
+ }
+
+ public static function trigger_static($name, $method){
+ $arg_list = func_get_args();
+ $name=strtolower(array_shift($arg_list));
+
+ if (isset(EventMaster::$eventsStatic[$name]))
+ foreach(EventMaster::$eventsStatic[$name] as $method){
+ if (is_array($method) && !method_exists($method[0],$method[1]))
+ throw new Exception("Incorrect method assigned to event: ".$method[0].":".$method[1]);
+ if (!is_array($method) && !function_exists($method))
+ throw new Exception("Incorrect function assigned to event: ".$method);
+ call_user_func_array($method, $arg_list);
+ }
+ return true;
+ }
+
+ /*! Detach code from event
+ @param name
+ name of event, case non-sensitive
+ */
+ public function detach($name){
+ $name=strtolower($name);
+ unset($this->events[$name]);
+ }
+ /*! Trigger event.
+ @param name
+ name of event, case non-sensitive
+ @param data
+ value which will be provided as argument for event function,
+ you can provide multiple data arguments, method accepts variable number of parameters
+ @return
+ true if event handler was not assigned , result of event hangler otherwise
+ */
+ public function trigger($name,$data){
+ $arg_list = func_get_args();
+ $name=strtolower(array_shift($arg_list));
+
+ if (isset($this->events[$name]))
+ foreach($this->events[$name] as $method){
+ if (is_array($method) && !method_exists($method[0],$method[1]))
+ throw new Exception("Incorrect method assigned to event: ".$method[0].":".$method[1]);
+ if (!is_array($method) && !function_exists($method))
+ throw new Exception("Incorrect function assigned to event: ".$method);
+ call_user_func_array($method, $arg_list);
+ }
+
+ if ($this->master !== false)
+ if (method_exists($this->master, $name))
+ call_user_func_array(array($this->master, $name), $arg_list);
+
+ return true;
+ }
+}
+
+/*! Class which handles access rules.
+**/
+class AccessMaster{
+ private $rules,$local;
+ /*! constructor
+
+ Set next access right to "allowed" by default : read, insert, update, delete
+ Basically - all common data operations allowed by default
+ */
+ function __construct(){
+ $this->rules=array("read" => true, "insert" => true, "update" => true, "delete" => true);
+ $this->local=true;
+ }
+ /*! change access rule to "allow"
+ @param name
+ name of access right
+ */
+ public function allow($name){
+ $this->rules[$name]=true;
+ }
+ /*! change access rule to "deny"
+
+ @param name
+ name of access right
+ */
+ public function deny($name){
+ $this->rules[$name]=false;
+ }
+
+ /*! change all access rules to "deny"
+ */
+ public function deny_all(){
+ $this->rules=array();
+ }
+
+ /*! check access rule
+
+ @param name
+ name of access right
+ @return
+ true if access rule allowed, false otherwise
+ */
+ public function check($name){
+ if ($this->local){
+ /*!
+ todo
+ add referrer check, to prevent access from remote points
+ */
+ }
+ if (!isset($this->rules[$name]) || !$this->rules[$name]){
+ return false;
+ }
+ return true;
+ }
+}
+
+/*! Controls error and debug logging.
+ Class designed to be used as static object.
+**/
+class LogMaster{
+ private static $_log=false;//!< logging mode flag
+ private static $_output=false;//!< output error infor to client flag
+ private static $session="";//!< all messages generated for current request
+
+ /*! convert array to string representation ( it is a bit more readable than var_dump )
+
+ @param data
+ data object
+ @param pref
+ prefix string, used for formating, optional
+ @return
+ string with array description
+ */
+ private static function log_details($data,$pref=""){
+ if (is_array($data)){
+ $str=array("");
+ foreach($data as $k=>$v)
+ array_push($str,$pref.$k." => ".LogMaster::log_details($v,$pref."\t"));
+ return implode("\n",$str);
+ }
+ return $data;
+ }
+ /*! put record in log
+
+ @param str
+ string with log info, optional
+ @param data
+ data object, which will be added to log, optional
+ */
+ public static function log($str="",$data=""){
+ if (LogMaster::$_log){
+ $message = $str.LogMaster::log_details($data)."\n\n";
+ LogMaster::$session.=$message;
+ error_log($message,3,LogMaster::$_log);
+ }
+ }
+
+ /*! get logs for current request
+ @return
+ string, which contains all log messages generated for current request
+ */
+ public static function get_session_log(){
+ return LogMaster::$session;
+ }
+
+ /*! error handler, put normal php errors in log file
+
+ @param errn
+ error number
+ @param errstr
+ error description
+ @param file
+ error file
+ @param line
+ error line
+ @param context
+ error cntext
+ */
+ public static function error_log($errn,$errstr,$file,$line,$context){
+ LogMaster::log($errstr." at ".$file." line ".$line);
+ }
+
+ /*! exception handler, used as default reaction on any error - show execution log and stop processing
+
+ @param exception
+ instance of Exception
+ */
+ public static function exception_log($exception){
+ LogMaster::log("!!!Uncaught Exception\nCode: " . $exception->getCode() . "\nMessage: " . $exception->getMessage());
+ if (LogMaster::$_output){
+ echo "<pre><xmp>\n";
+ echo LogMaster::get_session_log();
+ echo "\n</xmp></pre>";
+ }
+ die();
+ }
+
+ /*! enable logging
+
+ @param name
+ path to the log file, if boolean false provided as value - logging will be disabled
+ @param output
+ flag of client side output, if enabled - session log will be sent to client side in case of an error.
+ */
+ public static function enable_log($name,$output=false){
+ LogMaster::$_log=$name;
+ LogMaster::$_output=$output;
+ if ($name){
+ set_error_handler(array("LogMaster","error_log"),E_ALL);
+ set_exception_handler(array("LogMaster","exception_log"));
+ LogMaster::log("\n\n====================================\nLog started, ".date("d/m/Y h:m:s")."\n====================================");
+ }
+ }
+}
+
?> \ No newline at end of file
diff --git a/codebase/tree_connector.php b/codebase/tree_connector.php
index 850de0d..ddc21e7 100644
--- a/codebase/tree_connector.php
+++ b/codebase/tree_connector.php
@@ -1,235 +1,225 @@
-<?php
-/*
- @author dhtmlx.com
- @license GPL, see license.txt
-*/
-require_once("base_connector.php");
-
-/*! DataItem class for Tree component
-**/
-
-class TreeDataItem extends DataItem{
- private $im0;//!< image of closed folder
- private $im1;//!< image of opened folder
- private $im2;//!< image of leaf item
- private $check;//!< checked state
- private $kids=-1;//!< checked state
- private $attrs;//!< collection of custom attributes
-
- function __construct($data,$config,$index){
- parent::__construct($data,$config,$index);
-
- $this->im0=false;
- $this->im1=false;
- $this->im2=false;
- $this->check=false;
- $this->attrs = array();
- $this->userdata = array();
- }
- /*! get id of parent record
-
- @return
- id of parent record
- */
- function get_parent_id(){
- return $this->data[$this->config->relation_id["name"]];
- }
- /*! get state of items checkbox
-
- @return
- state of item's checkbox as int value, false if state was not defined
- */
- function get_check_state(){
- return $this->check;
- }
- /*! set state of item's checkbox
-
- @param value
- int value, 1 - checked, 0 - unchecked, -1 - third state
- */
- function set_check_state($value){
- $this->check=$value;
- }
-
- /*! return count of child items
- -1 if there is no info about childs
- @return
- count of child items
- */
- function has_kids(){
- return $this->kids;
- }
- /*! sets count of child items
- @param value
- count of child items
- */
- function set_kids($value){
- $this->kids=$value;
- }
-
- /*! set custom attribute
-
- @param name
- name of the attribute
- @param value
- new value of the attribute
- */
- function set_attribute($name, $value){
- switch($name){
- case "id":
- $this->set_id($value);
- break;
- case "text":
- $this->data[$this->config->text[0]["name"]]=$value;
- break;
- case "checked":
- $this->set_check_state($value);
- break;
- case "im0":
- $this->im0=$value;
- break;
- case "im1":
- $this->im1=$value;
- break;
- case "im2":
- $this->im2=$value;
- break;
- case "child":
- $this->set_kids($value);
- break;
- default:
- $this->attrs[$name]=$value;
- }
- }
-
- /*! set userdata section for the item
-
- @param name
- name of userdata
- @param value
- value of userdata
- */
- function set_userdata($name, $value){
- $this->userdata[$name]=$value;
- }
-
- /*! assign image for tree's item
-
- @param img_folder_closed
- image for item, which represents folder in closed state
- @param img_folder_open
- image for item, which represents folder in opened state, optional
- @param img_leaf
- image for item, which represents leaf item, optional
- */
- function set_image($img_folder_closed,$img_folder_open=false,$img_leaf=false){
- $this->im0=$img_folder_closed;
- $this->im1=$img_folder_open?$img_folder_open:$img_folder_closed;
- $this->im2=$img_leaf?$img_leaf:$img_folder_closed;
- }
- /*! return self as XML string, starting part
- */
- function to_xml_start(){
- if ($this->skip) return "";
-
- $str1="<item id='".$this->get_id()."' text='".$this->xmlentities($this->data[$this->config->text[0]["name"]])."' ";
- if ($this->has_kids()==true) $str1.="child='".$this->has_kids()."' ";
- if ($this->im0) $str1.="im0='".$this->im0."' ";
- if ($this->im1) $str1.="im1='".$this->im1."' ";
- if ($this->im2) $str1.="im2='".$this->im2."' ";
- if ($this->check) $str1.="checked='".$this->check."' ";
- foreach ($this->attrs as $key => $value)
- $str1.=$key."='".$this->xmlentities($value)."' ";
- $str1.=">";
- foreach ($this->userdata as $key => $value)
- $str1.="<userdata name='".$key."'><![CDATA[".$value."]]></userdata>";
-
- return $str1;
- }
- /*! return self as XML string, ending part
- */
- function to_xml_end(){
- if ($this->skip) return "";
- return "</item>";
- }
-
-}
-
-require_once("filesystem_item.php");
-
-/*! Connector for the dhtmlxtree
-**/
-class TreeConnector extends Connector{
- protected $parent_name = 'id';
-
- /*! constructor
-
- Here initilization of all Masters occurs, execution timer initialized
- @param res
- db connection resource
- @param type
- string , which hold type of database ( MySQL or Postgre ), optional, instead of short DB name, full name of DataWrapper-based class can be provided
- @param item_type
- name of class, which will be used for item rendering, optional, DataItem will be used by default
- @param data_type
- name of class which will be used for dataprocessor calls handling, optional, DataProcessor class will be used by default.
- * @param render_type
- * name of class which will provides data rendering
- */
- 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";
- 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
- public function parse_request(){
- parent::parse_request();
-
- 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
- }
-
- /*! renders self as xml, starting part
- */
- public function xml_start(){
- return "<tree id='".$this->request->get_relation()."'>";
- }
-
- /*! renders self as xml, ending part
- */
- public function xml_end(){
- return "</tree>";
- }
-}
-
-
-class TreeDataProcessor extends DataProcessor{
-
- function __construct($connector,$config,$request){
- parent::__construct($connector,$config,$request);
- $request->set_relation(false);
- }
-
- /*! convert incoming data name to valid db name
- converts c0..cN to valid field names
- @param data
- data name from incoming request
- @return
- related db_name
- */
- function name_data($data){
- if ($data=="tr_pid")
- return $this->config->relation_id["db_name"];
- if ($data=="tr_text")
- return $this->config->text[0]["db_name"];
- return $data;
- }
-}
-
+<?php
+/*
+ @author dhtmlx.com
+ @license GPL, see license.txt
+*/
+require_once("base_connector.php");
+
+/*! DataItem class for Tree component
+**/
+
+class TreeDataItem extends DataItem{
+ private $im0;//!< image of closed folder
+ private $im1;//!< image of opened folder
+ private $im2;//!< image of leaf item
+ private $check;//!< checked state
+ private $kids=-1;//!< checked state
+ private $attrs;//!< collection of custom attributes
+
+ function __construct($data,$config,$index){
+ parent::__construct($data,$config,$index);
+
+ $this->im0=false;
+ $this->im1=false;
+ $this->im2=false;
+ $this->check=false;
+ $this->attrs = array();
+ }
+ /*! get id of parent record
+
+ @return
+ id of parent record
+ */
+ function get_parent_id(){
+ return $this->data[$this->config->relation_id["name"]];
+ }
+ /*! get state of items checkbox
+
+ @return
+ state of item's checkbox as int value, false if state was not defined
+ */
+ function get_check_state(){
+ return $this->check;
+ }
+ /*! set state of item's checkbox
+
+ @param value
+ int value, 1 - checked, 0 - unchecked, -1 - third state
+ */
+ function set_check_state($value){
+ $this->check=$value;
+ }
+
+ /*! return count of child items
+ -1 if there is no info about childs
+ @return
+ count of child items
+ */
+ function has_kids(){
+ return $this->kids;
+ }
+ /*! sets count of child items
+ @param value
+ count of child items
+ */
+ function set_kids($value){
+ $this->kids=$value;
+ }
+
+ /*! set custom attribute
+
+ @param name
+ name of the attribute
+ @param value
+ new value of the attribute
+ */
+ function set_attribute($name, $value){
+ switch($name){
+ case "id":
+ $this->set_id($value);
+ break;
+ case "text":
+ $this->data[$this->config->text[0]["name"]]=$value;
+ break;
+ case "checked":
+ $this->set_check_state($value);
+ break;
+ case "im0":
+ $this->im0=$value;
+ break;
+ case "im1":
+ $this->im1=$value;
+ break;
+ case "im2":
+ $this->im2=$value;
+ break;
+ case "child":
+ $this->set_kids($value);
+ break;
+ default:
+ $this->attrs[$name]=$value;
+ }
+ }
+
+
+ /*! assign image for tree's item
+
+ @param img_folder_closed
+ image for item, which represents folder in closed state
+ @param img_folder_open
+ image for item, which represents folder in opened state, optional
+ @param img_leaf
+ image for item, which represents leaf item, optional
+ */
+ function set_image($img_folder_closed,$img_folder_open=false,$img_leaf=false){
+ $this->im0=$img_folder_closed;
+ $this->im1=$img_folder_open?$img_folder_open:$img_folder_closed;
+ $this->im2=$img_leaf?$img_leaf:$img_folder_closed;
+ }
+ /*! return self as XML string, starting part
+ */
+ function to_xml_start(){
+ if ($this->skip) return "";
+
+ $str1="<item id='".$this->get_id()."' text='".$this->xmlentities($this->data[$this->config->text[0]["name"]])."' ";
+ if ($this->has_kids()==true) $str1.="child='".$this->has_kids()."' ";
+ if ($this->im0) $str1.="im0='".$this->im0."' ";
+ if ($this->im1) $str1.="im1='".$this->im1."' ";
+ if ($this->im2) $str1.="im2='".$this->im2."' ";
+ if ($this->check) $str1.="checked='".$this->check."' ";
+ foreach ($this->attrs as $key => $value)
+ $str1.=$key."='".$this->xmlentities($value)."' ";
+ $str1.=">";
+ if ($this->userdata !== false)
+ foreach ($this->userdata as $key => $value)
+ $str1.="<userdata name='".$key."'><![CDATA[".$value."]]></userdata>";
+
+ return $str1;
+ }
+ /*! return self as XML string, ending part
+ */
+ function to_xml_end(){
+ if ($this->skip) return "";
+ return "</item>";
+ }
+
+}
+
+require_once("filesystem_item.php");
+
+/*! Connector for the dhtmlxtree
+**/
+class TreeConnector extends Connector{
+ protected $parent_name = 'id';
+
+ /*! constructor
+
+ Here initilization of all Masters occurs, execution timer initialized
+ @param res
+ db connection resource
+ @param type
+ string , which hold type of database ( MySQL or Postgre ), optional, instead of short DB name, full name of DataWrapper-based class can be provided
+ @param item_type
+ name of class, which will be used for item rendering, optional, DataItem will be used by default
+ @param data_type
+ name of class which will be used for dataprocessor calls handling, optional, DataProcessor class will be used by default.
+ * @param render_type
+ * name of class which will provides data rendering
+ */
+ 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";
+ 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
+ public function parse_request(){
+ parent::parse_request();
+
+ 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
+ }
+
+ /*! renders self as xml, starting part
+ */
+ public function xml_start(){
+ return "<tree id='".$this->request->get_relation()."'>";
+ }
+
+ /*! renders self as xml, ending part
+ */
+ public function xml_end(){
+ return "</tree>";
+ }
+}
+
+
+class TreeDataProcessor extends DataProcessor{
+
+ function __construct($connector,$config,$request){
+ parent::__construct($connector,$config,$request);
+ $request->set_relation(false);
+ }
+
+ /*! convert incoming data name to valid db name
+ converts c0..cN to valid field names
+ @param data
+ data name from incoming request
+ @return
+ related db_name
+ */
+ function name_data($data){
+ if ($data=="tr_pid")
+ return $this->config->relation_id["db_name"];
+ if ($data=="tr_text")
+ return $this->config->text[0]["db_name"];
+ return $data;
+ }
+}
+
?> \ No newline at end of file