Moving dhtmlxGantt library to 'libraries' folder
This commit is contained in:
parent
dbcdde741c
commit
5e16eb66dd
162 changed files with 6 additions and 5 deletions
948
libraries/dhtmlxgantt/connector/base_connector.php
Normal file
948
libraries/dhtmlxgantt/connector/base_connector.php
Normal file
|
|
@ -0,0 +1,948 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
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
|
||||
//because of this command, it strongly recommended to include connector's file before any other libs
|
||||
//in such case it will handle any extra output from not well formed code of other libs
|
||||
ini_set("output_buffering","On");
|
||||
ob_start();
|
||||
|
||||
class OutputWriter{
|
||||
private $start;
|
||||
private $end;
|
||||
private $type;
|
||||
|
||||
public function __construct($start, $end = ""){
|
||||
$this->start = $start;
|
||||
$this->end = $end;
|
||||
$this->type = "xml";
|
||||
}
|
||||
public function add($add){
|
||||
$this->start.=$add;
|
||||
}
|
||||
public function reset(){
|
||||
$this->start="";
|
||||
$this->end="";
|
||||
}
|
||||
public function set_type($add){
|
||||
$this->type=$add;
|
||||
}
|
||||
public function output($name="", $inline=true, $encoding=""){
|
||||
ob_clean();
|
||||
|
||||
if ($this->type == "xml"){
|
||||
$header = "Content-type: text/xml";
|
||||
if ("" != $encoding)
|
||||
$header.="; charset=".$encoding;
|
||||
header($header);
|
||||
}
|
||||
|
||||
echo $this->__toString();
|
||||
}
|
||||
public function __toString(){
|
||||
return $this->start.$this->end;
|
||||
}
|
||||
}
|
||||
|
||||
/*! EventInterface
|
||||
Base class , for iterable collections, which are used in event
|
||||
**/
|
||||
class EventInterface{
|
||||
protected $request; ////!< DataRequestConfig instance
|
||||
public $rules=array(); //!< array of sorting rules
|
||||
|
||||
/*! constructor
|
||||
creates a new interface based on existing request
|
||||
@param request
|
||||
DataRequestConfig object
|
||||
*/
|
||||
public function __construct($request){
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/*! remove all elements from collection
|
||||
*/
|
||||
public function clear(){
|
||||
array_splice($rules,0);
|
||||
}
|
||||
/*! get index by name
|
||||
|
||||
@param name
|
||||
name of field
|
||||
@return
|
||||
index of named field
|
||||
*/
|
||||
public function index($name){
|
||||
$len = sizeof($this->rules);
|
||||
for ($i=0; $i < $len; $i++) {
|
||||
if ($this->rules[$i]["name"]==$name)
|
||||
return $i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*! Wrapper for collection of sorting rules
|
||||
**/
|
||||
class SortInterface extends EventInterface{
|
||||
/*! constructor
|
||||
creates a new interface based on existing request
|
||||
@param request
|
||||
DataRequestConfig object
|
||||
*/
|
||||
public function __construct($request){
|
||||
parent::__construct($request);
|
||||
$this->rules = &$request->get_sort_by_ref();
|
||||
}
|
||||
/*! add new sorting rule
|
||||
|
||||
@param name
|
||||
name of field
|
||||
@param dir
|
||||
direction of sorting
|
||||
*/
|
||||
public function add($name,$dir){
|
||||
if ($dir === false)
|
||||
$this->request->set_sort($name);
|
||||
else
|
||||
$this->request->set_sort($name,$dir);
|
||||
}
|
||||
public function store(){
|
||||
$this->request->set_sort_by($this->rules);
|
||||
}
|
||||
}
|
||||
/*! Wrapper for collection of filtering rules
|
||||
**/
|
||||
class FilterInterface extends EventInterface{
|
||||
/*! constructor
|
||||
creates a new interface based on existing request
|
||||
@param request
|
||||
DataRequestConfig object
|
||||
*/
|
||||
public function __construct($request){
|
||||
$this->request = $request;
|
||||
$this->rules = &$request->get_filters_ref();
|
||||
}
|
||||
/*! add new filatering rule
|
||||
|
||||
@param name
|
||||
name of field
|
||||
@param value
|
||||
value to filter by
|
||||
@param rule
|
||||
filtering rule
|
||||
*/
|
||||
public function add($name,$value,$rule){
|
||||
$this->request->set_filter($name,$value,$rule);
|
||||
}
|
||||
public function store(){
|
||||
$this->request->set_filters($this->rules);
|
||||
}
|
||||
}
|
||||
|
||||
/*! base class for component item representation
|
||||
**/
|
||||
class DataItem{
|
||||
protected $data; //!< hash of data
|
||||
protected $config;//!< DataConfig instance
|
||||
protected $index;//!< index of element
|
||||
protected $skip;//!< flag , which set if element need to be skiped during rendering
|
||||
protected $userdata;
|
||||
|
||||
/*! constructor
|
||||
|
||||
@param data
|
||||
hash of data
|
||||
@param config
|
||||
DataConfig object
|
||||
@param index
|
||||
index of element
|
||||
*/
|
||||
function __construct($data,$config,$index){
|
||||
$this->config=$config;
|
||||
$this->data=$data;
|
||||
$this->index=$index;
|
||||
$this->skip=false;
|
||||
$this->userdata=false;
|
||||
}
|
||||
|
||||
//set userdata for the item
|
||||
function set_userdata($name, $value){
|
||||
if ($this->userdata === false)
|
||||
$this->userdata = array();
|
||||
|
||||
$this->userdata[$name]=$value;
|
||||
}
|
||||
/*! get named value
|
||||
|
||||
@param name
|
||||
name or alias of field
|
||||
@return
|
||||
value from field with provided name or alias
|
||||
*/
|
||||
public function get_value($name){
|
||||
return $this->data[$name];
|
||||
}
|
||||
/*! set named value
|
||||
|
||||
@param name
|
||||
name or alias of field
|
||||
@param value
|
||||
value for field with provided name or alias
|
||||
*/
|
||||
public function set_value($name,$value){
|
||||
return $this->data[$name]=$value;
|
||||
}
|
||||
/*! get id of element
|
||||
@return
|
||||
id of element
|
||||
*/
|
||||
public function get_id(){
|
||||
$id = $this->config->id["name"];
|
||||
if (array_key_exists($id,$this->data))
|
||||
return $this->data[$id];
|
||||
return false;
|
||||
}
|
||||
/*! change id of element
|
||||
|
||||
@param value
|
||||
new id value
|
||||
*/
|
||||
public function set_id($value){
|
||||
$this->data[$this->config->id["name"]]=$value;
|
||||
}
|
||||
/*! get index of element
|
||||
|
||||
@return
|
||||
index of element
|
||||
*/
|
||||
public function get_index(){
|
||||
return $this->index;
|
||||
}
|
||||
/*! mark element for skiping ( such element will not be rendered )
|
||||
*/
|
||||
public function skip(){
|
||||
$this->skip=true;
|
||||
}
|
||||
|
||||
/*! return self as XML string
|
||||
*/
|
||||
public function to_xml(){
|
||||
return $this->to_xml_start().$this->to_xml_end();
|
||||
}
|
||||
|
||||
/*! replace xml unsafe characters
|
||||
|
||||
@param string
|
||||
string to be escaped
|
||||
@return
|
||||
escaped string
|
||||
*/
|
||||
public function xmlentities($string) {
|
||||
return str_replace( array( '&', '"', "'", '<', '>', '’' ), array( '&' , '"', ''' , '<' , '>', ''' ), $string);
|
||||
}
|
||||
|
||||
/*! return starting tag for self as XML string
|
||||
*/
|
||||
public function to_xml_start(){
|
||||
$str="<item";
|
||||
for ($i=0; $i < sizeof($this->config->data); $i++){
|
||||
$name=$this->config->data[$i]["name"];
|
||||
$db_name=$this->config->data[$i]["db_name"];
|
||||
$str.=" ".$name."='".$this->xmlentities($this->data[$name])."'";
|
||||
}
|
||||
//output custom data
|
||||
if ($this->userdata !== false)
|
||||
foreach ($this->userdata as $key => $value){
|
||||
$str.=" ".$key."='".$this->xmlentities($value)."'";
|
||||
}
|
||||
|
||||
return $str.">";
|
||||
}
|
||||
/*! return ending tag for XML string
|
||||
*/
|
||||
public function to_xml_end(){
|
||||
return "</item>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*! Base connector class
|
||||
This class used as a base for all component specific connectors.
|
||||
Can be used on its own to provide raw data.
|
||||
**/
|
||||
class Connector {
|
||||
protected $config;//DataConfig instance
|
||||
protected $request;//DataRequestConfig instance
|
||||
protected $names;//!< hash of names for used classes
|
||||
protected $encoding="utf-8";//!< assigned encoding (UTF-8 by default)
|
||||
protected $editing=false;//!< flag of edit mode ( response for dataprocessor )
|
||||
|
||||
public static $filter_var="dhx_filter";
|
||||
public static $sort_var="dhx_sort";
|
||||
public static $kids_var="dhx_kids";
|
||||
|
||||
public $model=false;
|
||||
|
||||
private $updating=false;//!< flag of update mode ( response for data-update )
|
||||
private $db; //!< db connection resource
|
||||
protected $dload;//!< flag of dyn. loading mode
|
||||
public $access; //!< AccessMaster instance
|
||||
protected $data_separator = "\n";
|
||||
|
||||
public $sql; //DataWrapper instance
|
||||
public $event; //EventMaster instance
|
||||
public $limit=false;
|
||||
|
||||
private $id_seed=0; //!< default value, used to generate auto-IDs
|
||||
protected $live_update = false; // actions table name for autoupdating
|
||||
protected $extra_output="";//!< extra info which need to be sent to client side
|
||||
protected $options=array();//!< hash of OptionsConnector
|
||||
protected $as_string = false; // render() returns string, don't send result in response
|
||||
protected $simple = false; // render only data without any other info
|
||||
protected $filters;
|
||||
protected $sorts;
|
||||
protected $mix;
|
||||
protected $order = false;
|
||||
|
||||
/*! constructor
|
||||
|
||||
Here initilization of all Masters occurs, execution timer initialized
|
||||
@param db
|
||||
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($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->attributes = array();
|
||||
$this->filters = array();
|
||||
$this->sorts = array();
|
||||
$this->mix = array();
|
||||
|
||||
$this->config = new DataConfig();
|
||||
$this->request = new DataRequestConfig();
|
||||
$this->event = new EventMaster();
|
||||
$this->access = new AccessMaster();
|
||||
|
||||
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
|
||||
|
||||
EventMaster::trigger_static("connectorCreate",$this);
|
||||
}
|
||||
|
||||
/*! return db connection resource
|
||||
nested class may neeed to access live connection object
|
||||
@return
|
||||
DB connection resource
|
||||
*/
|
||||
protected function get_connection(){
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
public function get_config(){
|
||||
return new DataConfig($this->config);
|
||||
}
|
||||
|
||||
public function get_request(){
|
||||
return new DataRequestConfig($this->request);
|
||||
}
|
||||
|
||||
|
||||
protected $attributes;
|
||||
public function add_top_attribute($name, $string){
|
||||
$this->attributes[$name] = $string;
|
||||
}
|
||||
|
||||
//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
|
||||
name of table in DB
|
||||
@param id
|
||||
name of id field
|
||||
@param fields
|
||||
list of fields names
|
||||
@param extra
|
||||
list of extra fields, optional, such fields will not be included in data rendering, but will be accessible in all inner events
|
||||
@param relation_id
|
||||
name of field used to define relations for hierarchical data organization, optional
|
||||
*/
|
||||
public function render_table($table,$id="",$fields=false,$extra=false,$relation_id=false){
|
||||
$this->configure($table,$id,$fields,$extra,$relation_id);
|
||||
return $this->render();
|
||||
}
|
||||
public function configure($table,$id="",$fields=false,$extra=false,$relation_id=false){
|
||||
if ($fields === false){
|
||||
//auto-config
|
||||
$info = $this->sql->fields_list($table);
|
||||
$fields = implode(",",$info["fields"]);
|
||||
if ($info["key"])
|
||||
$id = $info["key"];
|
||||
}
|
||||
$this->config->init($id,$fields,$extra,$relation_id);
|
||||
if (strpos(trim($table), " ")!==false)
|
||||
$this->request->parse_sql($table);
|
||||
else
|
||||
$this->request->set_source($table);
|
||||
}
|
||||
|
||||
public function uuid(){
|
||||
return time()."x".$this->id_seed++;
|
||||
}
|
||||
|
||||
/*! config connector based on sql
|
||||
|
||||
@param sql
|
||||
sql query used as base of configuration
|
||||
@param id
|
||||
name of id field
|
||||
@param fields
|
||||
list of fields names
|
||||
@param extra
|
||||
list of extra fields, optional, such fields will not be included in data rendering, but will be accessible in all inner events
|
||||
@param relation_id
|
||||
name of field used to define relations for hierarchical data organization, optional
|
||||
*/
|
||||
public function render_sql($sql,$id,$fields,$extra=false,$relation_id=false){
|
||||
$this->config->init($id,$fields,$extra,$relation_id);
|
||||
$this->request->parse_sql($sql);
|
||||
return $this->render();
|
||||
}
|
||||
|
||||
public function render_array($data, $id, $fields, $extra=false, $relation_id=false){
|
||||
$this->configure("-",$id,$fields,$extra,$relation_id);
|
||||
$this->sql = new ArrayDBDataWrapper($data, $this->config);
|
||||
return $this->render();
|
||||
}
|
||||
|
||||
public function render_complex_sql($sql,$id,$fields,$extra=false,$relation_id=false){
|
||||
$this->config->init($id,$fields,$extra,$relation_id);
|
||||
$this->request->parse_sql($sql, true);
|
||||
return $this->render();
|
||||
}
|
||||
|
||||
/*! render already configured connector
|
||||
|
||||
@param config
|
||||
configuration of data
|
||||
@param request
|
||||
configuraton of request
|
||||
*/
|
||||
public function render_connector($config,$request){
|
||||
$this->config->copy($config);
|
||||
$this->request->copy($request);
|
||||
return $this->render();
|
||||
}
|
||||
|
||||
/*! render self
|
||||
process commands, output requested data as XML
|
||||
*/
|
||||
public function render(){
|
||||
$this->event->trigger("onInit", $this);
|
||||
EventMaster::trigger_static("connectorInit",$this);
|
||||
|
||||
if (!$this->as_string)
|
||||
$this->parse_request();
|
||||
$this->set_relation();
|
||||
|
||||
if ($this->live_update !== false && $this->updating!==false) {
|
||||
$this->live_update->get_updates();
|
||||
} else {
|
||||
if ($this->editing){
|
||||
$dp = new $this->names["data_class"]($this,$this->config,$this->request);
|
||||
$dp->process($this->config,$this->request);
|
||||
} else {
|
||||
if (!$this->access->check("read")){
|
||||
LogMaster::log("Access control: read operation blocked");
|
||||
echo "Access denied";
|
||||
die();
|
||||
}
|
||||
$wrap = new SortInterface($this->request);
|
||||
$this->apply_sorts($wrap);
|
||||
$this->event->trigger("beforeSort",$wrap);
|
||||
$wrap->store();
|
||||
|
||||
$wrap = new FilterInterface($this->request);
|
||||
$this->apply_filters($wrap);
|
||||
$this->event->trigger("beforeFilter",$wrap);
|
||||
$wrap->store();
|
||||
|
||||
if ($this->model && method_exists($this->model, "get")){
|
||||
$this->sql = new ArrayDBDataWrapper();
|
||||
$result = new ArrayQueryWrapper(call_user_func(array($this->model, "get"), $this->request));
|
||||
$out = $this->output_as_xml($result);
|
||||
} else {
|
||||
$out = $this->output_as_xml($this->get_resource());
|
||||
|
||||
if ($out !== null) return $out;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
$this->end_run();
|
||||
}
|
||||
|
||||
|
||||
/*! 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
|
||||
incoming field name
|
||||
@return
|
||||
safe field name
|
||||
*/
|
||||
protected function safe_field_name($str){
|
||||
return strtok($str, " \n\t;',");
|
||||
}
|
||||
|
||||
/*! limit max count of records
|
||||
connector will ignore any records after outputing max count
|
||||
@param limit
|
||||
max count of records
|
||||
@return
|
||||
none
|
||||
*/
|
||||
public function set_limit($limit){
|
||||
$this->limit = $limit;
|
||||
}
|
||||
|
||||
|
||||
public function limit($start, $count, $sort_field=false, $sort_dir=false){
|
||||
$this->request->set_limit($start, $count);
|
||||
if ($sort_field)
|
||||
$this->request->set_sort($sort_field, $sort_dir);
|
||||
}
|
||||
|
||||
protected function parse_request_mode(){
|
||||
//detect edit mode
|
||||
if (isset($_GET["editing"])){
|
||||
$this->editing=true;
|
||||
} else if (isset($_POST["ids"])){
|
||||
$this->editing=true;
|
||||
LogMaster::log('While there is no edit mode mark, POST parameters similar to edit mode detected. \n Switching to edit mode ( to disable behavior remove POST[ids]');
|
||||
} else if (isset($_GET['dhx_version'])){
|
||||
$this->updating = true;
|
||||
}
|
||||
}
|
||||
|
||||
/*! parse incoming request, detects commands and modes
|
||||
*/
|
||||
protected function parse_request(){
|
||||
//set default dyn. loading params, can be reset in child classes
|
||||
if ($this->dload)
|
||||
$this->request->set_limit(0,$this->dload);
|
||||
else if ($this->limit)
|
||||
$this->request->set_limit(0,$this->limit);
|
||||
|
||||
if (isset($_GET["posStart"]) && isset($_GET["count"])) {
|
||||
$this->request->set_limit($_GET["posStart"],$_GET["count"]);
|
||||
}
|
||||
|
||||
$this->parse_request_mode();
|
||||
|
||||
if ($this->live_update && ($this->updating || $this->editing)){
|
||||
$this->request->set_version($_GET["dhx_version"]);
|
||||
$this->request->set_user($_GET["dhx_user"]);
|
||||
}
|
||||
|
||||
if (isset($_GET[Connector::$sort_var]))
|
||||
foreach($_GET[Connector::$sort_var] as $k => $v){
|
||||
$k = $this->safe_field_name($k);
|
||||
$this->request->set_sort($this->resolve_parameter($k),$v);
|
||||
}
|
||||
|
||||
if (isset($_GET[Connector::$filter_var]))
|
||||
foreach($_GET[Connector::$filter_var] as $k => $v){
|
||||
$k = $this->safe_field_name($k);
|
||||
if ($v !== "")
|
||||
$this->request->set_filter($this->resolve_parameter($k),$v);
|
||||
}
|
||||
|
||||
$this->check_csrf();
|
||||
}
|
||||
|
||||
protected function check_csrf(){
|
||||
$key = ConnectorSecurity::checkCSRF($this->editing);
|
||||
if ($key !== "")
|
||||
$this->add_top_attribute(ConnectorSecurity::$security_var, $key);
|
||||
}
|
||||
|
||||
/*! convert incoming request name to the actual DB name
|
||||
@param name
|
||||
incoming parameter name
|
||||
@return
|
||||
name of related DB field
|
||||
*/
|
||||
protected function resolve_parameter($name){
|
||||
return $name;
|
||||
}
|
||||
|
||||
|
||||
/*! replace xml unsafe characters
|
||||
|
||||
@param string
|
||||
string to be escaped
|
||||
@return
|
||||
escaped string
|
||||
*/
|
||||
protected function xmlentities($string) {
|
||||
return str_replace( array( '&', '"', "'", '<', '>', '’' ), array( '&' , '"', ''' , '<' , '>', ''' ), $string);
|
||||
}
|
||||
|
||||
public function getRecord($id){
|
||||
LogMaster::log("Retreiving data for record: ".$id);
|
||||
$source = new DataRequestConfig($this->request);
|
||||
$source->set_filter($this->config->id["name"],$id, "=");
|
||||
|
||||
$res = $this->sql->select($source);
|
||||
|
||||
$temp = $this->data_separator;
|
||||
$this->data_separator="";
|
||||
$output = $this->render_set($res);
|
||||
$this->data_separato=$temp;
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/*! render from DB resultset
|
||||
@param res
|
||||
DB resultset
|
||||
process commands, output requested data as XML
|
||||
*/
|
||||
protected function render_set($res){
|
||||
return $this->render->render_set($res, $this->names["item_class"], $this->dload, $this->data_separator, $this->config, $this->mix);
|
||||
}
|
||||
|
||||
/*! output fetched data as XML
|
||||
@param res
|
||||
DB resultset
|
||||
*/
|
||||
protected function output_as_xml($res){
|
||||
$result = $this->render_set($res);
|
||||
if ($this->simple) return $result;
|
||||
|
||||
$start="<?xml version='1.0' encoding='".$this->encoding."' ?>".$this->xml_start();
|
||||
$end=$result.$this->xml_end();
|
||||
|
||||
if ($this->as_string) return $start.$end;
|
||||
|
||||
$out = new OutputWriter($start, $end);
|
||||
$this->event->trigger("beforeOutput", $this, $out);
|
||||
$out->output("", true, $this->encoding);
|
||||
}
|
||||
|
||||
|
||||
/*! end processing
|
||||
stop execution timer, kill the process
|
||||
*/
|
||||
protected function end_run(){
|
||||
$time=microtime(true)-$this->exec_time;
|
||||
LogMaster::log("Done in {$time}s");
|
||||
flush();
|
||||
die();
|
||||
}
|
||||
|
||||
/*! set xml encoding
|
||||
|
||||
methods sets only attribute in XML, no real encoding conversion occurs
|
||||
@param encoding
|
||||
value which will be used as XML encoding
|
||||
*/
|
||||
public function set_encoding($encoding){
|
||||
$this->encoding=$encoding;
|
||||
}
|
||||
|
||||
/*! enable or disable dynamic loading mode
|
||||
|
||||
@param count
|
||||
count of rows loaded from server, actual only for grid-connector, can be skiped in other cases.
|
||||
If value is a false or 0 - dyn. loading will be disabled
|
||||
*/
|
||||
public function dynamic_loading($count){
|
||||
$this->dload=$count;
|
||||
}
|
||||
|
||||
/*! enable or disable data reordering
|
||||
|
||||
@param name
|
||||
name of field, which will be used for order storing, optional
|
||||
by default 'sortorder' field will be used
|
||||
*/
|
||||
public function enable_order($name = true){
|
||||
if ($name === true)
|
||||
$name = "sortorder";
|
||||
|
||||
$this->sort($name);
|
||||
$this->access->allow("order");
|
||||
$this->request->set_order($name);
|
||||
$this->order = $name;
|
||||
}
|
||||
|
||||
/*! enable logging
|
||||
|
||||
@param path
|
||||
path to the log file. If set as false or empty strig - logging will be disabled
|
||||
@param client_log
|
||||
enable output of log data to the client side
|
||||
*/
|
||||
public function enable_log($path=true,$client_log=false){
|
||||
LogMaster::enable_log($path,$client_log);
|
||||
}
|
||||
|
||||
/*! provides infor about current processing mode
|
||||
@return
|
||||
true if processing dataprocessor command, false otherwise
|
||||
*/
|
||||
public function is_select_mode(){
|
||||
$this->parse_request_mode();
|
||||
return !$this->editing;
|
||||
}
|
||||
|
||||
public function is_first_call(){
|
||||
$this->parse_request_mode();
|
||||
return !($this->editing || $this->updating || $this->request->get_start() || isset($_GET['dhx_no_header']));
|
||||
|
||||
}
|
||||
|
||||
/*! renders self as xml, starting part
|
||||
*/
|
||||
protected function xml_start(){
|
||||
$attributes = "";
|
||||
|
||||
if ($this->dload){
|
||||
//info for dyn. loadin
|
||||
if ($pos=$this->request->get_start())
|
||||
$attributes .= " pos='".$pos."'";
|
||||
else
|
||||
$attributes .= " total_count='".$this->sql->get_size($this->request)."'";
|
||||
}
|
||||
foreach($this->attributes as $k=>$v)
|
||||
$attributes .= " ".$k."='".$v."'";
|
||||
|
||||
return "<data".$attributes.">";
|
||||
}
|
||||
/*! renders self as xml, ending part
|
||||
*/
|
||||
protected function xml_end(){
|
||||
$this->fill_collections();
|
||||
if (isset($this->extra_output))
|
||||
return $this->extra_output."</data>";
|
||||
else
|
||||
return "</data>";
|
||||
}
|
||||
|
||||
protected function fill_collections($list=""){
|
||||
foreach ($this->options as $k=>$v) {
|
||||
$name = $k;
|
||||
$this->extra_output.="<coll_options for='{$name}'>";
|
||||
if (!is_string($this->options[$name]))
|
||||
$this->extra_output.=$this->options[$name]->render();
|
||||
else
|
||||
$this->extra_output.=$this->options[$name];
|
||||
$this->extra_output.="</coll_options>";
|
||||
}
|
||||
}
|
||||
|
||||
/*! assign options collection to the column
|
||||
|
||||
@param name
|
||||
name of the column
|
||||
@param options
|
||||
array or connector object
|
||||
*/
|
||||
public function set_options($name,$options){
|
||||
if (is_array($options)){
|
||||
$str="";
|
||||
foreach($options as $k => $v)
|
||||
$str.="<item value='".$this->xmlentities($k)."' label='".$this->xmlentities($v)."' />";
|
||||
$options=$str;
|
||||
}
|
||||
$this->options[$name]=$options;
|
||||
}
|
||||
|
||||
|
||||
public function insert($data) {
|
||||
$action = new DataAction('inserted', false, $data);
|
||||
$request = new DataRequestConfig();
|
||||
$request->set_source($this->request->get_source());
|
||||
|
||||
$this->config->limit_fields($data);
|
||||
$this->sql->insert($action,$request);
|
||||
$this->config->restore_fields($data);
|
||||
|
||||
return $action->get_new_id();
|
||||
}
|
||||
|
||||
public function delete($id) {
|
||||
$action = new DataAction('deleted', $id, array());
|
||||
$request = new DataRequestConfig();
|
||||
$request->set_source($this->request->get_source());
|
||||
|
||||
$this->sql->delete($action,$request);
|
||||
return $action->get_status();
|
||||
}
|
||||
|
||||
public function update($data) {
|
||||
$action = new DataAction('updated', $data[$this->config->id["name"]], $data);
|
||||
$request = new DataRequestConfig();
|
||||
$request->set_source($this->request->get_source());
|
||||
|
||||
$this->config->limit_fields($data);
|
||||
$this->sql->update($action,$request);
|
||||
$this->config->restore_fields($data);
|
||||
|
||||
return $action->get_status();
|
||||
}
|
||||
|
||||
/*! sets actions_table for Optimistic concurrency control mode and start it
|
||||
@param table_name
|
||||
name of database table which will used for saving actions
|
||||
@param url
|
||||
url used for update notifications
|
||||
*/
|
||||
public function enable_live_update($table, $url=false){
|
||||
$this->live_update = new DataUpdate($this->sql, $this->config, $this->request, $table,$url);
|
||||
$this->live_update->set_event($this->event,$this->names["item_class"]);
|
||||
$this->event->attach("beforeOutput", Array($this->live_update, "version_output"));
|
||||
$this->event->attach("beforeFiltering", Array($this->live_update, "get_updates"));
|
||||
$this->event->attach("beforeProcessing", Array($this->live_update, "check_collision"));
|
||||
$this->event->attach("afterProcessing", Array($this->live_update, "log_operations"));
|
||||
}
|
||||
|
||||
/*! render() returns result as string or send to response
|
||||
*/
|
||||
public function asString($as_string) {
|
||||
$this->as_string = $as_string;
|
||||
}
|
||||
|
||||
public function simple_render() {
|
||||
$this->simple = true;
|
||||
return $this->render();
|
||||
}
|
||||
|
||||
public function filter($name, $value = false, $operation = '=') {
|
||||
$this->filters[] = array('name' => $name, 'value' => $value, 'operation' => $operation);
|
||||
}
|
||||
|
||||
public function clear_filter() {
|
||||
$this->filters = array();
|
||||
$this->request->set_filters(array());
|
||||
}
|
||||
|
||||
protected function apply_filters($wrap) {
|
||||
for ($i = 0; $i < count($this->filters); $i++) {
|
||||
$f = $this->filters[$i];
|
||||
$wrap->add($f['name'], $f['value'], $f['operation']);
|
||||
}
|
||||
}
|
||||
|
||||
public function sort($name, $direction = false) {
|
||||
$this->sorts[] = array('name' => $name, 'direction' => $direction);
|
||||
}
|
||||
|
||||
protected function apply_sorts($wrap) {
|
||||
for ($i = 0; $i < count($this->sorts); $i++) {
|
||||
$s = $this->sorts[$i];
|
||||
$wrap->add($s['name'], $s['direction']);
|
||||
}
|
||||
}
|
||||
|
||||
public function mix($name, $value, $filter=false) {
|
||||
$this->mix[] = Array('name'=>$name, 'value'=>$value, 'filter'=>$filter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! wrapper around options collection, used for comboboxes and filters
|
||||
**/
|
||||
class OptionsConnector extends Connector{
|
||||
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="DataItem";
|
||||
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 DistinctOptionsConnector extends OptionsConnector{
|
||||
/*! 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);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
18
libraries/dhtmlxgantt/connector/chart_connector.php
Normal file
18
libraries/dhtmlxgantt/connector/chart_connector.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
|
||||
require_once("dataview_connector.php");
|
||||
|
||||
|
||||
/*! Connector class for DataView
|
||||
**/
|
||||
class ChartConnector extends DataViewConnector{
|
||||
public function __construct($res,$type=false,$item_type=false,$data_type=false){
|
||||
parent::__construct($res,$type,$item_type,$data_type);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
94
libraries/dhtmlxgantt/connector/combo_connector.php
Normal file
94
libraries/dhtmlxgantt/connector/combo_connector.php
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
|
||||
require_once("base_connector.php");
|
||||
/*! DataItem class for Combo component
|
||||
**/
|
||||
class ComboDataItem extends DataItem{
|
||||
private $selected;//!< flag of selected option
|
||||
|
||||
function __construct($data,$config,$index){
|
||||
parent::__construct($data,$config,$index);
|
||||
|
||||
$this->selected=false;
|
||||
}
|
||||
/*! mark option as selected
|
||||
*/
|
||||
function select(){
|
||||
$this->selected=true;
|
||||
}
|
||||
/*! return self as XML string, starting part
|
||||
*/
|
||||
function to_xml_start(){
|
||||
if ($this->skip) return "";
|
||||
|
||||
return "<option ".($this->selected?"selected='true'":"")."value='".$this->xmlentities($this->get_id())."'><![CDATA[".$this->data[$this->config->text[0]["name"]]."]]>";
|
||||
}
|
||||
/*! return self as XML string, ending part
|
||||
*/
|
||||
function to_xml_end(){
|
||||
if ($this->skip) return "";
|
||||
return "</option>";
|
||||
}
|
||||
}
|
||||
|
||||
/*! Connector for the dhtmlxCombo
|
||||
**/
|
||||
class ComboConnector extends Connector{
|
||||
private $filter; //!< filtering mask from incoming request
|
||||
private $position; //!< position from incoming request
|
||||
|
||||
/*! 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){
|
||||
if (!$item_type) $item_type="ComboDataItem";
|
||||
parent::__construct($res,$type,$item_type,$data_type);
|
||||
}
|
||||
|
||||
//parse GET scoope, all operations with incoming request must be done here
|
||||
function parse_request(){
|
||||
parent::parse_request();
|
||||
|
||||
if (isset($_GET["pos"])){
|
||||
if (!$this->dload) //not critical, so just write a log message
|
||||
LogMaster::log("Dyn loading request received, but server side was not configured to process dyn. loading. ");
|
||||
else
|
||||
$this->request->set_limit($_GET["pos"],$this->dload);
|
||||
}
|
||||
|
||||
if (isset($_GET["mask"]))
|
||||
$this->request->set_filter($this->config->text[0]["db_name"],$_GET["mask"]."%","LIKE");
|
||||
|
||||
LogMaster::log($this->request);
|
||||
}
|
||||
|
||||
|
||||
/*! renders self as xml, starting part
|
||||
*/
|
||||
public function xml_start(){
|
||||
if ($this->request->get_start())
|
||||
return "<complete add='true'>";
|
||||
else
|
||||
return "<complete>";
|
||||
}
|
||||
|
||||
/*! renders self as xml, ending part
|
||||
*/
|
||||
public function xml_end(){
|
||||
return "</complete>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
69
libraries/dhtmlxgantt/connector/convert.php
Normal file
69
libraries/dhtmlxgantt/connector/convert.php
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
class ConvertService{
|
||||
private $url;
|
||||
private $type;
|
||||
private $name;
|
||||
private $inline;
|
||||
|
||||
public function __construct($url){
|
||||
$this->url = $url;
|
||||
$this->pdf();
|
||||
EventMaster::attach_static("connectorInit",array($this, "handle"));
|
||||
}
|
||||
public function pdf($name = "data.pdf", $inline = false){
|
||||
$this->type = "pdf";
|
||||
$this->name = $name;
|
||||
$this->inline = $inline;
|
||||
}
|
||||
public function excel($name = "data.xls", $inline = false){
|
||||
$this->type = "excel";
|
||||
$this->name = $name;
|
||||
$this->inline = $inline;
|
||||
}
|
||||
public function handle($conn){
|
||||
$conn->event->attach("beforeOutput",array($this,"convert"));
|
||||
}
|
||||
private function as_file($size, $name, $inline){
|
||||
header('Content-Type: application/force-download');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Type: application/download');
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
|
||||
header('Content-Length: '.$size);
|
||||
if ($inline)
|
||||
header('Content-Disposition: inline; filename="'.$name.'";');
|
||||
else
|
||||
header('Content-Disposition: attachment; filename="'.basename($name).'";');
|
||||
}
|
||||
public function convert($conn, $out){
|
||||
|
||||
$str_out = str_replace("<rows>","<rows profile='color'>", $out);
|
||||
$str_out = str_replace("<head>","<head><columns>", $str_out);
|
||||
$str_out = str_replace("</head>","</columns></head>", $str_out);
|
||||
|
||||
if ($this->type == "pdf")
|
||||
header("Content-type: application/pdf");
|
||||
else
|
||||
header("Content-type: application/ms-excel");
|
||||
|
||||
$handle = curl_init($this->url);
|
||||
curl_setopt($handle, CURLOPT_POST, true);
|
||||
curl_setopt($handle, CURLOPT_HEADER, false);
|
||||
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($handle, CURLOPT_POSTFIELDS, "grid_xml=".urlencode($str_out));
|
||||
|
||||
|
||||
$out->reset();
|
||||
$out->set_type("pdf");
|
||||
$out->add(curl_exec($handle));
|
||||
$this->as_file(strlen((string)$out), $this->name, $this->inline);
|
||||
|
||||
curl_close($handle);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
141
libraries/dhtmlxgantt/connector/crosslink_connector.php
Normal file
141
libraries/dhtmlxgantt/connector/crosslink_connector.php
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("data_connector.php");
|
||||
|
||||
class DelayedConnector extends Connector{
|
||||
protected $init_flag=false;//!< used to prevent rendering while initialization
|
||||
private $data_mode=false;//!< flag to separate xml and data request modes
|
||||
private $data_result=false;//<! store results of query
|
||||
|
||||
public function dataMode($name){
|
||||
$this->data_mode = $name;
|
||||
$this->data_result=array();
|
||||
}
|
||||
public function getDataResult(){
|
||||
return $this->data_result;
|
||||
}
|
||||
|
||||
public function render(){
|
||||
if (!$this->init_flag){
|
||||
$this->init_flag=true;
|
||||
return "";
|
||||
}
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
protected function output_as_xml($res){
|
||||
if ($this->data_mode){
|
||||
while ($data=$this->sql->get_next($res)){
|
||||
$this->data_result[]=$data[$this->data_mode];
|
||||
}
|
||||
}
|
||||
else
|
||||
return parent::output_as_xml($res);
|
||||
}
|
||||
protected function end_run(){
|
||||
if (!$this->data_mode)
|
||||
parent::end_run();
|
||||
}
|
||||
}
|
||||
|
||||
class CrossOptionsConnector extends Connector{
|
||||
public $options, $link;
|
||||
private $master_name, $link_name, $master_value;
|
||||
|
||||
public function __construct($res,$type=false,$item_type=false,$data_type=false){
|
||||
$this->options = new OptionsConnector($res,$type,$item_type,$data_type);
|
||||
$this->link = new DelayedConnector($res,$type,$item_type,$data_type);
|
||||
|
||||
EventMaster::attach_static("connectorInit",array($this, "handle"));
|
||||
}
|
||||
public function handle($conn){
|
||||
if ($conn instanceof DelayedConnector) return;
|
||||
if ($conn instanceof OptionsConnector) return;
|
||||
|
||||
$this->master_name = $this->link->get_config()->id["db_name"];
|
||||
$this->link_name = $this->options->get_config()->id["db_name"];
|
||||
|
||||
$this->link->event->attach("beforeFilter",array($this, "get_only_related"));
|
||||
|
||||
if (isset($_GET["dhx_crosslink_".$this->link_name])){
|
||||
$this->get_links($_GET["dhx_crosslink_".$this->link_name]);
|
||||
die();
|
||||
}
|
||||
|
||||
if (!$this->dload){
|
||||
$conn->event->attach("beforeRender", array($this, "getOptions"));
|
||||
$conn->event->attach("beforeRenderSet", array($this, "prepareConfig"));
|
||||
}
|
||||
|
||||
|
||||
$conn->event->attach("afterProcessing", array($this, "afterProcessing"));
|
||||
}
|
||||
public function prepareConfig($conn, $res, $config){
|
||||
$config->add_field($this->link_name);
|
||||
}
|
||||
public function getOptions($data){
|
||||
$this->link->dataMode($this->link_name);
|
||||
|
||||
$this->get_links($data->get_value($this->master_name));
|
||||
|
||||
$data->set_value($this->link_name, implode(",",$this->link->getDataResult()));
|
||||
}
|
||||
public function get_links($id){
|
||||
$this->master_value = $id;
|
||||
$this->link->render();
|
||||
}
|
||||
public function get_only_related($filters){
|
||||
$index = $filters->index($this->master_name);
|
||||
if ($index!==false){
|
||||
$filters->rules[$index]["value"]=$this->master_value;
|
||||
} else
|
||||
$filters->add($this->master_name, $this->master_value, "=");
|
||||
}
|
||||
public function afterProcessing($action){
|
||||
$status = $action->get_status();
|
||||
|
||||
$master_key = $action->get_id();//value($this->master_name);
|
||||
$link_key = $action->get_value($this->link_name);
|
||||
$link_key = explode(',', $link_key);
|
||||
|
||||
if ($status == "inserted")
|
||||
$master_key = $action->get_new_id();
|
||||
|
||||
switch ($status){
|
||||
case "deleted":
|
||||
$this->link->delete($master_key);
|
||||
break;
|
||||
case "updated":
|
||||
//cross link options not loaded yet, so we can skip update
|
||||
if (!array_key_exists($this->link_name, $action->get_data()))
|
||||
break;
|
||||
//else, delete old options and continue in insert section to add new values
|
||||
$this->link->delete($master_key);
|
||||
case "inserted":
|
||||
for ($i=0; $i < sizeof($link_key); $i++)
|
||||
if ($link_key[$i]!="")
|
||||
$this->link->insert(array(
|
||||
$this->link_name => $link_key[$i],
|
||||
$this->master_name => $master_key
|
||||
));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class JSONCrossOptionsConnector extends CrossOptionsConnector{
|
||||
public $options, $link;
|
||||
private $master_name, $link_name, $master_value;
|
||||
|
||||
public function __construct($res,$type=false,$item_type=false,$data_type=false){
|
||||
$this->options = new JSONOptionsConnector($res,$type,$item_type,$data_type);
|
||||
$this->link = new DelayedConnector($res,$type,$item_type,$data_type);
|
||||
|
||||
EventMaster::attach_static("connectorInit",array($this, "handle"));
|
||||
}
|
||||
}
|
||||
?>
|
||||
528
libraries/dhtmlxgantt/connector/data_connector.php
Normal file
528
libraries/dhtmlxgantt/connector/data_connector.php
Normal file
|
|
@ -0,0 +1,528 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("base_connector.php");
|
||||
|
||||
class CommonDataProcessor extends DataProcessor{
|
||||
protected function get_post_values($ids){
|
||||
if (isset($_GET['action'])){
|
||||
$data = array();
|
||||
if (isset($_POST["id"])){
|
||||
$dataset = array();
|
||||
foreach($_POST as $key=>$value)
|
||||
$dataset[$key] = ConnectorSecurity::filter($value);
|
||||
|
||||
$data[$_POST["id"]] = $dataset;
|
||||
}
|
||||
else
|
||||
$data["dummy_id"] = $_POST;
|
||||
return $data;
|
||||
}
|
||||
return parent::get_post_values($ids);
|
||||
}
|
||||
|
||||
protected function get_ids(){
|
||||
if (isset($_GET['action'])){
|
||||
if (isset($_POST["id"]))
|
||||
return array($_POST['id']);
|
||||
else
|
||||
return array("dummy_id");
|
||||
}
|
||||
return parent::get_ids();
|
||||
}
|
||||
|
||||
protected function get_operation($rid){
|
||||
if (isset($_GET['action']))
|
||||
return $_GET['action'];
|
||||
return parent::get_operation($rid);
|
||||
}
|
||||
|
||||
public function output_as_xml($results){
|
||||
if (isset($_GET['action'])){
|
||||
LogMaster::log("Edit operation finished",$results);
|
||||
ob_clean();
|
||||
$type = $results[0]->get_status();
|
||||
if ($type == "error" || $type == "invalid"){
|
||||
echo "false";
|
||||
} else if ($type=="insert"){
|
||||
echo "true\n".$results[0]->get_new_id();
|
||||
} else
|
||||
echo "true";
|
||||
} else
|
||||
return parent::output_as_xml($results);
|
||||
}
|
||||
};
|
||||
|
||||
/*! DataItem class for DataView component
|
||||
**/
|
||||
class CommonDataItem extends DataItem{
|
||||
/*! return self as XML string
|
||||
*/
|
||||
function to_xml(){
|
||||
if ($this->skip) return "";
|
||||
return $this->to_xml_start().$this->to_xml_end();
|
||||
}
|
||||
|
||||
function to_xml_start(){
|
||||
$str="<item id='".$this->get_id()."' ";
|
||||
for ($i=0; $i < sizeof($this->config->text); $i++){
|
||||
$name=$this->config->text[$i]["name"];
|
||||
$str.=" ".$name."='".$this->xmlentities($this->data[$name])."'";
|
||||
}
|
||||
|
||||
if ($this->userdata !== false)
|
||||
foreach ($this->userdata as $key => $value)
|
||||
$str.=" ".$key."='".$this->xmlentities($value)."'";
|
||||
|
||||
return $str.">";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Connector class for DataView
|
||||
**/
|
||||
class DataConnector extends Connector{
|
||||
|
||||
/*! 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="CommonDataItem";
|
||||
if (!$data_type) $data_type="CommonDataProcessor";
|
||||
|
||||
$this->sections = array();
|
||||
|
||||
if (!$render_type) $render_type="RenderStrategy";
|
||||
parent::__construct($res,$type,$item_type,$data_type,$render_type);
|
||||
|
||||
}
|
||||
|
||||
protected $sections;
|
||||
public function add_section($name, $string){
|
||||
$this->sections[$name] = $string;
|
||||
}
|
||||
|
||||
protected function parse_request_mode(){
|
||||
if (isset($_GET['action']) && $_GET["action"] != "get")
|
||||
$this->editing = true;
|
||||
else
|
||||
parent::parse_request_mode();
|
||||
}
|
||||
|
||||
//parse GET scoope, all operations with incoming request must be done here
|
||||
protected function parse_request(){
|
||||
if (isset($_GET['action'])){
|
||||
$action = $_GET['action'];
|
||||
//simple request mode
|
||||
if ($action == "get"){
|
||||
//data request
|
||||
if (isset($_GET['id'])){
|
||||
//single entity data request
|
||||
$this->request->set_filter($this->config->id["name"],$_GET['id'],"=");
|
||||
} else {
|
||||
//loading collection of items
|
||||
}
|
||||
} else {
|
||||
//data saving
|
||||
$this->editing = true;
|
||||
}
|
||||
parent::check_csrf();
|
||||
} else {
|
||||
if (isset($_GET['editing']) && isset($_POST['ids']))
|
||||
$this->editing = true;
|
||||
parent::parse_request();
|
||||
}
|
||||
|
||||
if (isset($_GET["start"]) && isset($_GET["count"]))
|
||||
$this->request->set_limit($_GET["start"],$_GET["count"]);
|
||||
|
||||
}
|
||||
|
||||
/*! renders self as xml, starting part
|
||||
*/
|
||||
protected function xml_start(){
|
||||
$start = "<data";
|
||||
foreach($this->attributes as $k=>$v)
|
||||
$start .= " ".$k."='".$v."'";
|
||||
$start.= ">";
|
||||
|
||||
foreach($this->sections as $k=>$v)
|
||||
$start .= "<".$k.">".$v."</".$k.">\n";
|
||||
return $start;
|
||||
}
|
||||
};
|
||||
|
||||
class JSONDataConnector extends DataConnector{
|
||||
|
||||
public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
|
||||
if (!$item_type) $item_type="JSONCommonDataItem";
|
||||
if (!$data_type) $data_type="CommonDataProcessor";
|
||||
if (!$render_type) $render_type="JSONRenderStrategy";
|
||||
$this->data_separator = ",\n";
|
||||
parent::__construct($res,$type,$item_type,$data_type,$render_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;
|
||||
}
|
||||
|
||||
/*! generates xml description for options collections
|
||||
|
||||
@param list
|
||||
comma separated list of column names, for which options need to be generated
|
||||
*/
|
||||
protected function fill_collections($list=""){
|
||||
$options = array();
|
||||
foreach ($this->options as $k=>$v) {
|
||||
$name = $k;
|
||||
$option="\"{$name}\":[";
|
||||
if (!is_string($this->options[$name]))
|
||||
$option.=substr(json_encode($this->options[$name]->render()),1,-1);
|
||||
else
|
||||
$option.=$this->options[$name];
|
||||
$option.="]";
|
||||
$options[] = $option;
|
||||
}
|
||||
$this->extra_output .= implode($this->data_separator, $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){
|
||||
$json = $this->render_set($res);
|
||||
if ($this->simple) return $json;
|
||||
$result = json_encode($json);
|
||||
|
||||
$this->fill_collections();
|
||||
$is_sections = sizeof($this->sections) && $this->is_first_call();
|
||||
if ($this->dload || $is_sections || sizeof($this->attributes) || !empty($this->extra_data)){
|
||||
|
||||
$attributes = "";
|
||||
foreach($this->attributes as $k=>$v)
|
||||
$attributes .= ", \"".$k."\":\"".$v."\"";
|
||||
|
||||
$extra = "";
|
||||
if (!empty($this->extra_output))
|
||||
$extra .= ', "collections": {'.$this->extra_output.'}';
|
||||
|
||||
$sections = "";
|
||||
if ($is_sections){
|
||||
//extra sections
|
||||
foreach($this->sections as $k=>$v)
|
||||
$sections .= ", \"".$k."\":".$v;
|
||||
}
|
||||
|
||||
$dyn = "";
|
||||
if ($this->dload){
|
||||
//info for dyn. loadin
|
||||
if ($pos=$this->request->get_start())
|
||||
$dyn .= ", \"pos\":".$pos;
|
||||
else
|
||||
$dyn .= ", \"pos\":0, \"total_count\":".$this->sql->get_size($this->request);
|
||||
}
|
||||
if ($attributes || $sections || $this->extra_output || $dyn) {
|
||||
$result = "{ \"data\":".$result.$attributes.$extra.$sections.$dyn."}";
|
||||
}
|
||||
}
|
||||
|
||||
// return as string
|
||||
if ($this->as_string) return $result;
|
||||
|
||||
// output direct to response
|
||||
$out = new OutputWriter($result, "");
|
||||
$out->set_type("json");
|
||||
$this->event->trigger("beforeOutput", $this, $out);
|
||||
$out->output("", true, $this->encoding);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class JSONCommonDataItem extends DataItem{
|
||||
/*! return self as XML string
|
||||
*/
|
||||
function to_xml(){
|
||||
if ($this->skip) return false;
|
||||
|
||||
$data = array(
|
||||
'id' => $this->get_id()
|
||||
);
|
||||
for ($i=0; $i<sizeof($this->config->text); $i++){
|
||||
$extra = $this->config->text[$i]["name"];
|
||||
$data[$extra]=$this->data[$extra];
|
||||
if (is_null($data[$extra]))
|
||||
$data[$extra] = "";
|
||||
}
|
||||
|
||||
if ($this->userdata !== false)
|
||||
foreach ($this->userdata as $key => $value){
|
||||
if ($value === null)
|
||||
$data[$key]="";
|
||||
$data[$key]=$value;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! 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;
|
||||
|
||||
function to_xml_start(){
|
||||
$str="<item id='".$this->get_id()."' ";
|
||||
for ($i=0; $i < sizeof($this->config->text); $i++){
|
||||
$name=$this->config->text[$i]["name"];
|
||||
$str.=" ".$name."='".$this->xmlentities($this->data[$name])."'";
|
||||
}
|
||||
|
||||
if ($this->userdata !== false)
|
||||
foreach ($this->userdata as $key => $value)
|
||||
$str.=" ".$key."='".$this->xmlentities($value)."'";
|
||||
|
||||
if ($this->kids === true)
|
||||
$str .=" ".Connector::$kids_var."='1'";
|
||||
|
||||
return $str.">";
|
||||
}
|
||||
|
||||
function has_kids(){
|
||||
return $this->kids;
|
||||
}
|
||||
|
||||
function set_kids($value){
|
||||
$this->kids=$value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class TreeDataConnector extends DataConnector{
|
||||
protected $parent_name = 'parent';
|
||||
public $rootId = "0";
|
||||
|
||||
/*! 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="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[$this->parent_name]))
|
||||
$this->request->set_relation($_GET[$this->parent_name]);
|
||||
else
|
||||
$this->request->set_relation($this->rootId);
|
||||
|
||||
$this->request->set_limit(0,0); //netralize default reaction on dyn. loading mode
|
||||
}
|
||||
|
||||
/*! renders self as xml, starting part
|
||||
*/
|
||||
protected function xml_start(){
|
||||
$attributes = " ";
|
||||
if (!$this->rootId || $this->rootId != $this->request->get_relation())
|
||||
$attributes = " parent='".$this->request->get_relation()."' ";
|
||||
|
||||
foreach($this->attributes as $k=>$v)
|
||||
$attributes .= " ".$k."='".$v."'";
|
||||
|
||||
return "<data".$attributes.">";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class JSONTreeDataConnector extends TreeDataConnector{
|
||||
|
||||
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";
|
||||
if (!$render_type) $render_type="JSONTreeRenderStrategy";
|
||||
parent::__construct($res,$type,$item_type,$data_type,$render_type);
|
||||
}
|
||||
|
||||
protected function output_as_xml($res){
|
||||
$result = $this->render_set($res);
|
||||
if ($this->simple) return $result;
|
||||
|
||||
$data = array();
|
||||
if (!$this->rootId || $this->rootId != $this->request->get_relation())
|
||||
$data["parent"] = $this->request->get_relation();
|
||||
|
||||
$data["data"] = $result;
|
||||
|
||||
$this->fill_collections();
|
||||
if (!empty($this->options))
|
||||
$data["collections"] = $this->options;
|
||||
|
||||
|
||||
foreach($this->attributes as $k=>$v)
|
||||
$data[$k] = $v;
|
||||
|
||||
$data = json_encode($data);
|
||||
|
||||
// return as string
|
||||
if ($this->as_string) return $data;
|
||||
|
||||
// output direct to response
|
||||
$out = new OutputWriter($data, "");
|
||||
$out->set_type("json");
|
||||
$this->event->trigger("beforeOutput", $this, $out);
|
||||
$out->output("", true, $this->encoding);
|
||||
}
|
||||
|
||||
/*! 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[]=Array("id"=>$this->xmlentities($k), "value"=>$this->xmlentities($v));//'{"id":"'.$this->xmlentities($k).'", "value":"'.$this->xmlentities($v).'"}';
|
||||
$options=$str;
|
||||
}
|
||||
$this->options[$name]=$options;
|
||||
}
|
||||
|
||||
/*! generates xml description for options collections
|
||||
|
||||
@param list
|
||||
comma separated list of column names, for which options need to be generated
|
||||
*/
|
||||
protected function fill_collections($list=""){
|
||||
$options = array();
|
||||
foreach ($this->options as $k=>$v) {
|
||||
$name = $k;
|
||||
if (!is_array($this->options[$name]))
|
||||
$option=$this->options[$name]->render();
|
||||
else
|
||||
$option=$this->options[$name];
|
||||
$options[$name] = $option;
|
||||
}
|
||||
$this->options = $options;
|
||||
$this->extra_output .= "'collections':".json_encode($options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class JSONTreeCommonDataItem extends TreeCommonDataItem{
|
||||
/*! return self as XML string
|
||||
*/
|
||||
function to_xml_start(){
|
||||
if ($this->skip) return false;
|
||||
|
||||
$data = array( "id" => $this->get_id() );
|
||||
for ($i=0; $i<sizeof($this->config->text); $i++){
|
||||
$extra = $this->config->text[$i]["name"];
|
||||
if (isset($this->data[$extra]))
|
||||
$data[$extra]=$this->data[$extra];
|
||||
}
|
||||
|
||||
if ($this->userdata !== false)
|
||||
foreach ($this->userdata as $key => $value)
|
||||
$data[$key]=$value;
|
||||
|
||||
if ($this->kids === true)
|
||||
$data[Connector::$kids_var] = 1;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
function to_xml_end(){
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
521
libraries/dhtmlxgantt/connector/dataprocessor.php
Normal file
521
libraries/dhtmlxgantt/connector/dataprocessor.php
Normal file
|
|
@ -0,0 +1,521 @@
|
|||
<?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: {$mode} operation blocked");
|
||||
$action->error();
|
||||
} else {
|
||||
$check = $this->connector->event->trigger("beforeProcessing",$action);
|
||||
if (!$action->is_ready())
|
||||
$this->check_exts($action,$mode);
|
||||
if ($mode == "insert" && $action->get_status() != "error" && $action->get_status() != "invalid")
|
||||
$this->connector->sql->new_record_order($action, $this->request);
|
||||
|
||||
$check = $this->connector->event->trigger("afterProcessing",$action);
|
||||
}
|
||||
|
||||
} catch (Exception $e){
|
||||
LogMaster::log($e);
|
||||
$action->set_status("error");
|
||||
if ($action)
|
||||
$this->connector->event->trigger("onDBError", $action, $e);
|
||||
}
|
||||
|
||||
if ($this->connector->sql->is_record_transaction()){
|
||||
if ($action->get_status()=="error" || $action->get_status()=="invalid")
|
||||
$this->connector->sql->rollback_transaction();
|
||||
else
|
||||
$this->connector->sql->commit_transaction();
|
||||
}
|
||||
|
||||
return $action;
|
||||
}
|
||||
|
||||
/*! check if some event intercepts processing, send data to DataWrapper in other case
|
||||
|
||||
@param action
|
||||
DataAction object
|
||||
@param mode
|
||||
name of inner mode ( will be used to generate event names )
|
||||
*/
|
||||
function check_exts($action,$mode){
|
||||
$old_config = new DataConfig($this->config);
|
||||
|
||||
$this->connector->event->trigger("before".$mode,$action);
|
||||
if ($action->is_ready())
|
||||
LogMaster::log("Event code for ".$mode." processed");
|
||||
else {
|
||||
//check if custom sql defined
|
||||
$sql = $this->connector->sql->get_sql($mode,$action);
|
||||
if ($sql){
|
||||
$this->connector->sql->query($sql);
|
||||
}
|
||||
else{
|
||||
$action->sync_config($this->config);
|
||||
if ($this->connector->model && method_exists($this->connector->model, $mode)){
|
||||
call_user_func(array($this->connector->model, $mode), $action);
|
||||
LogMaster::log("Model object process action: ".$mode);
|
||||
}
|
||||
if (!$action->is_ready()){
|
||||
$method=array($this->connector->sql,$mode);
|
||||
if (!is_callable($method))
|
||||
throw new Exception("Unknown dataprocessing action: ".$mode);
|
||||
call_user_func($method,$action,$this->request);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->connector->event->trigger("after".$mode,$action);
|
||||
|
||||
$this->config->copy($old_config);
|
||||
}
|
||||
|
||||
/*! output xml response for dataprocessor
|
||||
|
||||
@param results
|
||||
array of DataAction objects
|
||||
*/
|
||||
function output_as_xml($results){
|
||||
LogMaster::log("Edit operation finished",$results);
|
||||
ob_clean();
|
||||
header("Content-type:text/xml");
|
||||
echo "<?xml version='1.0' ?>";
|
||||
echo "<data>";
|
||||
for ($i=0; $i < sizeof($results); $i++)
|
||||
echo $results[$i]->to_xml();
|
||||
echo "</data>";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*! 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."='".$this->xmlentities($v)."' ";
|
||||
}
|
||||
$str.=">{$this->output}</action>";
|
||||
return $str;
|
||||
}
|
||||
|
||||
/*! replace xml unsafe characters
|
||||
|
||||
@param string
|
||||
string to be escaped
|
||||
@return
|
||||
escaped string
|
||||
*/
|
||||
public function xmlentities($string) {
|
||||
return str_replace( array( '&', '"', "'", '<', '>', '’' ), array( '&' , '"', ''' , '<' , '>', ''' ), $string);
|
||||
}
|
||||
|
||||
/*! convert self to string ( for logs )
|
||||
|
||||
@return
|
||||
DataAction operation report as plain string
|
||||
*/
|
||||
function __toString(){
|
||||
return "action:{$this->status}; sid:{$this->id}; tid:{$this->nid};";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
73
libraries/dhtmlxgantt/connector/dataview_connector.php
Normal file
73
libraries/dhtmlxgantt/connector/dataview_connector.php
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("base_connector.php");
|
||||
|
||||
/*! DataItem class for DataView component
|
||||
**/
|
||||
class DataViewDataItem extends DataItem{
|
||||
/*! return self as XML string
|
||||
*/
|
||||
function to_xml(){
|
||||
if ($this->skip) return "";
|
||||
|
||||
$str="<item id='".$this->get_id()."' >";
|
||||
for ($i=0; $i<sizeof($this->config->text); $i++){
|
||||
$extra = $this->config->text[$i]["name"];
|
||||
$str.="<".$extra."><![CDATA[".$this->data[$extra]."]]></".$extra.">";
|
||||
}
|
||||
return $str."</item>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Connector class for DataView
|
||||
**/
|
||||
class DataViewConnector extends Connector{
|
||||
|
||||
/*! 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){
|
||||
if (!$item_type) $item_type="DataViewDataItem";
|
||||
if (!$data_type) $data_type="DataProcessor";
|
||||
parent::__construct($res,$type,$item_type,$data_type);
|
||||
}
|
||||
|
||||
//parse GET scoope, all operations with incoming request must be done here
|
||||
function parse_request(){
|
||||
parent::parse_request();
|
||||
|
||||
if (isset($_GET["posStart"]) && isset($_GET["count"]))
|
||||
$this->request->set_limit($_GET["posStart"],$_GET["count"]);
|
||||
}
|
||||
|
||||
/*! renders self as xml, starting part
|
||||
*/
|
||||
protected function xml_start(){
|
||||
$attributes = "";
|
||||
foreach($this->attributes as $k=>$v)
|
||||
$attributes .= " ".$k."='".$v."'";
|
||||
|
||||
if ($this->dload){
|
||||
if ($pos=$this->request->get_start())
|
||||
return "<data pos='".$pos."'".$attributes.">";
|
||||
else
|
||||
return "<data total_count='".$this->sql->get_size($this->request)."'".$attributes.">";
|
||||
}
|
||||
else
|
||||
return "<data".$attributes.">";
|
||||
}
|
||||
}
|
||||
?>
|
||||
72
libraries/dhtmlxgantt/connector/db_adodb.php
Normal file
72
libraries/dhtmlxgantt/connector/db_adodb.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("db_common.php");
|
||||
/*! Implementation of DataWrapper for PostgreSQL
|
||||
**/
|
||||
class AdoDBDataWrapper extends DBDataWrapper{
|
||||
protected $last_result;
|
||||
public function query($sql){
|
||||
LogMaster::log($sql);
|
||||
if (is_array($sql)) {
|
||||
$res = $this->connection->SelectLimit($sql['sql'], $sql['numrows'], $sql['offset']);
|
||||
} else {
|
||||
$res = $this->connection->Execute($sql);
|
||||
}
|
||||
|
||||
if ($res===false) throw new Exception("ADODB operation failed\n".$this->connection->ErrorMsg());
|
||||
$this->last_result = $res;
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function get_next($res){
|
||||
if (!$res)
|
||||
$res = $this->last_result;
|
||||
|
||||
if ($res->EOF)
|
||||
return false;
|
||||
|
||||
$row = $res->GetRowAssoc(false);
|
||||
$res->MoveNext();
|
||||
return $row;
|
||||
}
|
||||
|
||||
protected function get_new_id(){
|
||||
return $this->connection->Insert_ID();
|
||||
}
|
||||
|
||||
public function escape($data){
|
||||
return $this->connection->addq($data);
|
||||
}
|
||||
|
||||
/*! escape field name to prevent sql reserved words conflict
|
||||
@param data
|
||||
unescaped data
|
||||
@return
|
||||
escaped data
|
||||
*/
|
||||
public function escape_name($data){
|
||||
if ((strpos($data,"`")!==false || is_int($data)) || (strpos($data,".")!==false))
|
||||
return $data;
|
||||
return '`'.$data.'`';
|
||||
}
|
||||
|
||||
|
||||
protected function select_query($select,$from,$where,$sort,$start,$count){
|
||||
if (!$from)
|
||||
return $select;
|
||||
|
||||
$sql="SELECT ".$select." FROM ".$from;
|
||||
if ($where) $sql.=" WHERE ".$where;
|
||||
if ($sort) $sql.=" ORDER BY ".$sort;
|
||||
|
||||
if ($start || $count) {
|
||||
$sql=array("sql"=>$sql,'numrows'=>$count, 'offset'=>$start);
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
1149
libraries/dhtmlxgantt/connector/db_common.php
Normal file
1149
libraries/dhtmlxgantt/connector/db_common.php
Normal file
File diff suppressed because it is too large
Load diff
190
libraries/dhtmlxgantt/connector/db_excel.php
Normal file
190
libraries/dhtmlxgantt/connector/db_excel.php
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once('db_common.php');
|
||||
|
||||
if (!defined('DHX_IGNORE_EMPTY_ROWS')) {
|
||||
define('DHX_IGNORE_EMPTY_ROWS', true);
|
||||
}
|
||||
|
||||
class ExcelDBDataWrapper extends DBDataWrapper {
|
||||
|
||||
public $emptyLimit = 10;
|
||||
public function excel_data($points){
|
||||
$path = $this->connection;
|
||||
$excel = PHPExcel_IOFactory::createReaderForFile($path);
|
||||
$excel = $excel->load($path);
|
||||
$result = array();
|
||||
$excelWS = $excel->getActiveSheet();
|
||||
|
||||
for ($i=0; $i < sizeof($points); $i++) {
|
||||
$c = array();
|
||||
preg_match("/^([a-zA-Z]+)(\d+)/", $points[$i], $c);
|
||||
if (count($c) > 0) {
|
||||
$col = PHPExcel_Cell::columnIndexFromString($c[1]) - 1;
|
||||
$cell = $excelWS->getCellByColumnAndRow($col, (int)$c[2]);
|
||||
$result[] = $cell->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
public function select($source) {
|
||||
$path = $this->connection;
|
||||
$excel = PHPExcel_IOFactory::createReaderForFile($path);
|
||||
$excel->setReadDataOnly(false);
|
||||
$excel = $excel->load($path);
|
||||
$excRes = new ExcelResult();
|
||||
$excelWS = $excel->getActiveSheet();
|
||||
$addFields = true;
|
||||
|
||||
$coords = array();
|
||||
if ($source->get_source() == '*') {
|
||||
$coords['start_row'] = 0;
|
||||
$coords['end_row'] = false;
|
||||
} else {
|
||||
$c = array();
|
||||
preg_match("/^([a-zA-Z]+)(\d+)/", $source->get_source(), $c);
|
||||
if (count($c) > 0) {
|
||||
$coords['start_row'] = (int) $c[2];
|
||||
} else {
|
||||
$coords['start_row'] = 0;
|
||||
}
|
||||
$c = array();
|
||||
preg_match("/:(.+)(\d+)$/U", $source->get_source(), $c);
|
||||
if (count($c) > 0) {
|
||||
$coords['end_row'] = (int) $c[2];
|
||||
} else {
|
||||
$coords['end_row'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
$i = $coords['start_row'];
|
||||
$end = 0;
|
||||
while ((($coords['end_row'] == false)&&($end < $this->emptyLimit))||(($coords['end_row'] !== false)&&($i < $coords['end_row']))) {
|
||||
$r = Array();
|
||||
$emptyNum = 0;
|
||||
for ($j = 0; $j < count($this->config->text); $j++) {
|
||||
$col = PHPExcel_Cell::columnIndexFromString($this->config->text[$j]['name']) - 1;
|
||||
$cell = $excelWS->getCellByColumnAndRow($col, $i);
|
||||
if (PHPExcel_Shared_Date::isDateTime($cell)) {
|
||||
$r[PHPExcel_Cell::stringFromColumnIndex($col)] = PHPExcel_Shared_Date::ExcelToPHP($cell->getValue());
|
||||
} else if ($cell->getDataType() == 'f') {
|
||||
$r[PHPExcel_Cell::stringFromColumnIndex($col)] = $cell->getCalculatedValue();
|
||||
} else {
|
||||
$r[PHPExcel_Cell::stringFromColumnIndex($col)] = $cell->getValue();
|
||||
}
|
||||
if ($r[PHPExcel_Cell::stringFromColumnIndex($col)] == '') {
|
||||
$emptyNum++;
|
||||
}
|
||||
}
|
||||
if ($emptyNum < count($this->config->text)) {
|
||||
$r['id'] = $i;
|
||||
$excRes->addRecord($r);
|
||||
$end = 0;
|
||||
} else {
|
||||
if (DHX_IGNORE_EMPTY_ROWS == false) {
|
||||
$r['id'] = $i;
|
||||
$excRes->addRecord($r);
|
||||
}
|
||||
$end++;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
return $excRes;
|
||||
}
|
||||
|
||||
public function query($sql) {
|
||||
}
|
||||
|
||||
public function get_new_id() {
|
||||
}
|
||||
|
||||
public function escape($data) {
|
||||
}
|
||||
|
||||
public function get_next($res) {
|
||||
return $res->next();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class ExcelResult {
|
||||
private $rows;
|
||||
private $currentRecord = 0;
|
||||
|
||||
|
||||
// add record to output list
|
||||
public function addRecord($file) {
|
||||
$this->rows[] = $file;
|
||||
}
|
||||
|
||||
|
||||
// return next record
|
||||
public function next() {
|
||||
if ($this->currentRecord < count($this->rows)) {
|
||||
$row = $this->rows[$this->currentRecord];
|
||||
$this->currentRecord++;
|
||||
return $row;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sorts records under $sort array
|
||||
public function sort($sort, $data) {
|
||||
if (count($this->files) == 0) {
|
||||
return $this;
|
||||
}
|
||||
// defines fields list if it's need
|
||||
for ($i = 0; $i < count($sort); $i++) {
|
||||
$fieldname = $sort[$i]['name'];
|
||||
if (!isset($this->files[0][$fieldname])) {
|
||||
if (isset($data[$fieldname])) {
|
||||
$fieldname = $data[$fieldname]['db_name'];
|
||||
$sort[$i]['name'] = $fieldname;
|
||||
} else {
|
||||
$fieldname = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for every sorting field will sort
|
||||
for ($i = 0; $i < count($sort); $i++) {
|
||||
// if field, setted in sort parameter doesn't exist, continue
|
||||
if ($sort[$i]['name'] == false) {
|
||||
continue;
|
||||
}
|
||||
// sorting by current field
|
||||
$flag = true;
|
||||
while ($flag == true) {
|
||||
$flag = false;
|
||||
// checks if previous sorting fields are equal
|
||||
for ($j = 0; $j < count($this->files) - 1; $j++) {
|
||||
$equal = true;
|
||||
for ($k = 0; $k < $i; $k++) {
|
||||
if ($this->files[$j][$sort[$k]['name']] != $this->files[$j + 1][$sort[$k]['name']]) {
|
||||
$equal = false;
|
||||
}
|
||||
}
|
||||
// compares two records in list under current sorting field and sorting direction
|
||||
if (((($this->files[$j][$sort[$i]['name']] > $this->files[$j + 1][$sort[$i]['name']])&&($sort[$i]['direction'] == 'ASC'))||(($this->files[$j][$sort[$i]['name']] < $this->files[$j + 1][$sort[$i]['name']])&&($sort[$i]['direction'] == 'DESC')))&&($equal == true)) {
|
||||
$c = $this->files[$j];
|
||||
$this->files[$j] = $this->files[$j+1];
|
||||
$this->files[$j+1] = $c;
|
||||
$flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
345
libraries/dhtmlxgantt/connector/db_filesystem.php
Normal file
345
libraries/dhtmlxgantt/connector/db_filesystem.php
Normal file
|
|
@ -0,0 +1,345 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once('db_common.php');
|
||||
require_once('tree_connector.php');
|
||||
|
||||
/*
|
||||
Most execution time is a standart functions for workin with FileSystem: is_dir(), dir(), readdir(), stat()
|
||||
*/
|
||||
|
||||
class FileSystemDBDataWrapper extends DBDataWrapper {
|
||||
|
||||
|
||||
// returns list of files and directories
|
||||
public function select($source) {
|
||||
$relation = $this->getFileName($source->get_relation());
|
||||
// for tree checks relation id and forms absolute path
|
||||
if ($relation == '0') {
|
||||
$relation = '';
|
||||
} else {
|
||||
$path = $source->get_source();
|
||||
}
|
||||
$path = $source->get_source();
|
||||
$path = $this->getFileName($path);
|
||||
$path = realpath($path);
|
||||
if ($path == false) {
|
||||
return new FileSystemResult();
|
||||
}
|
||||
|
||||
if (strpos(realpath($path.'/'.$relation), $path) !== 0) {
|
||||
return new FileSystemResult();
|
||||
}
|
||||
// gets files and directories list
|
||||
$res = $this->getFilesList($path, $relation);
|
||||
// sorts list
|
||||
$res = $res->sort($source->get_sort_by(), $this->config->data);
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
// gets files and directory list
|
||||
private function getFilesList($path, $relation) {
|
||||
$fileSystemTypes = FileSystemTypes::getInstance();
|
||||
LogMaster::log("Query filesystem: ".$path);
|
||||
$dir = opendir($path.'/'.$relation);
|
||||
$result = new FileSystemResult();
|
||||
// forms fields list
|
||||
for ($i = 0; $i < count($this->config->data); $i++) {
|
||||
$fields[] = $this->config->data[$i]['db_name'];
|
||||
}
|
||||
// for every file and directory of folder
|
||||
while ($file = readdir($dir)) {
|
||||
// . and .. should not be in output list
|
||||
if (($file == '.')||($file == '..')) {
|
||||
continue;
|
||||
}
|
||||
$newFile = array();
|
||||
// parse file name as Array('name', 'ext', 'is_dir')
|
||||
$fileNameExt = $this->parseFileName($path.'/'.$relation, $file);
|
||||
// checks if file should be in output array
|
||||
if (!$fileSystemTypes->checkFile($file, $fileNameExt)) {
|
||||
continue;
|
||||
}
|
||||
// takes file stat if it's need
|
||||
if ((in_array('size', $fields))||(in_array('date', $fields))) {
|
||||
$fileInfo = stat($path.'/'.$file);
|
||||
}
|
||||
|
||||
// for every field forms list of fields
|
||||
for ($i = 0; $i < count($fields); $i++) {
|
||||
$field = $fields[$i];
|
||||
switch ($field) {
|
||||
case 'filename':
|
||||
$newFile['filename'] = $file;
|
||||
break;
|
||||
case 'full_filename':
|
||||
$newFile['full_filename'] = $path."/".$file;
|
||||
break;
|
||||
case 'size':
|
||||
$newFile['size'] = $fileInfo['size'];
|
||||
break;
|
||||
case 'extention':
|
||||
$newFile['extention'] = $fileNameExt['ext'];
|
||||
break;
|
||||
case 'name':
|
||||
$newFile['name'] = $fileNameExt['name'];
|
||||
break;
|
||||
case 'date':
|
||||
$newFile['date'] = date("Y-m-d H:i:s", $fileInfo['ctime']);
|
||||
break;
|
||||
}
|
||||
$newFile['relation_id'] = $relation.'/'.$file;
|
||||
$newFile['safe_name'] = $this->setFileName($relation.'/'.$file);
|
||||
$newFile['is_folder'] = $fileNameExt['is_dir'];
|
||||
}
|
||||
// add file in output list
|
||||
$result->addFile($newFile);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
// replaces '.' and '_' in id
|
||||
private function setFileName($filename) {
|
||||
$filename = str_replace(".", "{-dot-}", $filename);
|
||||
$filename = str_replace("_", "{-nizh-}", $filename);
|
||||
return $filename;
|
||||
}
|
||||
|
||||
|
||||
// replaces '{-dot-}' and '{-nizh-}' in id
|
||||
private function getFileName($filename) {
|
||||
$filename = str_replace("{-dot-}", ".", $filename);
|
||||
$filename = str_replace("{-nizh-}", "_", $filename);
|
||||
return $filename;
|
||||
}
|
||||
|
||||
|
||||
// parses file name and checks if is directory
|
||||
private function parseFileName($path, $file) {
|
||||
$result = Array();
|
||||
if (is_dir($path.'/'.$file)) {
|
||||
$result['name'] = $file;
|
||||
$result['ext'] = 'dir';
|
||||
$result['is_dir'] = 1;
|
||||
} else {
|
||||
$pos = strrpos($file, '.');
|
||||
$result['name'] = substr($file, 0, $pos);
|
||||
$result['ext'] = substr($file, $pos + 1);
|
||||
$result['is_dir'] = 0;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function query($sql) {
|
||||
}
|
||||
|
||||
public function get_new_id() {
|
||||
}
|
||||
|
||||
public function escape($data) {
|
||||
}
|
||||
|
||||
public function get_next($res) {
|
||||
return $res->next();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class FileSystemResult {
|
||||
private $files;
|
||||
private $currentRecord = 0;
|
||||
|
||||
|
||||
// add record to output list
|
||||
public function addFile($file) {
|
||||
$this->files[] = $file;
|
||||
}
|
||||
|
||||
|
||||
// return next record
|
||||
public function next() {
|
||||
if ($this->currentRecord < count($this->files)) {
|
||||
$file = $this->files[$this->currentRecord];
|
||||
$this->currentRecord++;
|
||||
return $file;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// sorts records under $sort array
|
||||
public function sort($sort, $data) {
|
||||
if (count($this->files) == 0) {
|
||||
return $this;
|
||||
}
|
||||
// defines fields list if it's need
|
||||
for ($i = 0; $i < count($sort); $i++) {
|
||||
$fieldname = $sort[$i]['name'];
|
||||
if (!isset($this->files[0][$fieldname])) {
|
||||
if (isset($data[$fieldname])) {
|
||||
$fieldname = $data[$fieldname]['db_name'];
|
||||
$sort[$i]['name'] = $fieldname;
|
||||
} else {
|
||||
$fieldname = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for every sorting field will sort
|
||||
for ($i = 0; $i < count($sort); $i++) {
|
||||
// if field, setted in sort parameter doesn't exist, continue
|
||||
if ($sort[$i]['name'] == false) {
|
||||
continue;
|
||||
}
|
||||
// sorting by current field
|
||||
$flag = true;
|
||||
while ($flag == true) {
|
||||
$flag = false;
|
||||
// checks if previous sorting fields are equal
|
||||
for ($j = 0; $j < count($this->files) - 1; $j++) {
|
||||
$equal = true;
|
||||
for ($k = 0; $k < $i; $k++) {
|
||||
if ($this->files[$j][$sort[$k]['name']] != $this->files[$j + 1][$sort[$k]['name']]) {
|
||||
$equal = false;
|
||||
}
|
||||
}
|
||||
// compares two records in list under current sorting field and sorting direction
|
||||
if (((($this->files[$j][$sort[$i]['name']] > $this->files[$j + 1][$sort[$i]['name']])&&($sort[$i]['direction'] == 'ASC'))||(($this->files[$j][$sort[$i]['name']] < $this->files[$j + 1][$sort[$i]['name']])&&($sort[$i]['direction'] == 'DESC')))&&($equal == true)) {
|
||||
$c = $this->files[$j];
|
||||
$this->files[$j] = $this->files[$j+1];
|
||||
$this->files[$j+1] = $c;
|
||||
$flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// singleton class for setting file types filter
|
||||
class FileSystemTypes {
|
||||
|
||||
static private $instance = NULL;
|
||||
private $extentions = Array();
|
||||
private $extentions_not = Array();
|
||||
private $all = true;
|
||||
private $patterns = Array();
|
||||
// predefined types
|
||||
private $types = Array(
|
||||
'image' => Array('jpg', 'jpeg', 'gif', 'png', 'tiff', 'bmp', 'psd', 'dir'),
|
||||
'document' => Array('txt', 'doc', 'docx', 'xls', 'xlsx', 'rtf', 'dir'),
|
||||
'web' => Array('php', 'html', 'htm', 'js', 'css', 'dir'),
|
||||
'audio' => Array('mp3', 'wav', 'ogg', 'dir'),
|
||||
'video' => Array('avi', 'mpg', 'mpeg', 'mp4', 'dir'),
|
||||
'only_dir' => Array('dir')
|
||||
);
|
||||
|
||||
|
||||
static function getInstance() {
|
||||
if (self::$instance == NULL) {
|
||||
self::$instance = new FileSystemTypes();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
// sets array of extentions
|
||||
public function setExtentions($ext) {
|
||||
$this->all = false;
|
||||
$this->extentions = $ext;
|
||||
}
|
||||
|
||||
// adds one extention in array
|
||||
public function addExtention($ext) {
|
||||
$this->all = false;
|
||||
$this->extentions[] = $ext;
|
||||
}
|
||||
|
||||
|
||||
// adds one extention which will not ouputed in array
|
||||
public function addExtentionNot($ext) {
|
||||
$this->extentions_not[] = $ext;
|
||||
}
|
||||
|
||||
|
||||
// returns array of extentions
|
||||
public function getExtentions() {
|
||||
return $this->extentions;
|
||||
}
|
||||
|
||||
// adds regexp pattern
|
||||
public function addPattern($pattern) {
|
||||
$this->all = false;
|
||||
$this->patterns[] = $pattern;
|
||||
}
|
||||
|
||||
// clear extentions array
|
||||
public function clearExtentions() {
|
||||
$this->all = true;
|
||||
$this->extentions = Array();
|
||||
}
|
||||
|
||||
// clear regexp patterns array
|
||||
public function clearPatterns() {
|
||||
$this->all = true;
|
||||
$this->patterns = Array();
|
||||
}
|
||||
|
||||
// clear all filters
|
||||
public function clearAll() {
|
||||
$this->clearExtentions();
|
||||
$this->clearPatterns();
|
||||
}
|
||||
|
||||
// sets predefined type
|
||||
public function setType($type, $clear = false) {
|
||||
$this->all = false;
|
||||
if ($type == 'all') {
|
||||
$this->all = true;
|
||||
return true;
|
||||
}
|
||||
if (isset($this->types[$type])) {
|
||||
if ($clear) {
|
||||
$this->clearExtentions();
|
||||
}
|
||||
for ($i = 0; $i < count($this->types[$type]); $i++) {
|
||||
$this->extentions[] = $this->types[$type][$i];
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check file under setted filter
|
||||
public function checkFile($filename, $fileNameExt) {
|
||||
if (in_array($fileNameExt['ext'], $this->extentions_not)) {
|
||||
return false;
|
||||
}
|
||||
if ($this->all) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((count($this->extentions) > 0)&&(!in_array($fileNameExt['ext'], $this->extentions))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < count($this->patterns); $i++) {
|
||||
if (!preg_match($this->patterns[$i], $filename)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
73
libraries/dhtmlxgantt/connector/db_mssql.php
Normal file
73
libraries/dhtmlxgantt/connector/db_mssql.php
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("db_common.php");
|
||||
/*! MSSQL implementation of DataWrapper
|
||||
**/
|
||||
class MsSQLDBDataWrapper extends DBDataWrapper{
|
||||
private $last_id=""; //!< ID of previously inserted record
|
||||
private $insert_operation=false; //!< flag of insert operation
|
||||
private $start_from=false; //!< index of start position
|
||||
|
||||
public function query($sql){
|
||||
LogMaster::log($sql);
|
||||
$res = mssql_query($sql,$this->connection);
|
||||
if ($this->insert_operation){
|
||||
$last = mssql_fetch_assoc($res);
|
||||
$this->last_id = $last["dhx_id"];
|
||||
mssql_free_result($res);
|
||||
}
|
||||
if ($this->start_from)
|
||||
mssql_data_seek($res,$this->start_from);
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function get_next($res){
|
||||
return mssql_fetch_assoc($res);
|
||||
}
|
||||
|
||||
public function get_new_id(){
|
||||
/*
|
||||
MSSQL doesn't support identity or auto-increment fields
|
||||
Insert SQL returns new ID value, which stored in last_id field
|
||||
*/
|
||||
return $this->last_id;
|
||||
}
|
||||
|
||||
protected function insert_query($data,$request){
|
||||
$sql = parent::insert_query($data,$request);
|
||||
$this->insert_operation=true;
|
||||
return $sql.";SELECT @@IDENTITY AS dhx_id";
|
||||
}
|
||||
|
||||
protected function select_query($select,$from,$where,$sort,$start,$count){
|
||||
if (!$from)
|
||||
return $select;
|
||||
|
||||
$sql="SELECT " ;
|
||||
if ($count)
|
||||
$sql.=" TOP ".($count+$start);
|
||||
$sql.=" ".$select." FROM ".$from;
|
||||
if ($where) $sql.=" WHERE ".$where;
|
||||
if ($sort) $sql.=" ORDER BY ".$sort;
|
||||
if ($start && $count)
|
||||
$this->start_from=$start;
|
||||
else
|
||||
$this->start_from=false;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function escape($data){
|
||||
/*
|
||||
there is no special escaping method for mssql - use common logic
|
||||
*/
|
||||
return str_replace("'","''",$data);
|
||||
}
|
||||
|
||||
public function begin_transaction(){
|
||||
$this->query("BEGIN TRAN");
|
||||
}
|
||||
}
|
||||
?>
|
||||
56
libraries/dhtmlxgantt/connector/db_mysqli.php
Normal file
56
libraries/dhtmlxgantt/connector/db_mysqli.php
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("db_common.php");
|
||||
|
||||
class MySQLiDBDataWrapper extends MySQLDBDataWrapper{
|
||||
|
||||
public function query($sql){
|
||||
LogMaster::log($sql);
|
||||
$res = $this->connection->query($sql);
|
||||
if ($res===false) throw new Exception("MySQL operation failed\n".$this->connection->error);
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function get_next($res){
|
||||
return $res->fetch_assoc();
|
||||
}
|
||||
|
||||
public function get_new_id(){
|
||||
return $this->connection->insert_id;
|
||||
}
|
||||
|
||||
public function escape($data){
|
||||
return $this->connection->real_escape_string($data);
|
||||
}
|
||||
|
||||
public function tables_list() {
|
||||
$result = $this->connection->query("SHOW TABLES");
|
||||
if ($result===false) throw new Exception("MySQL operation failed\n".$this->connection->error);
|
||||
|
||||
$tables = array();
|
||||
while ($table = $result->fetch_array()) {
|
||||
$tables[] = $table[0];
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
public function fields_list($table) {
|
||||
$result = $this->connection->query("SHOW COLUMNS FROM `".$table."`");
|
||||
if ($result===false) throw new Exception("MySQL operation failed\n".$this->connection->error);
|
||||
$fields = array();
|
||||
while ($field = $result->fetch_array()) {
|
||||
if ($field['Key'] == "PRI") {
|
||||
$fields[$field[0]] = 1;
|
||||
} else {
|
||||
$fields[$field[0]] = 0;
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
88
libraries/dhtmlxgantt/connector/db_oracle.php
Normal file
88
libraries/dhtmlxgantt/connector/db_oracle.php
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("db_common.php");
|
||||
/*! Implementation of DataWrapper for Oracle
|
||||
**/
|
||||
class OracleDBDataWrapper extends DBDataWrapper{
|
||||
private $last_id=""; //id of previously inserted record
|
||||
private $insert_operation=false; //flag of insert operation
|
||||
|
||||
public function query($sql){
|
||||
LogMaster::log($sql);
|
||||
$stm = oci_parse($this->connection,$sql);
|
||||
if ($stm===false) throw new Exception("Oracle - sql parsing failed\n".oci_error($this->connection));
|
||||
|
||||
$out = array(0=>null);
|
||||
if($this->insert_operation){
|
||||
oci_bind_by_name($stm,":outID",$out[0],999);
|
||||
$this->insert_operation=false;
|
||||
}
|
||||
|
||||
|
||||
$mode = ($this->is_record_transaction() || $this->is_global_transaction())?OCI_DEFAULT:OCI_COMMIT_ON_SUCCESS;
|
||||
$res = @oci_execute($stm,$mode);
|
||||
if ($res===false) throw new Exception(oci_error($this->connection));
|
||||
|
||||
$this->last_id=$out[0];
|
||||
|
||||
return $stm;
|
||||
}
|
||||
|
||||
public function get_next($res){
|
||||
$data = oci_fetch_assoc($res);
|
||||
if ($data){
|
||||
foreach ($data as $k => $v)
|
||||
$data[strtolower($k)] = $v;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function get_new_id(){
|
||||
/*
|
||||
Oracle doesn't support identity or auto-increment fields
|
||||
Insert SQL returns new ID value, which stored in last_id field
|
||||
*/
|
||||
return $this->last_id;
|
||||
}
|
||||
|
||||
protected function insert_query($data,$request){
|
||||
$sql = parent::insert_query($data,$request);
|
||||
$this->insert_operation=true;
|
||||
return $sql." returning ".$this->config->id["db_name"]." into :outID";
|
||||
}
|
||||
|
||||
protected function select_query($select,$from,$where,$sort,$start,$count){
|
||||
if (!$from)
|
||||
return $select;
|
||||
|
||||
$sql="SELECT ".$select." FROM ".$from;
|
||||
if ($where) $sql.=" WHERE ".$where;
|
||||
if ($sort) $sql.=" ORDER BY ".$sort;
|
||||
if ($start || $count)
|
||||
$sql="SELECT * FROM ( select /*+ FIRST_ROWS(".$count.")*/dhx_table.*, ROWNUM rnum FROM (".$sql.") dhx_table where ROWNUM <= ".($count+$start)." ) where rnum >".$start;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function escape($data){
|
||||
/*
|
||||
as far as I can see the only way to escape data is by using oci_bind_by_name
|
||||
while it is neat solution in common case, it conflicts with existing SQL building logic
|
||||
fallback to simple escaping
|
||||
*/
|
||||
return str_replace("'","''",$data);
|
||||
}
|
||||
|
||||
public function begin_transaction(){
|
||||
//auto-start of transaction
|
||||
}
|
||||
public function commit_transaction(){
|
||||
oci_commit($this->connection);
|
||||
}
|
||||
public function rollback_transaction(){
|
||||
oci_rollback($this->connection);
|
||||
}
|
||||
}
|
||||
?>
|
||||
100
libraries/dhtmlxgantt/connector/db_pdo.php
Normal file
100
libraries/dhtmlxgantt/connector/db_pdo.php
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<?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 PDODBDataWrapper 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) {
|
||||
$message = $this->connection->errorInfo();
|
||||
throw new Exception("PDO - sql execution failed\n".$message[2]);
|
||||
}
|
||||
|
||||
return new PDOResultSet($res);
|
||||
}
|
||||
|
||||
protected function select_query($select,$from,$where,$sort,$start,$count){
|
||||
if (!$from)
|
||||
return $select;
|
||||
|
||||
$sql="SELECT ".$select." FROM ".$from;
|
||||
if ($where) $sql.=" WHERE ".$where;
|
||||
if ($sort) $sql.=" ORDER BY ".$sort;
|
||||
if ($start || $count) {
|
||||
if ($this->connection->getAttribute(PDO::ATTR_DRIVER_NAME)=="pgsql")
|
||||
$sql.=" OFFSET ".$start." LIMIT ".$count;
|
||||
else
|
||||
$sql.=" LIMIT ".$start.",".$count;
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function tables_list() {
|
||||
$result = $this->query("SHOW TABLES");
|
||||
if ($result===false) throw new Exception("MySQL operation failed\n".mysql_error($this->connection));
|
||||
|
||||
$tables = array();
|
||||
while ($table = $result->next()) {
|
||||
$tables[] = $table[0];
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
public function fields_list($table) {
|
||||
$result = $this->query("SHOW COLUMNS FROM `".$table."`");
|
||||
if ($result===false) throw new Exception("MySQL operation failed\n".mysql_error($this->connection));
|
||||
|
||||
$fields = array();
|
||||
$id = "";
|
||||
while ($field = $result->next()) {
|
||||
if ($field['Key'] == "PRI")
|
||||
$id = $field["Field"];
|
||||
else
|
||||
$fields[] = $field["Field"];
|
||||
}
|
||||
return array("fields" => $fields, "key" => $id );
|
||||
}
|
||||
|
||||
public function get_next($res){
|
||||
$data = $res->next();
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function get_new_id(){
|
||||
return $this->connection->lastInsertId();
|
||||
}
|
||||
|
||||
public function escape($str){
|
||||
$res=$this->connection->quote($str);
|
||||
if ($res===false) //not supported by pdo driver
|
||||
return str_replace("'","''",$str);
|
||||
return substr($res,1,-1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class PDOResultSet{
|
||||
private $res;
|
||||
public function __construct($res){
|
||||
$this->res = $res;
|
||||
}
|
||||
public function next(){
|
||||
$data = $this->res->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$data){
|
||||
$this->res->closeCursor();
|
||||
return null;
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
?>
|
||||
85
libraries/dhtmlxgantt/connector/db_phpcake.php
Normal file
85
libraries/dhtmlxgantt/connector/db_phpcake.php
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("db_common.php");
|
||||
|
||||
//DataProcessor::$action_param ="dhx_editor_status";
|
||||
|
||||
/*! Implementation of DataWrapper for PDO
|
||||
|
||||
if you plan to use it for Oracle - use Oracle connection type instead
|
||||
**/
|
||||
class PHPCakeDBDataWrapper extends ArrayDBDataWrapper{
|
||||
public function select($sql){
|
||||
$source = $sql->get_source();
|
||||
if (is_array($source)) //result of find
|
||||
$res = $source;
|
||||
else
|
||||
$res = $this->connection->find("all");
|
||||
|
||||
$temp = array();
|
||||
if (sizeof($res)){
|
||||
$name = get_class($this->connection);
|
||||
for ($i=sizeof($res)-1; $i>=0; $i--)
|
||||
$temp[]=&$res[$i][$name];
|
||||
}
|
||||
return new ArrayQueryWrapper($temp);
|
||||
}
|
||||
|
||||
protected function getErrorMessage(){
|
||||
$errors = $this->connection->invalidFields();
|
||||
$text = array();
|
||||
foreach ($errors as $key => $value){
|
||||
$text[] = $key." - ".$value[0];
|
||||
}
|
||||
return implode("\n", $text);
|
||||
}
|
||||
|
||||
public function insert($data,$source){
|
||||
$name = get_class($this->connection);
|
||||
$save = array();
|
||||
$temp_data = $data->get_data();
|
||||
unset($temp_data[$this->config->id['db_name']]);
|
||||
unset($temp_data["!nativeeditor_status"]);
|
||||
$save[$name] = $temp_data;
|
||||
|
||||
if ($this->connection->save($save)){
|
||||
$data->success($this->connection->getLastInsertID());
|
||||
} else {
|
||||
$data->set_response_attribute("details", $this->getErrorMessage());
|
||||
$data->invalid();
|
||||
}
|
||||
}
|
||||
public function delete($data,$source){
|
||||
$id = $data->get_id();
|
||||
$this->connection->delete($id);
|
||||
$data->success();
|
||||
}
|
||||
public function update($data,$source){
|
||||
$name = get_class($this->connection);
|
||||
$save = array();
|
||||
$save[$name] = &$data->get_data();
|
||||
|
||||
if ($this->connection->save($save)){
|
||||
$data->success();
|
||||
} else {
|
||||
$data->set_response_attribute("details", $this->getErrorMessage());
|
||||
$data->invalid();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function escape($str){
|
||||
throw new Exception("Not implemented");
|
||||
}
|
||||
public function query($str){
|
||||
throw new Exception("Not implemented");
|
||||
}
|
||||
public function get_new_id(){
|
||||
throw new Exception("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
65
libraries/dhtmlxgantt/connector/db_phpci.php
Normal file
65
libraries/dhtmlxgantt/connector/db_phpci.php
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("db_common.php");
|
||||
|
||||
/*! Implementation of DataWrapper for PDO
|
||||
|
||||
if you plan to use it for Oracle - use Oracle connection type instead
|
||||
**/
|
||||
class 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");
|
||||
}
|
||||
|
||||
if (is_object($res))
|
||||
return new PHPCIResultSet($res);
|
||||
return new ArrayQueryWrapper(array());
|
||||
}
|
||||
|
||||
public function get_next($res){
|
||||
$data = $res->next();
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function get_new_id(){
|
||||
return $this->connection->insert_id();
|
||||
}
|
||||
|
||||
public function escape($str){
|
||||
return $this->connection->escape_str($str);
|
||||
}
|
||||
|
||||
public function escape_name($data){
|
||||
return $this->connection->protect_identifiers($data);
|
||||
}
|
||||
}
|
||||
|
||||
class PHPCIResultSet{
|
||||
private $res;
|
||||
private $start;
|
||||
private $count;
|
||||
|
||||
public function __construct($res){
|
||||
$this->res = $res;
|
||||
$this->start = $res->current_row;
|
||||
$this->count = $res->num_rows;
|
||||
}
|
||||
public function next(){
|
||||
if ($this->start != $this->count){
|
||||
return $this->res->row($this->start++,'array');
|
||||
} else {
|
||||
$this->res->free_result();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
91
libraries/dhtmlxgantt/connector/db_phpyii.php
Normal file
91
libraries/dhtmlxgantt/connector/db_phpyii.php
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
|
||||
require_once("db_common.php");
|
||||
|
||||
class PHPYiiDBDataWrapper extends ArrayDBDataWrapper{
|
||||
public function select($sql){
|
||||
if (is_array($this->connection)) //result of findAll
|
||||
$res = $this->connection;
|
||||
else
|
||||
$res = $this->connection->findAll();
|
||||
|
||||
$temp = array();
|
||||
if (sizeof($res)){
|
||||
foreach ($res as $obj)
|
||||
$temp[]=$obj->getAttributes();
|
||||
}
|
||||
return new ArrayQueryWrapper($temp);
|
||||
}
|
||||
|
||||
protected function getErrorMessage(){
|
||||
$errors = $this->connection->invalidFields();
|
||||
$text = array();
|
||||
foreach ($errors as $key => $value){
|
||||
$text[] = $key." - ".$value[0];
|
||||
}
|
||||
return implode("\n", $text);
|
||||
}
|
||||
public function insert($data,$source){
|
||||
$name = get_class($this->connection);
|
||||
$obj = new $name();
|
||||
|
||||
$this->fill_model_and_save($obj, $data);
|
||||
}
|
||||
public function delete($data,$source){
|
||||
$obj = $this->connection->findByPk($data->get_id());
|
||||
if ($obj->delete()){
|
||||
$data->success();
|
||||
$data->set_new_id($obj->getPrimaryKey());
|
||||
} else {
|
||||
$data->set_response_attribute("details", $this->errors_to_string($obj->getErrors()));
|
||||
$data->invalid();
|
||||
}
|
||||
}
|
||||
public function update($data,$source){
|
||||
$obj = $this->connection->findByPk($data->get_id());
|
||||
$this->fill_model_and_save($obj, $data);
|
||||
}
|
||||
|
||||
protected function fill_model_and_save($obj, $data){
|
||||
$values = $data->get_data();
|
||||
|
||||
//map data to model object
|
||||
for ($i=0; $i < sizeof($this->config->text); $i++){
|
||||
$step=$this->config->text[$i];
|
||||
$obj->setAttribute($step["name"], $data->get_value($step["name"]));
|
||||
}
|
||||
if ($relation = $this->config->relation_id["db_name"])
|
||||
$obj->setAttribute($relation, $data->get_value($relation));
|
||||
|
||||
//save model
|
||||
if ($obj->save()){
|
||||
$data->success();
|
||||
$data->set_new_id($obj->getPrimaryKey());
|
||||
} else {
|
||||
$data->set_response_attribute("details", $this->errors_to_string($obj->getErrors()));
|
||||
$data->invalid();
|
||||
}
|
||||
}
|
||||
|
||||
protected function errors_to_string($errors){
|
||||
$text = array();
|
||||
foreach($errors as $value)
|
||||
$text[]=implode("\n", $value);
|
||||
return implode("\n",$text);
|
||||
}
|
||||
public function escape($str){
|
||||
throw new Exception("Not implemented");
|
||||
}
|
||||
public function query($str){
|
||||
throw new Exception("Not implemented");
|
||||
}
|
||||
public function get_new_id(){
|
||||
throw new Exception("Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
73
libraries/dhtmlxgantt/connector/db_postgre.php
Normal file
73
libraries/dhtmlxgantt/connector/db_postgre.php
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("db_common.php");
|
||||
/*! Implementation of DataWrapper for PostgreSQL
|
||||
**/
|
||||
class PostgreDBDataWrapper extends DBDataWrapper{
|
||||
public function query($sql){
|
||||
LogMaster::log($sql);
|
||||
|
||||
$res=pg_query($this->connection,$sql);
|
||||
if ($res===false) throw new Exception("Postgre - sql execution failed\n".pg_last_error($this->connection));
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
protected function select_query($select,$from,$where,$sort,$start,$count){
|
||||
if (!$from)
|
||||
return $select;
|
||||
|
||||
$sql="SELECT ".$select." FROM ".$from;
|
||||
if ($where) $sql.=" WHERE ".$where;
|
||||
if ($sort) $sql.=" ORDER BY ".$sort;
|
||||
if ($start || $count)
|
||||
$sql.=" OFFSET ".$start." LIMIT ".$count;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function get_next($res){
|
||||
return pg_fetch_assoc($res);
|
||||
}
|
||||
|
||||
public function get_new_id(){
|
||||
$res = pg_query( $this->connection, "SELECT LASTVAL() AS seq");
|
||||
$data = pg_fetch_assoc($res);
|
||||
pg_free_result($res);
|
||||
return $data['seq'];
|
||||
}
|
||||
|
||||
public function escape($data){
|
||||
//need to use oci_bind_by_name
|
||||
return pg_escape_string($this->connection,$data);
|
||||
}
|
||||
|
||||
public function tables_list() {
|
||||
$sql = "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'";
|
||||
$res = pg_query($this->connection, $sql);
|
||||
$tables = array();
|
||||
while ($table = pg_fetch_assoc($res)) {
|
||||
$tables[] = $table['table_name'];
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
public function fields_list($table) {
|
||||
$sql = "SELECT * FROM information_schema.constraint_column_usage";
|
||||
$result = pg_query($this->connection, $sql);
|
||||
$field = pg_fetch_assoc($result);
|
||||
$id = $field['column_name'];
|
||||
|
||||
$sql = "SELECT * FROM information_schema.columns WHERE table_name ='".$table."';";
|
||||
$result = pg_query($this->connection, $sql);
|
||||
$fields = array();
|
||||
$id = "";
|
||||
while ($field = pg_fetch_assoc($result)) {
|
||||
$fields[] = $field["column_name"];
|
||||
}
|
||||
return array('fields' => $fields, 'key' => $id );
|
||||
}
|
||||
}
|
||||
?>
|
||||
54
libraries/dhtmlxgantt/connector/db_sasql.php
Normal file
54
libraries/dhtmlxgantt/connector/db_sasql.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
require_once("db_common.php");
|
||||
/*! SaSQL implementation of DataWrapper
|
||||
**/
|
||||
class SaSQLDBDataWrapper extends DBDataWrapper{
|
||||
private $last_id=""; //!< ID of previously inserted record
|
||||
|
||||
public function query($sql){
|
||||
LogMaster::log($sql);
|
||||
$res=sasql_query($this->connection, $sql);
|
||||
if ($res===false) throw new Exception("SaSQL operation failed\n".sasql_error($this->connection));
|
||||
$this->last_result = $res;
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function get_next($res){
|
||||
if (!$res)
|
||||
$res = $this->last_result;
|
||||
|
||||
return sasql_fetch_assoc($res);
|
||||
}
|
||||
|
||||
public function get_new_id(){
|
||||
return sasql_insert_id($this->connection);
|
||||
}
|
||||
|
||||
protected function insert_query($data,$request){
|
||||
$sql = parent::insert_query($data,$request);
|
||||
$this->insert_operation=true;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
protected function select_query($select,$from,$where,$sort,$start,$count){
|
||||
if (!$from)
|
||||
return $select;
|
||||
|
||||
$sql="SELECT " ;
|
||||
if ($count)
|
||||
$sql.=" TOP ".($count+$start);
|
||||
$sql.=" ".$select." FROM ".$from;
|
||||
if ($where) $sql.=" WHERE ".$where;
|
||||
if ($sort) $sql.=" ORDER BY ".$sort;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function escape($data){
|
||||
return sasql_escape_string($this->connection, $data);
|
||||
}
|
||||
|
||||
public function begin_transaction(){
|
||||
$this->query("BEGIN TRAN");
|
||||
}
|
||||
}
|
||||
?>
|
||||
34
libraries/dhtmlxgantt/connector/db_sqlite.php
Normal file
34
libraries/dhtmlxgantt/connector/db_sqlite.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("db_common.php");
|
||||
/*! SQLite implementation of DataWrapper
|
||||
**/
|
||||
class SQLiteDBDataWrapper extends DBDataWrapper{
|
||||
|
||||
public function query($sql){
|
||||
LogMaster::log($sql);
|
||||
|
||||
$res = sqlite_query($this->connection,$sql);
|
||||
if ($res === false)
|
||||
throw new Exception("SQLLite - sql execution failed\n".sqlite_error_string(sqlite_last_error($this->connection)));
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function get_next($res){
|
||||
$data = sqlite_fetch_array($res, SQLITE_ASSOC);
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function get_new_id(){
|
||||
return sqlite_last_insert_rowid($this->connection);
|
||||
}
|
||||
|
||||
public function escape($data){
|
||||
return sqlite_escape_string($data);
|
||||
}
|
||||
}
|
||||
?>
|
||||
33
libraries/dhtmlxgantt/connector/db_sqlite3.php
Normal file
33
libraries/dhtmlxgantt/connector/db_sqlite3.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("db_common.php");
|
||||
/*! SQLite implementation of DataWrapper
|
||||
**/
|
||||
class SQLite3DBDataWrapper extends DBDataWrapper{
|
||||
|
||||
public function query($sql){
|
||||
LogMaster::log($sql);
|
||||
|
||||
$res = $this->connection->query($sql);
|
||||
if ($res === false)
|
||||
throw new Exception("SQLLite - sql execution failed\n".$this->connection->lastErrorMsg());
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function get_next($res){
|
||||
return $res->fetchArray();
|
||||
}
|
||||
|
||||
public function get_new_id(){
|
||||
return $this->connection->lastInsertRowID();
|
||||
}
|
||||
|
||||
public function escape($data){
|
||||
return $this->connection->escapeString($data);
|
||||
}
|
||||
}
|
||||
?>
|
||||
102
libraries/dhtmlxgantt/connector/db_sqlsrv.php
Normal file
102
libraries/dhtmlxgantt/connector/db_sqlsrv.php
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
/*
|
||||
This software is allowed to use under GPL or you need to obtain Commercial or Enterise License
|
||||
to use it in non-GPL project. Please contact sales@dhtmlx.com for details
|
||||
*/
|
||||
?><?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("db_common.php");
|
||||
/*! MSSQL implementation of DataWrapper
|
||||
**/
|
||||
class SQLSrvDBDataWrapper extends DBDataWrapper{
|
||||
private $last_id=""; //!< ID of previously inserted record
|
||||
private $insert_operation=false; //!< flag of insert operation
|
||||
private $start_from=false; //!< index of start position
|
||||
|
||||
public function query($sql){
|
||||
LogMaster::log($sql);
|
||||
if ($this->start_from)
|
||||
$res = sqlsrv_query($this->connection,$sql, array(), array("Scrollable" => SQLSRV_CURSOR_STATIC));
|
||||
else
|
||||
$res = sqlsrv_query($this->connection,$sql);
|
||||
|
||||
if ($res === false){
|
||||
$errors = sqlsrv_errors();
|
||||
$message = Array();
|
||||
foreach($errors as $error)
|
||||
$message[]=$error["SQLSTATE"].$error["code"].$error["message"];
|
||||
throw new Exception("SQLSrv operation failed\n".implode("\n\n", $message));
|
||||
}
|
||||
|
||||
if ($this->insert_operation){
|
||||
sqlsrv_next_result($res);
|
||||
$last = sqlsrv_fetch_array($res);
|
||||
$this->last_id = $last["dhx_id"];
|
||||
sqlsrv_free_stmt($res);
|
||||
}
|
||||
if ($this->start_from)
|
||||
$data = sqlsrv_fetch($res, SQLSRV_SCROLL_ABSOLUTE, $this->start_from-1);
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function get_next($res){
|
||||
$data = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC);
|
||||
if ($data)
|
||||
foreach ($data as $key => $value)
|
||||
if (is_a($value, "DateTime"))
|
||||
$data[$key] = $value->format("Y-m-d H:i");
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function get_new_id(){
|
||||
/*
|
||||
MSSQL doesn't support identity or auto-increment fields
|
||||
Insert SQL returns new ID value, which stored in last_id field
|
||||
*/
|
||||
return $this->last_id;
|
||||
}
|
||||
|
||||
protected function insert_query($data,$request){
|
||||
$sql = parent::insert_query($data,$request);
|
||||
$this->insert_operation=true;
|
||||
return $sql.";SELECT SCOPE_IDENTITY() as dhx_id";
|
||||
}
|
||||
|
||||
protected function select_query($select,$from,$where,$sort,$start,$count){
|
||||
if (!$from)
|
||||
return $select;
|
||||
|
||||
$sql="SELECT " ;
|
||||
if ($count)
|
||||
$sql.=" TOP ".($count+$start);
|
||||
$sql.=" ".$select." FROM ".$from;
|
||||
if ($where) $sql.=" WHERE ".$where;
|
||||
if ($sort) $sql.=" ORDER BY ".$sort;
|
||||
if ($start && $count)
|
||||
$this->start_from=$start;
|
||||
else
|
||||
$this->start_from=false;
|
||||
return $sql;
|
||||
}
|
||||
|
||||
public function escape($data){
|
||||
/*
|
||||
there is no special escaping method for mssql - use common logic
|
||||
*/
|
||||
return str_replace("'","''",$data);
|
||||
}
|
||||
|
||||
public function begin_transaction(){
|
||||
sqlsrv_begin_transaction($this->connection);
|
||||
}
|
||||
public function commit_transaction(){
|
||||
sqlsrv_commit($this->connection);
|
||||
}
|
||||
public function rollback_transaction(){
|
||||
sqlsrv_rollback($this->connection);
|
||||
}
|
||||
}
|
||||
?>
|
||||
19
libraries/dhtmlxgantt/connector/filesystem_item.php
Normal file
19
libraries/dhtmlxgantt/connector/filesystem_item.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
|
||||
class FileTreeDataItem extends TreeDataItem {
|
||||
|
||||
function has_kids(){
|
||||
if ($this->data['is_folder'] == '1') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
62
libraries/dhtmlxgantt/connector/form_connector.php
Normal file
62
libraries/dhtmlxgantt/connector/form_connector.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("base_connector.php");
|
||||
|
||||
/*! DataItem class for dhxForm component
|
||||
**/
|
||||
class FormDataItem extends DataItem{
|
||||
/*! return self as XML string
|
||||
*/
|
||||
function to_xml(){
|
||||
if ($this->skip) return "";
|
||||
$str="";
|
||||
for ($i = 0; $i < count($this->config->data); $i++) {
|
||||
$str .= "<".$this->config->data[$i]['name']."><![CDATA[".$this->data[$this->config->data[$i]['name']]."]]></".$this->config->data[$i]['name'].">";
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Connector class for dhtmlxForm
|
||||
**/
|
||||
class FormConnector extends Connector{
|
||||
|
||||
/*! 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){
|
||||
if (!$item_type) $item_type="FormDataItem";
|
||||
if (!$data_type) $data_type="FormDataProcessor";
|
||||
parent::__construct($res,$type,$item_type,$data_type);
|
||||
}
|
||||
|
||||
//parse GET scoope, all operations with incoming request must be done here
|
||||
function parse_request(){
|
||||
parent::parse_request();
|
||||
if (isset($_GET["id"]))
|
||||
$this->request->set_filter($this->config->id["name"],$_GET["id"],"=");
|
||||
else if (!$_POST["ids"])
|
||||
throw new Exception("ID parameter is missed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*! DataProcessor class for dhxForm component
|
||||
**/
|
||||
class FormDataProcessor extends DataProcessor{
|
||||
|
||||
}
|
||||
?>
|
||||
364
libraries/dhtmlxgantt/connector/gantt_connector.php
Normal file
364
libraries/dhtmlxgantt/connector/gantt_connector.php
Normal file
|
|
@ -0,0 +1,364 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("base_connector.php");
|
||||
require_once("data_connector.php");
|
||||
|
||||
/*! DataItem class for Gantt component
|
||||
**/
|
||||
class GanttDataItem extends DataItem{
|
||||
|
||||
/*! return self as XML string
|
||||
*/
|
||||
function to_xml(){
|
||||
if ($this->skip) return "";
|
||||
|
||||
$str="<task id='".$this->get_id()."' >";
|
||||
$str.="<start_date><![CDATA[".$this->data[$this->config->text[0]["name"]]."]]></start_date>";
|
||||
$str.="<".$this->config->text[1]["name"]."><![CDATA[".$this->data[$this->config->text[1]["name"]]."]]></".$this->config->text[1]["name"].">";
|
||||
$str.="<text><![CDATA[".$this->data[$this->config->text[2]["name"]]."]]></text>";
|
||||
for ($i=3; $i<sizeof($this->config->text); $i++){
|
||||
$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."</task>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Connector class for dhtmlxGantt
|
||||
**/
|
||||
class GanttConnector extends Connector{
|
||||
|
||||
protected $extra_output="";//!< extra info which need to be sent to client side
|
||||
protected $options=array();//!< hash of OptionsConnector
|
||||
protected $links_mode = false;
|
||||
|
||||
|
||||
/*! assign options collection to the column
|
||||
|
||||
@param name
|
||||
name of the column
|
||||
@param options
|
||||
array or connector object
|
||||
*/
|
||||
public function set_options($name,$options){
|
||||
if (is_array($options)){
|
||||
$str="";
|
||||
foreach($options as $k => $v)
|
||||
$str.="<item value='".$this->xmlentities($k)."' label='".$this->xmlentities($v)."' />";
|
||||
$options=$str;
|
||||
}
|
||||
$this->options[$name]=$options;
|
||||
}
|
||||
|
||||
|
||||
/*! constructor
|
||||
|
||||
Here initilization of all Masters occurs, execution timer initialized
|
||||
@param res
|
||||
db connection resource
|
||||
@param type
|
||||
string , which hold type of database ( MySQL or Postgre ), optional, instead of short DB name, full name of DataWrapper-based class can be provided
|
||||
@param item_type
|
||||
name of class, which will be used for item rendering, optional, DataItem will be used by default
|
||||
@param data_type
|
||||
name of class which will be used for dataprocessor calls handling, optional, DataProcessor class will be used by default.
|
||||
* @param render_type
|
||||
name of class which will be used for rendering.
|
||||
*/
|
||||
public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
|
||||
if (!$item_type) $item_type="GanttDataItem";
|
||||
if (!$data_type) $data_type="GanttDataProcessor";
|
||||
if (!$render_type) $render_type="RenderStrategy";
|
||||
parent::__construct($res,$type,$item_type,$data_type,$render_type);
|
||||
|
||||
$this->event->attach("afterDelete", array($this, "delete_related_links"));
|
||||
$this->event->attach("afterOrder", array($this, "order_set_parent"));
|
||||
}
|
||||
|
||||
//parse GET scoope, all operations with incoming request must be done here
|
||||
function parse_request(){
|
||||
parent::parse_request();
|
||||
|
||||
if (isset($_GET["gantt_mode"]) && $_GET["gantt_mode"] == "links")
|
||||
$this->links_mode = true;
|
||||
|
||||
if (count($this->config->text)){
|
||||
if (isset($_GET["to"]))
|
||||
$this->request->set_filter($this->config->text[0]["name"],$_GET["to"],"<");
|
||||
if (isset($_GET["from"]))
|
||||
$this->request->set_filter($this->config->text[1]["name"],$_GET["from"],">");
|
||||
}
|
||||
}
|
||||
|
||||
function order_set_parent($action){
|
||||
$value = $action->get_id();
|
||||
$parent = $action->get_value("parent");
|
||||
|
||||
$table = $this->request->get_source();
|
||||
$id = $this->config->id["db_name"];
|
||||
|
||||
$this->sql->query("UPDATE $table SET parent = $parent WHERE $id = $value");
|
||||
}
|
||||
|
||||
function delete_related_links($action){
|
||||
if (isset($this->options["links"])){
|
||||
$links = $this->options["links"];
|
||||
$value = $this->sql->escape($action->get_new_id());
|
||||
$table = $links->get_request()->get_source();
|
||||
|
||||
$this->sql->query("DELETE FROM $table WHERE source = '$value'");
|
||||
$this->sql->query("DELETE FROM $table WHERE target = '$value'");
|
||||
}
|
||||
}
|
||||
|
||||
public function render_links($table,$id="",$fields=false,$extra=false,$relation_id=false) {
|
||||
$links = new GanttLinksConnector($this->get_connection(),$this->names["db_class"]);
|
||||
$links->render_table($table,$id,$fields,$extra);
|
||||
$this->set_options("links", $links);
|
||||
}
|
||||
}
|
||||
|
||||
/*! DataProcessor class for Gantt component
|
||||
**/
|
||||
class GanttDataProcessor extends DataProcessor{
|
||||
function name_data($data){
|
||||
if ($data=="start_date")
|
||||
return $this->config->text[0]["name"];
|
||||
if ($data=="id")
|
||||
return $this->config->id["name"];
|
||||
if ($data=="duration" && $this->config->text[1]["name"] == "duration")
|
||||
return $this->config->text[1]["name"];
|
||||
if ($data=="end_date" && $this->config->text[1]["name"] == "end_date")
|
||||
return $this->config->text[1]["name"];
|
||||
if ($data=="text")
|
||||
return $this->config->text[2]["name"];
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class JSONGanttDataItem extends GanttDataItem{
|
||||
/*! return self as XML string
|
||||
*/
|
||||
function to_xml(){
|
||||
if ($this->skip) return "";
|
||||
|
||||
$obj = array();
|
||||
$obj['id'] = $this->get_id();
|
||||
$obj['start_date'] = $this->data[$this->config->text[0]["name"]];
|
||||
$obj[$this->config->text[1]["name"]] = $this->data[$this->config->text[1]["name"]];
|
||||
$obj['text'] = $this->data[$this->config->text[2]["name"]];
|
||||
for ($i=3; $i<sizeof($this->config->text); $i++){
|
||||
$extra = $this->config->text[$i]["name"];
|
||||
$obj[$extra]=$this->data[$extra];
|
||||
}
|
||||
|
||||
if ($this->userdata !== false)
|
||||
foreach ($this->userdata as $key => $value)
|
||||
$obj[$key]=$value;
|
||||
|
||||
return $obj;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class JSONGanttConnector extends GanttConnector {
|
||||
|
||||
protected $data_separator = ",";
|
||||
|
||||
/*! constructor
|
||||
|
||||
Here initilization of all Masters occurs, execution timer initialized
|
||||
@param res
|
||||
db connection resource
|
||||
@param type
|
||||
string , which hold type of database ( MySQL or Postgre ), optional, instead of short DB name, full name of DataWrapper-based class can be provided
|
||||
@param item_type
|
||||
name of class, which will be used for item rendering, optional, DataItem will be used by default
|
||||
@param data_type
|
||||
name of class which will be used for dataprocessor calls handling, optional, DataProcessor class will be used by default.
|
||||
*/
|
||||
public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
|
||||
if (!$item_type) $item_type="JSONGanttDataItem";
|
||||
if (!$data_type) $data_type="GanttDataProcessor";
|
||||
if (!$render_type) $render_type="JSONRenderStrategy";
|
||||
parent::__construct($res,$type,$item_type,$data_type,$render_type);
|
||||
}
|
||||
|
||||
protected function xml_start() {
|
||||
return '{ "data":';
|
||||
}
|
||||
|
||||
protected function xml_end() {
|
||||
$this->fill_collections();
|
||||
$end = (!empty($this->extra_output)) ? ', "collections": {'.$this->extra_output.'}' : '';
|
||||
foreach ($this->attributes as $k => $v)
|
||||
$end.=", \"".$k."\":\"".$v."\"";
|
||||
$end .= '}';
|
||||
return $end;
|
||||
}
|
||||
|
||||
/*! assign options collection to the column
|
||||
|
||||
@param name
|
||||
name of the column
|
||||
@param options
|
||||
array or connector object
|
||||
*/
|
||||
public function set_options($name,$options){
|
||||
if (is_array($options)){
|
||||
$str=array();
|
||||
foreach($options as $k => $v)
|
||||
$str[]='{"id":"'.$this->xmlentities($k).'", "value":"'.$this->xmlentities($v).'"}';
|
||||
$options=implode(",",$str);
|
||||
}
|
||||
$this->options[$name]=$options;
|
||||
}
|
||||
|
||||
|
||||
/*! generates xml description for options collections
|
||||
|
||||
@param list
|
||||
comma separated list of column names, for which options need to be generated
|
||||
*/
|
||||
protected function fill_collections($list=""){
|
||||
$options = array();
|
||||
foreach ($this->options as $k=>$v) {
|
||||
$name = $k;
|
||||
$option="\"{$name}\":[";
|
||||
if (!is_string($this->options[$name])){
|
||||
$data = json_encode($this->options[$name]->render());
|
||||
$option.=substr($data,1,-1);
|
||||
} else
|
||||
$option.=$this->options[$name];
|
||||
$option.="]";
|
||||
$options[] = $option;
|
||||
}
|
||||
$this->extra_output .= implode($this->data_separator, $options);
|
||||
}
|
||||
|
||||
|
||||
/*! output fetched data as XML
|
||||
@param res
|
||||
DB resultset
|
||||
*/
|
||||
protected function output_as_xml($res){
|
||||
$result = $this->render_set($res);
|
||||
if ($this->simple) return $result;
|
||||
|
||||
$data=$this->xml_start().json_encode($result).$this->xml_end();
|
||||
|
||||
if ($this->as_string) return $data;
|
||||
|
||||
$out = new OutputWriter($data, "");
|
||||
$out->set_type("json");
|
||||
$this->event->trigger("beforeOutput", $this, $out);
|
||||
$out->output("", true, $this->encoding);
|
||||
}
|
||||
|
||||
public function render_links($table,$id="",$fields=false,$extra=false,$relation_id=false) {
|
||||
$links = new JSONGanttLinksConnector($this->get_connection(),$this->names["db_class"]);
|
||||
$links->render_table($table,$id,$fields,$extra);
|
||||
$this->set_options("links", $links);
|
||||
}
|
||||
|
||||
|
||||
/*! render self
|
||||
process commands, output requested data as XML
|
||||
*/
|
||||
public function render(){
|
||||
$this->event->trigger("onInit", $this);
|
||||
EventMaster::trigger_static("connectorInit",$this);
|
||||
|
||||
if (!$this->as_string)
|
||||
$this->parse_request();
|
||||
$this->set_relation();
|
||||
|
||||
if ($this->live_update !== false && $this->updating!==false) {
|
||||
$this->live_update->get_updates();
|
||||
} else {
|
||||
if ($this->editing){
|
||||
if ($this->links_mode && isset($this->options["links"])) {
|
||||
$this->options["links"]->save();
|
||||
} else {
|
||||
$dp = new $this->names["data_class"]($this,$this->config,$this->request);
|
||||
$dp->process($this->config,$this->request);
|
||||
}
|
||||
} else {
|
||||
if (!$this->access->check("read")){
|
||||
LogMaster::log("Access control: read operation blocked");
|
||||
echo "Access denied";
|
||||
die();
|
||||
}
|
||||
$wrap = new SortInterface($this->request);
|
||||
$this->apply_sorts($wrap);
|
||||
$this->event->trigger("beforeSort",$wrap);
|
||||
$wrap->store();
|
||||
|
||||
$wrap = new FilterInterface($this->request);
|
||||
$this->apply_filters($wrap);
|
||||
$this->event->trigger("beforeFilter",$wrap);
|
||||
$wrap->store();
|
||||
|
||||
if ($this->model && method_exists($this->model, "get")){
|
||||
$this->sql = new ArrayDBDataWrapper();
|
||||
$result = new ArrayQueryWrapper(call_user_func(array($this->model, "get"), $this->request));
|
||||
$out = $this->output_as_xml($result);
|
||||
} else {
|
||||
$out = $this->output_as_xml($this->get_resource());
|
||||
|
||||
if ($out !== null) return $out;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
$this->end_run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class GanttLinksConnector extends OptionsConnector {
|
||||
public function render(){
|
||||
if (!$this->init_flag){
|
||||
$this->init_flag=true;
|
||||
return "";
|
||||
}
|
||||
|
||||
$res = $this->sql->select($this->request);
|
||||
return $this->render_set($res);
|
||||
}
|
||||
|
||||
public function save() {
|
||||
$dp = new $this->names["data_class"]($this,$this->config,$this->request);
|
||||
$dp->process($this->config,$this->request);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class JSONGanttLinksConnector extends JSONOptionsConnector {
|
||||
public function render(){
|
||||
if (!$this->init_flag){
|
||||
$this->init_flag=true;
|
||||
return "";
|
||||
}
|
||||
|
||||
$res = $this->sql->select($this->request);
|
||||
return $this->render_set($res);
|
||||
}
|
||||
|
||||
public function save() {
|
||||
$dp = new $this->names["data_class"]($this,$this->config,$this->request);
|
||||
$dp->process($this->config,$this->request);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
423
libraries/dhtmlxgantt/connector/grid_config.php
Normal file
423
libraries/dhtmlxgantt/connector/grid_config.php
Normal file
|
|
@ -0,0 +1,423 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
|
||||
class GridConfiguration{
|
||||
|
||||
/*! attaching header functionality
|
||||
*/
|
||||
protected $headerDelimiter = ',';
|
||||
protected $headerNames = false;
|
||||
protected $headerAttaches = array();
|
||||
protected $footerAttaches = array();
|
||||
protected $headerWidthsUnits = 'px';
|
||||
|
||||
protected $headerIds = false;
|
||||
protected $headerWidths = false;
|
||||
protected $headerTypes = false;
|
||||
protected $headerAlign = false;
|
||||
protected $headerVAlign = false;
|
||||
protected $headerSorts = false;
|
||||
protected $headerColors = false;
|
||||
protected $headerHidden = false;
|
||||
protected $headerFormat = false;
|
||||
|
||||
protected $convert_mode = false;
|
||||
|
||||
function __construct($headers = false){
|
||||
if ($headers === false || $headers === true )
|
||||
$this->headerNames = $headers;
|
||||
else
|
||||
$this->setHeader($headers);
|
||||
}
|
||||
|
||||
/*! brief convert list of parameters to an array
|
||||
@param param
|
||||
list of values or array of values
|
||||
@return array of parameters
|
||||
*/
|
||||
private function parse_param_array($param, $check=false, $default = ""){
|
||||
if (gettype($param) == 'string')
|
||||
$param = explode($this->headerDelimiter, $param);
|
||||
|
||||
if ($check){
|
||||
for ($i=0; $i < sizeof($param); $i++) {
|
||||
if (!array_key_exists($param[$i],$check))
|
||||
$param[$i] = $default;
|
||||
}
|
||||
}
|
||||
return $param;
|
||||
}
|
||||
|
||||
/*! sets delimiter for string arguments in attach header functions (default is ,)
|
||||
@param headerDelimiter
|
||||
string delimiter
|
||||
*/
|
||||
public function setHeaderDelimiter($headerDelimiter) {
|
||||
$this->headerDelimiter = $headerDelimiter;
|
||||
}
|
||||
|
||||
/*! sets header
|
||||
@param names
|
||||
array of names or string of names, delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function setHeader($names) {
|
||||
if ($names instanceof DataConfig){
|
||||
$out = array();
|
||||
for ($i=0; $i < sizeof($names->text); $i++)
|
||||
$out[]=$names->text[$i]["name"];
|
||||
$names = $out;
|
||||
}
|
||||
|
||||
$this->headerNames = $this->parse_param_array($names);
|
||||
}
|
||||
|
||||
/*! sets init columns width in pixels
|
||||
@param wp
|
||||
array of widths or string of widths, delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function setInitWidths($wp) {
|
||||
$this->headerWidths = $this->parse_param_array($wp);
|
||||
$this->headerWidthsUnits = 'px';
|
||||
}
|
||||
|
||||
/*! sets init columns width in persents
|
||||
@param wp
|
||||
array of widths or string of widths, delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function setInitWidthsP($wp) {
|
||||
$this->setInitWidths($wp);
|
||||
$this->headerWidthsUnits = '%';
|
||||
}
|
||||
|
||||
/*! sets columns align
|
||||
@param alStr
|
||||
array of aligns or string of aligns, delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function setColAlign($alStr) {
|
||||
$this->headerAlign = $this->parse_param_array($alStr,
|
||||
array("right"=>1, "left"=>1, "center"=>1, "justify"=>1),
|
||||
"left");
|
||||
}
|
||||
|
||||
/*! sets columns vertical align
|
||||
@param alStr
|
||||
array of vertical aligns or string of vertical aligns, delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function setColVAlign($alStr) {
|
||||
$this->headerVAlign = $this->parse_param_array($alStr,
|
||||
array("baseline"=>1, "sub"=>1, "super"=>1, "top"=>1, "text-top"=>1, "middle"=>1, "bottom"=>1, "text-bottom"=>1),
|
||||
"top");
|
||||
}
|
||||
|
||||
/*! sets column types
|
||||
@param typeStr
|
||||
array of types or string of types, delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function setColTypes($typeStr) {
|
||||
$this->headerTypes = $this->parse_param_array($typeStr);
|
||||
}
|
||||
|
||||
/*! sets columns sorting
|
||||
@param sortStr
|
||||
array if sortings or string of sortings, delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function setColSorting($sortStr) {
|
||||
$this->headerSorts = $this->parse_param_array($sortStr);
|
||||
}
|
||||
|
||||
/*! sets columns colors
|
||||
@param colorStr
|
||||
array of colors or string of colors, delimited by headerDelimiter (default is ,)
|
||||
if (color should not be applied it's value should be null)
|
||||
*/
|
||||
public function setColColor($colorStr) {
|
||||
$this->headerColors = $this->parse_param_array($colorStr);
|
||||
}
|
||||
|
||||
/*! sets hidden columns
|
||||
@param hidStr
|
||||
array of bool values or string of bool values, delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function setColHidden($hidStr) {
|
||||
$this->headerHidden = $this->parse_param_array($hidStr);
|
||||
}
|
||||
|
||||
/*! sets columns id
|
||||
@param idsStr
|
||||
array of ids or string of ids, delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function setColIds($idsStr) {
|
||||
$this->headerIds = $this->parse_param_array($idsStr);
|
||||
}
|
||||
|
||||
/*! sets number/date format
|
||||
@param formatArr
|
||||
array of mask formats for number/dates , delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function setColFormat($formatArr) {
|
||||
$this->headerFormat = $this->parse_param_array($formatArr);
|
||||
}
|
||||
|
||||
/*! attaches header
|
||||
@param values
|
||||
array of header names or string of header names, delimited by headerDelimiter (default is ,)
|
||||
@param styles
|
||||
array of header styles or string of header styles, delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function attachHeader($values, $styles = null, $footer = false) {
|
||||
$header = array();
|
||||
$header['values'] = $this->parse_param_array($values);
|
||||
if ($styles != null) {
|
||||
$header['styles'] = $this->parse_param_array($styles);
|
||||
} else {
|
||||
$header['styles'] = null;
|
||||
}
|
||||
if ($footer)
|
||||
$this->footerAttaches[] = $header;
|
||||
else
|
||||
$this->headerAttaches[] = $header;
|
||||
}
|
||||
|
||||
/*! attaches footer
|
||||
@param values
|
||||
array of footer names or string of footer names, delimited by headerDelimiter (default is ,)
|
||||
@param styles
|
||||
array of footer styles or string of footer styles, delimited by headerDelimiter (default is ,)
|
||||
*/
|
||||
public function attachFooter($values, $styles = null) {
|
||||
$this->attachHeader($values, $styles, true);
|
||||
}
|
||||
|
||||
private function auto_fill($mode){
|
||||
$headerWidths = array();
|
||||
$headerTypes = array();
|
||||
$headerSorts = array();
|
||||
$headerAttaches = array();
|
||||
|
||||
for ($i=0; $i < sizeof($this->headerNames); $i++) {
|
||||
$headerWidths[] = 100;
|
||||
$headerTypes[] = "ro";
|
||||
$headerSorts[] = "connector";
|
||||
$headerAttaches[] = "#connector_text_filter";
|
||||
}
|
||||
if ($this->headerWidths == false)
|
||||
$this->setInitWidths($headerWidths);
|
||||
if ($this->headerTypes == false)
|
||||
$this->setColTypes($headerTypes);
|
||||
|
||||
if ($mode){
|
||||
if ($this->headerSorts == false)
|
||||
$this->setColSorting($headerSorts);
|
||||
$this->attachHeader($headerAttaches);
|
||||
}
|
||||
}
|
||||
|
||||
public function defineOptions($conn){
|
||||
if (!$conn->is_first_call()) return; //render head only for first call
|
||||
|
||||
$config = $conn->get_config();
|
||||
$full_header = ($this->headerNames === true);
|
||||
|
||||
if (gettype($this->headerNames) == 'boolean') //auto-config
|
||||
$this->setHeader($config);
|
||||
$this->auto_fill($full_header);
|
||||
|
||||
if (isset($_GET["dhx_colls"])) return;
|
||||
|
||||
$fillList = array();
|
||||
for ($i = 0; $i < count($this->headerNames); $i++)
|
||||
if ($this->headerTypes[$i] == "co" || $this->headerTypes[$i] == "coro")
|
||||
$fillList[$i] = true;
|
||||
|
||||
for ($i = 0; $i < count($this->headerAttaches); $i++) {
|
||||
for ($j = 0; $j < count($this->headerAttaches[$i]['values']); $j++) {
|
||||
if ($this->headerAttaches[$i]['values'][$j] == "#connector_select_filter"
|
||||
|| $this->headerAttaches[$i]['values'][$j] == "#select_filter") {
|
||||
$fillList[$j] = true;;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$temp = array();
|
||||
foreach($fillList as $k => $v)
|
||||
$temp[] = $k;
|
||||
if (count($temp))
|
||||
$_GET["dhx_colls"] = implode(",",$temp);
|
||||
}
|
||||
|
||||
|
||||
/*! gets header as array
|
||||
*/
|
||||
private function getHeaderArray() {
|
||||
$head = Array();
|
||||
$head[0] = $this->headerNames;
|
||||
$head = $this->getAttaches($head, $this->headerAttaches);
|
||||
return $head;
|
||||
}
|
||||
|
||||
|
||||
/*! get footer as array
|
||||
*/
|
||||
private function getFooterArray() {
|
||||
$foot = Array();
|
||||
$foot = $this->getAttaches($foot, $this->footerAttaches);
|
||||
return $foot;
|
||||
}
|
||||
|
||||
|
||||
/*! gets array of data with attaches
|
||||
*/
|
||||
private function getAttaches($to, $from) {
|
||||
for ($i = 0; $i < count($from); $i++) {
|
||||
$line = $from[$i]['values'];
|
||||
$to[] = $line;
|
||||
}
|
||||
return $to;
|
||||
}
|
||||
|
||||
|
||||
/*! calculates rowspan array according #cspan markers
|
||||
*/
|
||||
private function processCspan($data) {
|
||||
$rspan = Array();
|
||||
for ($i = 0; $i < count($data); $i++) {
|
||||
$last = 0;
|
||||
$rspan[$i] = Array();
|
||||
for ($j = 0; $j < count($data[$i]); $j++) {
|
||||
$rspan[$i][$j] = 0;
|
||||
if ($data[$i][$j] === '#cspan') {
|
||||
$rspan[$i][$last]++;
|
||||
} else {
|
||||
$last = $j;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $rspan;
|
||||
}
|
||||
|
||||
|
||||
/*! calculates colspan array according #rspan markers
|
||||
*/
|
||||
private function processRspan($data) {
|
||||
$last = Array();
|
||||
$cspan = Array();
|
||||
for ($i = 0; $i < count($data); $i++) {
|
||||
$cspan[$i] = Array();
|
||||
for ($j = 0; $j < count($data[$i]); $j++) {
|
||||
$cspan[$i][$j] = 0;
|
||||
if (!isset($last[$j])) $last[$j] = 0;
|
||||
if ($data[$i][$j] === '#rspan') {
|
||||
$cspan[$last[$j]][$j]++;
|
||||
} else {
|
||||
$last[$j] = $i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $cspan;
|
||||
}
|
||||
|
||||
|
||||
/*! sets mode of output format: usual mode or convert mode.
|
||||
* @param mode
|
||||
* true - convert mode, false - otherwise
|
||||
*/
|
||||
public function set_convert_mode($mode) {
|
||||
$this->convert_mode = $mode;
|
||||
}
|
||||
|
||||
|
||||
/*! adds header configuration in output XML
|
||||
*/
|
||||
public function attachHeaderToXML($conn, $out) {
|
||||
if (!$conn->is_first_call()) return; //render head only for first call
|
||||
|
||||
$head = $this->getHeaderArray();
|
||||
$foot = $this->getFooterArray();
|
||||
$rspan = $this->processRspan($head);
|
||||
$cspan = $this->processCspan($head);
|
||||
|
||||
$str = '<head>';
|
||||
|
||||
if ($this->convert_mode) $str .= "<columns>";
|
||||
|
||||
for ($i = 0; $i < count($this->headerNames); $i++) {
|
||||
$str .= '<column';
|
||||
$str .= ' type="'. $this->headerTypes[$i].'"';
|
||||
$str .= ' width="'.$this->headerWidths[$i].'"';
|
||||
$str .= $this->headerIds ? ' id="'.$this->headerIds[$i].'"' : '';
|
||||
$str .= $this->headerAlign[$i] ? ' align="'.$this->headerAlign[$i].'"' : '';
|
||||
$str .= $this->headerVAlign[$i] ? ' valign="'.$this->headerVAlign[$i].'"' : '';
|
||||
$str .= $this->headerSorts[$i] ? ' sort="'.$this->headerSorts[$i].'"' : '';
|
||||
$str .= $this->headerColors[$i] ? ' color="'.$this->headerColors[$i].'"' : '';
|
||||
$str .= $this->headerHidden[$i] ? ' hidden="'.$this->headerHidden[$i].'"' : '';
|
||||
$str .= $this->headerFormat[$i] ? ' format="'.$this->headerFormat[$i].'"' : '';
|
||||
$str .= $cspan[0][$i] ? ' colspan="'.($cspan[0][$i] + 1).'"' : '';
|
||||
$str .= $rspan[0][$i] ? ' rowspan="'.($rspan[0][$i] + 1).'"' : '';
|
||||
$str .= '>'.$this->headerNames[$i].'</column>';
|
||||
}
|
||||
|
||||
if (!$this->convert_mode) {
|
||||
$str .= '<settings><colwidth>'.$this->headerWidthsUnits.'</colwidth></settings>';
|
||||
if ((count($this->headerAttaches) > 0)||(count($this->footerAttaches) > 0)) {
|
||||
$str .= '<afterInit>';
|
||||
}
|
||||
for ($i = 0; $i < count($this->headerAttaches); $i++) {
|
||||
$str .= '<call command="attachHeader">';
|
||||
$str .= '<param>'.implode(",",$this->headerAttaches[$i]['values']).'</param>';
|
||||
if ($this->headerAttaches[$i]['styles'] != null) {
|
||||
$str .= '<param>'.implode(",",$this->headerAttaches[$i]['styles']).'</param>';
|
||||
}
|
||||
$str .= '</call>';
|
||||
}
|
||||
for ($i = 0; $i < count($this->footerAttaches); $i++) {
|
||||
$str .= '<call command="attachFooter">';
|
||||
$str .= '<param>'.implode(",",$this->footerAttaches[$i]['values']).'</param>';
|
||||
if ($this->footerAttaches[$i]['styles'] != null) {
|
||||
$str .= '<param>'.implode(",",$this->footerAttaches[$i]['styles']).'</param>';
|
||||
}
|
||||
$str .= '</call>';
|
||||
}
|
||||
if ((count($this->headerAttaches) > 0)||(count($this->footerAttaches) > 0)) {
|
||||
$str .= '</afterInit>';
|
||||
}
|
||||
} else {
|
||||
$str .= "</columns>";
|
||||
for ($i = 1; $i < count($head); $i++) {
|
||||
$str .= "<columns>";
|
||||
for ($j = 0; $j < count($head[$i]); $j++) {
|
||||
$str .= '<column';
|
||||
$str .= $cspan[$i][$j] ? ' colspan="'.($cspan[$i][$j] + 1).'"' : '';
|
||||
$str .= $rspan[$i][$j] ? ' rowspan="'.($rspan[$i][$j] + 1).'"' : '';
|
||||
$str .= '>'.$head[$i][$j].'</column>';
|
||||
}
|
||||
$str .= "</columns>\n";
|
||||
}
|
||||
}
|
||||
$str .= '</head>';
|
||||
|
||||
|
||||
if ($this->convert_mode && count($foot) > 0) {
|
||||
$rspan = $this->processRspan($foot);
|
||||
$cspan = $this->processCspan($foot);
|
||||
$str .= "<foot>";
|
||||
for ($i = 0; $i < count($foot); $i++) {
|
||||
$str .= "<columns>";
|
||||
for ($j = 0; $j < count($foot[$i]); $j++) {
|
||||
$str .= '<column';
|
||||
$str .= $cspan[$i][$j] ? ' colspan="'.($cspan[$i][$j] + 1).'"' : '';
|
||||
$str .= $rspan[$i][$j] ? ' rowspan="'.($rspan[$i][$j] + 1).'"' : '';
|
||||
$str .= '>'.$foot[$i][$j].'</column>';
|
||||
}
|
||||
$str .= "</columns>\n";
|
||||
}
|
||||
$str .= "</foot>";
|
||||
}
|
||||
|
||||
$out->add($str);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
269
libraries/dhtmlxgantt/connector/grid_connector.php
Normal file
269
libraries/dhtmlxgantt/connector/grid_connector.php
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("base_connector.php");
|
||||
require_once("grid_config.php");
|
||||
|
||||
//require_once("grid_dataprocessor.php");
|
||||
|
||||
/*! DataItem class for Grid component
|
||||
**/
|
||||
|
||||
class GridDataItem extends DataItem{
|
||||
protected $row_attrs;//!< hash of row attributes
|
||||
protected $cell_attrs;//!< hash of cell attributes
|
||||
|
||||
function __construct($data,$name,$index=0){
|
||||
parent::__construct($data,$name,$index);
|
||||
|
||||
$this->row_attrs=array();
|
||||
$this->cell_attrs=array();
|
||||
}
|
||||
/*! set color of row
|
||||
|
||||
@param color
|
||||
color of row
|
||||
*/
|
||||
function set_row_color($color){
|
||||
$this->row_attrs["bgColor"]=$color;
|
||||
}
|
||||
/*! set style of row
|
||||
|
||||
@param color
|
||||
color of row
|
||||
*/
|
||||
function set_row_style($color){
|
||||
$this->row_attrs["style"]=$color;
|
||||
}
|
||||
/*! assign custom style to the cell
|
||||
|
||||
@param name
|
||||
name of column
|
||||
@param value
|
||||
css style string
|
||||
*/
|
||||
function set_cell_style($name,$value){
|
||||
$this->set_cell_attribute($name,"style",$value);
|
||||
}
|
||||
/*! assign custom class to specific cell
|
||||
|
||||
@param name
|
||||
name of column
|
||||
@param value
|
||||
css class name
|
||||
*/
|
||||
function set_cell_class($name,$value){
|
||||
$this->set_cell_attribute($name,"class",$value);
|
||||
}
|
||||
/*! set custom cell attribute
|
||||
|
||||
@param name
|
||||
name of column
|
||||
@param attr
|
||||
name of attribute
|
||||
@param value
|
||||
value of attribute
|
||||
*/
|
||||
function set_cell_attribute($name,$attr,$value){
|
||||
if (!array_key_exists($name, $this->cell_attrs)) $this->cell_attrs[$name]=array();
|
||||
$this->cell_attrs[$name][$attr]=$value;
|
||||
}
|
||||
|
||||
/*! set custom row attribute
|
||||
|
||||
@param attr
|
||||
name of attribute
|
||||
@param value
|
||||
value of attribute
|
||||
*/
|
||||
function set_row_attribute($attr,$value){
|
||||
$this->row_attrs[$attr]=$value;
|
||||
}
|
||||
|
||||
/*! return self as XML string, starting part
|
||||
*/
|
||||
public function to_xml_start(){
|
||||
if ($this->skip) return "";
|
||||
|
||||
$str="<row id='".$this->xmlentities($this->get_id())."'";
|
||||
foreach ($this->row_attrs as $k=>$v)
|
||||
$str.=" ".$k."='".$v."'";
|
||||
$str.=">";
|
||||
for ($i=0; $i < sizeof($this->config->text); $i++){
|
||||
$str.="<cell";
|
||||
$name=$this->config->text[$i]["name"];
|
||||
$xmlcontent = false;
|
||||
if (isset($this->cell_attrs[$name])){
|
||||
$cattrs=$this->cell_attrs[$name];
|
||||
foreach ($cattrs as $k => $v){
|
||||
$str.=" ".$k."='".$this->xmlentities($v)."'";
|
||||
if ($k == "xmlcontent")
|
||||
$xmlcontent = true;
|
||||
}
|
||||
}
|
||||
$value = isset($this->data[$name]) ? $this->data[$name] : '';
|
||||
if (!$xmlcontent)
|
||||
$str.="><![CDATA[".$value."]]></cell>";
|
||||
else
|
||||
$str.=">".$value."</cell>";
|
||||
}
|
||||
if ($this->userdata !== false)
|
||||
foreach ($this->userdata as $key => $value)
|
||||
$str.="<userdata name='".$key."'><![CDATA[".$value."]]></userdata>";
|
||||
|
||||
return $str;
|
||||
}
|
||||
/*! return self as XML string, ending part
|
||||
*/
|
||||
public function to_xml_end(){
|
||||
if ($this->skip) return "";
|
||||
|
||||
return "</row>";
|
||||
}
|
||||
}
|
||||
/*! Connector for the dhtmlxgrid
|
||||
**/
|
||||
class GridConnector extends Connector{
|
||||
|
||||
/*! 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="GridDataItem";
|
||||
if (!$data_type) $data_type="GridDataProcessor";
|
||||
if (!$render_type) $render_type="RenderStrategy";
|
||||
parent::__construct($res,$type,$item_type,$data_type,$render_type);
|
||||
}
|
||||
|
||||
|
||||
protected function parse_request(){
|
||||
parent::parse_request();
|
||||
|
||||
if (isset($_GET["dhx_colls"]))
|
||||
$this->fill_collections($_GET["dhx_colls"]);
|
||||
}
|
||||
protected function resolve_parameter($name){
|
||||
if (intval($name).""==$name)
|
||||
return $this->config->text[intval($name)]["db_name"];
|
||||
return $name;
|
||||
}
|
||||
|
||||
/*! replace xml unsafe characters
|
||||
|
||||
@param string
|
||||
string to be escaped
|
||||
@return
|
||||
escaped string
|
||||
*/
|
||||
protected function xmlentities($string) {
|
||||
return str_replace( array( '&', '"', "'", '<', '>', '’' ), array( '&' , '"', ''' , '<' , '>', ''' ), $string);
|
||||
}
|
||||
|
||||
/*! assign options collection to the column
|
||||
|
||||
@param name
|
||||
name of the column
|
||||
@param options
|
||||
array or connector object
|
||||
*/
|
||||
public function set_options($name,$options){
|
||||
if (is_array($options)){
|
||||
$str="";
|
||||
foreach($options as $k => $v)
|
||||
$str.="<item value='".$this->xmlentities($k)."' label='".$this->xmlentities($v)."' />";
|
||||
$options=$str;
|
||||
}
|
||||
$this->options[$name]=$options;
|
||||
}
|
||||
/*! generates xml description for options collections
|
||||
|
||||
@param list
|
||||
comma separated list of column names, for which options need to be generated
|
||||
*/
|
||||
protected function fill_collections($list=""){
|
||||
$names=explode(",",$list);
|
||||
for ($i=0; $i < sizeof($names); $i++) {
|
||||
$name = $this->resolve_parameter($names[$i]);
|
||||
if (!array_key_exists($name,$this->options)){
|
||||
$this->options[$name] = new DistinctOptionsConnector($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);
|
||||
}
|
||||
|
||||
$this->extra_output.="<coll_options for='{$names[$i]}'>";
|
||||
if (!is_string($this->options[$name]))
|
||||
$this->extra_output.=$this->options[$name]->render();
|
||||
else
|
||||
$this->extra_output.=$this->options[$name];
|
||||
$this->extra_output.="</coll_options>";
|
||||
}
|
||||
}
|
||||
|
||||
/*! renders self as xml, starting part
|
||||
*/
|
||||
protected function xml_start(){
|
||||
$attributes = "";
|
||||
foreach($this->attributes as $k=>$v)
|
||||
$attributes .= " ".$k."='".$v."'";
|
||||
|
||||
if ($this->dload){
|
||||
if ($pos=$this->request->get_start())
|
||||
return "<rows pos='".$pos."'".$attributes.">";
|
||||
else
|
||||
return "<rows total_count='".$this->sql->get_size($this->request)."'".$attributes.">";
|
||||
}
|
||||
else
|
||||
return "<rows".$attributes.">";
|
||||
}
|
||||
|
||||
|
||||
/*! renders self as xml, ending part
|
||||
*/
|
||||
protected function xml_end(){
|
||||
return $this->extra_output."</rows>";
|
||||
}
|
||||
|
||||
public function set_config($config = false){
|
||||
if (gettype($config) == 'boolean')
|
||||
$config = new GridConfiguration($config);
|
||||
|
||||
$this->event->attach("beforeOutput", Array($config, "attachHeaderToXML"));
|
||||
$this->event->attach("onInit", Array($config, "defineOptions"));
|
||||
}
|
||||
}
|
||||
|
||||
/*! DataProcessor class for Grid component
|
||||
**/
|
||||
class GridDataProcessor extends DataProcessor{
|
||||
|
||||
/*! convert incoming data name to valid db name
|
||||
converts c0..cN to valid field names
|
||||
@param data
|
||||
data name from incoming request
|
||||
@return
|
||||
related db_name
|
||||
*/
|
||||
function name_data($data){
|
||||
if ($data == "gr_id") return $this->config->id["name"];
|
||||
$parts=explode("c",$data);
|
||||
if ($parts[0]=="" && ((string)intval($parts[1]))==$parts[1])
|
||||
if (sizeof($this->config->text)>intval($parts[1]))
|
||||
return $this->config->text[intval($parts[1])]["name"];
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
?>
|
||||
48
libraries/dhtmlxgantt/connector/keygrid_connector.php
Normal file
48
libraries/dhtmlxgantt/connector/keygrid_connector.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("grid_connector.php");
|
||||
class KeyGridConnector extends GridConnector{
|
||||
public function __construct($res,$type=false,$item_type=false,$data_type=false){
|
||||
if (!$item_type) $item_type="GridDataItem";
|
||||
if (!$data_type) $data_type="KeyGridDataProcessor";
|
||||
parent::__construct($res,$type,$item_type,$data_type);
|
||||
|
||||
$this->event->attach("beforeProcessing",array($this,"before_check_key"));
|
||||
$this->event->attach("afterProcessing",array($this,"after_check_key"));
|
||||
}
|
||||
|
||||
public function before_check_key($action){
|
||||
if ($action->get_value($this->config->id["name"])=="")
|
||||
$action->error();
|
||||
}
|
||||
public function after_check_key($action){
|
||||
if ($action->get_status()=="inserted" || $action->get_status()=="updated"){
|
||||
$action->success($action->get_value($this->config->id["name"]));
|
||||
$action->set_status("inserted");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class KeyGridDataProcessor extends DataProcessor{
|
||||
|
||||
/*! convert incoming data name to valid db name
|
||||
converts c0..cN to valid field names
|
||||
@param data
|
||||
data name from incoming request
|
||||
@return
|
||||
related db_name
|
||||
*/
|
||||
function name_data($data){
|
||||
if ($data == "gr_id") return "__dummy__id__"; //ignore ID
|
||||
$parts=explode("c",$data);
|
||||
if ($parts[0]=="" && intval($parts[1])==$parts[1])
|
||||
return $this->config->text[intval($parts[1])]["name"];
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
28
libraries/dhtmlxgantt/connector/mixed_connector.php
Normal file
28
libraries/dhtmlxgantt/connector/mixed_connector.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("base_connector.php");
|
||||
|
||||
class MixedConnector extends Connector {
|
||||
|
||||
protected $connectors = array();
|
||||
|
||||
public function add($name, $conn) {
|
||||
$this->connectors[$name] = $conn;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$result = "{";
|
||||
$parts = array();
|
||||
foreach($this->connectors as $name => $conn) {
|
||||
$conn->asString(true);
|
||||
$parts[] = "\"".$name."\":".($conn->render())."\n";
|
||||
}
|
||||
$result .= implode(",\n", $parts)."}";
|
||||
echo $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
45
libraries/dhtmlxgantt/connector/options_connector.php
Normal file
45
libraries/dhtmlxgantt/connector/options_connector.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("base_connector.php");
|
||||
|
||||
/*! DataItem class for dhxForm:options
|
||||
**/
|
||||
class OptionsDataItem extends DataItem{
|
||||
/*! return self as XML string
|
||||
*/
|
||||
function to_xml(){
|
||||
if ($this->skip) return "";
|
||||
$str ="";
|
||||
|
||||
$str .= "<item value=\"".$this->xmlentities($this->data[$this->config->data[0]['db_name']])."\" label=\"".$this->xmlentities($this->data[$this->config->data[1]['db_name']])."\" />";
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/*! Connector class for dhtmlxForm:options
|
||||
**/
|
||||
class SelectOptionsConnector extends Connector{
|
||||
|
||||
/*! 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){
|
||||
if (!$item_type) $item_type="OptionsDataItem";
|
||||
parent::__construct($res,$type,$item_type,$data_type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
230
libraries/dhtmlxgantt/connector/scheduler_connector.php
Normal file
230
libraries/dhtmlxgantt/connector/scheduler_connector.php
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("base_connector.php");
|
||||
require_once("data_connector.php");
|
||||
|
||||
/*! DataItem class for Scheduler component
|
||||
**/
|
||||
class SchedulerDataItem extends DataItem{
|
||||
/*! return self as XML string
|
||||
*/
|
||||
function to_xml(){
|
||||
if ($this->skip) return "";
|
||||
|
||||
$str="<event id='".$this->get_id()."' >";
|
||||
$str.="<start_date><![CDATA[".$this->data[$this->config->text[0]["name"]]."]]></start_date>";
|
||||
$str.="<end_date><![CDATA[".$this->data[$this->config->text[1]["name"]]."]]></end_date>";
|
||||
$str.="<text><![CDATA[".$this->data[$this->config->text[2]["name"]]."]]></text>";
|
||||
for ($i=3; $i<sizeof($this->config->text); $i++){
|
||||
$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>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Connector class for dhtmlxScheduler
|
||||
**/
|
||||
class SchedulerConnector extends Connector{
|
||||
|
||||
protected $extra_output="";//!< extra info which need to be sent to client side
|
||||
protected $options=array();//!< hash of OptionsConnector
|
||||
|
||||
|
||||
/*! assign options collection to the column
|
||||
|
||||
@param name
|
||||
name of the column
|
||||
@param options
|
||||
array or connector object
|
||||
*/
|
||||
public function set_options($name,$options){
|
||||
if (is_array($options)){
|
||||
$str="";
|
||||
foreach($options as $k => $v)
|
||||
$str.="<item value='".$this->xmlentities($k)."' label='".$this->xmlentities($v)."' />";
|
||||
$options=$str;
|
||||
}
|
||||
$this->options[$name]=$options;
|
||||
}
|
||||
|
||||
|
||||
/*! constructor
|
||||
|
||||
Here initilization of all Masters occurs, execution timer initialized
|
||||
@param res
|
||||
db connection resource
|
||||
@param type
|
||||
string , which hold type of database ( MySQL or Postgre ), optional, instead of short DB name, full name of DataWrapper-based class can be provided
|
||||
@param item_type
|
||||
name of class, which will be used for item rendering, optional, DataItem will be used by default
|
||||
@param data_type
|
||||
name of class which will be used for dataprocessor calls handling, optional, DataProcessor class will be used by default.
|
||||
* @param render_type
|
||||
name of class which will be used for rendering.
|
||||
*/
|
||||
public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
|
||||
if (!$item_type) $item_type="SchedulerDataItem";
|
||||
if (!$data_type) $data_type="SchedulerDataProcessor";
|
||||
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
|
||||
function parse_request(){
|
||||
parent::parse_request();
|
||||
if (count($this->config->text)){
|
||||
if (isset($_GET["to"]))
|
||||
$this->request->set_filter($this->config->text[0]["name"],$_GET["to"],"<");
|
||||
if (isset($_GET["from"]))
|
||||
$this->request->set_filter($this->config->text[1]["name"],$_GET["from"],">");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! DataProcessor class for Scheduler component
|
||||
**/
|
||||
class SchedulerDataProcessor extends DataProcessor{
|
||||
function name_data($data){
|
||||
if ($data=="start_date")
|
||||
return $this->config->text[0]["db_name"];
|
||||
if ($data=="id")
|
||||
return $this->config->id["db_name"];
|
||||
if ($data=="end_date")
|
||||
return $this->config->text[1]["db_name"];
|
||||
if ($data=="text")
|
||||
return $this->config->text[2]["db_name"];
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
if ($this->userdata !== false)
|
||||
foreach ($this->userdata as $key => $value)
|
||||
$obj[$key]=$value;
|
||||
|
||||
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();
|
||||
$end = (!empty($this->extra_output)) ? ', "collections": {'.$this->extra_output.'}' : '';
|
||||
foreach ($this->attributes as $k => $v)
|
||||
$end.=", \"".$k."\":\"".$v."\"";
|
||||
$end .= '}';
|
||||
return $end;
|
||||
}
|
||||
|
||||
/*! assign options collection to the column
|
||||
|
||||
@param name
|
||||
name of the column
|
||||
@param options
|
||||
array or connector object
|
||||
*/
|
||||
public function set_options($name,$options){
|
||||
if (is_array($options)){
|
||||
$str=array();
|
||||
foreach($options as $k => $v)
|
||||
$str[]='{"id":"'.$this->xmlentities($k).'", "value":"'.$this->xmlentities($v).'"}';
|
||||
$options=implode(",",$str);
|
||||
}
|
||||
$this->options[$name]=$options;
|
||||
}
|
||||
|
||||
|
||||
/*! generates xml description for options collections
|
||||
|
||||
@param list
|
||||
comma separated list of column names, for which options need to be generated
|
||||
*/
|
||||
protected function fill_collections($list=""){
|
||||
$options = array();
|
||||
foreach ($this->options as $k=>$v) {
|
||||
$name = $k;
|
||||
$option="\"{$name}\":[";
|
||||
if (!is_string($this->options[$name])){
|
||||
$data = json_encode($this->options[$name]->render());
|
||||
$option.=substr($data,1,-1);
|
||||
} else
|
||||
$option.=$this->options[$name];
|
||||
$option.="]";
|
||||
$options[] = $option;
|
||||
}
|
||||
$this->extra_output .= implode($this->data_separator, $options);
|
||||
}
|
||||
|
||||
|
||||
/*! output fetched data as XML
|
||||
@param res
|
||||
DB resultset
|
||||
*/
|
||||
protected function output_as_xml($res){
|
||||
$result = $this->render_set($res);
|
||||
if ($this->simple) return $result;
|
||||
|
||||
$data=$this->xml_start().json_encode($result).$this->xml_end();
|
||||
|
||||
if ($this->as_string) return $data;
|
||||
|
||||
$out = new OutputWriter($data, "");
|
||||
$out->set_type("json");
|
||||
$this->event->trigger("beforeOutput", $this, $out);
|
||||
$out->output("", true, $this->encoding);
|
||||
}
|
||||
}
|
||||
?>
|
||||
508
libraries/dhtmlxgantt/connector/strategy.php
Normal file
508
libraries/dhtmlxgantt/connector/strategy.php
Normal file
|
|
@ -0,0 +1,508 @@
|
|||
<?php
|
||||
|
||||
class RenderStrategy {
|
||||
|
||||
protected $conn = null;
|
||||
|
||||
public function __construct($conn) {
|
||||
$this->conn = $conn;
|
||||
}
|
||||
|
||||
/*! adds mix fields into DataConfig
|
||||
* @param config
|
||||
* DataConfig object
|
||||
* @param mix
|
||||
* mix structure
|
||||
*/
|
||||
protected function mix($config, $mix) {
|
||||
for ($i = 0; $i < count($mix); $i++) {
|
||||
if ($config->is_field($mix[$i]['name'])===-1) {
|
||||
$config->add_field($mix[$i]['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! remove mix fields from DataConfig
|
||||
* @param config
|
||||
* DataConfig object
|
||||
* @param mix
|
||||
* mix structure
|
||||
*/
|
||||
protected function unmix($config, $mix) {
|
||||
for ($i = 0; $i < count($mix); $i++) {
|
||||
if ($config->is_field($mix[$i]['name'])!==-1) {
|
||||
$config->remove_field_full($mix[$i]['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! adds mix fields in item
|
||||
* simple mix adds only strings specified by user
|
||||
* @param mix
|
||||
* mix structure
|
||||
* @param data
|
||||
* array of selected data
|
||||
*/
|
||||
protected function simple_mix($mix, $data) {
|
||||
// get mix details
|
||||
for ($i = 0; $i < count($mix); $i++)
|
||||
$data[$mix[$i]["name"]] = is_object($mix[$i]["value"]) ? "" : $mix[$i]["value"];
|
||||
return $data;
|
||||
}
|
||||
|
||||
/*! adds mix fields in item
|
||||
* complex mix adds strings specified by user and results of subrequests
|
||||
* @param mix
|
||||
* mix structure
|
||||
* @param data
|
||||
* array of selected data
|
||||
*/
|
||||
protected function complex_mix($mix, $data) {
|
||||
// get mix details
|
||||
for ($i = 0; $i < count($mix); $i++) {
|
||||
$mixname = $mix[$i]["name"];
|
||||
if ($mix[$i]['filter'] !== false) {
|
||||
$subconn = $mix[$i]["value"];
|
||||
$filter = $mix[$i]["filter"];
|
||||
|
||||
// setting relationships
|
||||
$subconn->clear_filter();
|
||||
foreach ($filter as $k => $v)
|
||||
if (isset($data[$v]))
|
||||
$subconn->filter($k, $data[$v], "=");
|
||||
else
|
||||
throw new Exception('There was no such data field registered as: '.$k);
|
||||
|
||||
$subconn->asString(true);
|
||||
$data[$mixname]=$subconn->simple_render();
|
||||
if (is_array($data[$mixname]) && count($data[$mixname]) == 1)
|
||||
$data[$mixname] = $data[$mixname][0];
|
||||
} else {
|
||||
$data[$mixname] = $mix[$i]["value"];
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/*! render from DB resultset
|
||||
@param res
|
||||
DB resultset
|
||||
process commands, output requested data as XML
|
||||
*/
|
||||
public function render_set($res, $name, $dload, $sep, $config, $mix){
|
||||
$output="";
|
||||
$index=0;
|
||||
$conn = $this->conn;
|
||||
$this->mix($config, $mix);
|
||||
$conn->event->trigger("beforeRenderSet",$conn,$res,$config);
|
||||
while ($data=$conn->sql->get_next($res)){
|
||||
$data = $this->simple_mix($mix, $data);
|
||||
|
||||
$data = new $name($data,$config,$index);
|
||||
if ($data->get_id()===false)
|
||||
$data->set_id($conn->uuid());
|
||||
$conn->event->trigger("beforeRender",$data);
|
||||
$output.=$data->to_xml().$sep;
|
||||
$index++;
|
||||
}
|
||||
$this->unmix($config, $mix);
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class JSONRenderStrategy extends RenderStrategy {
|
||||
|
||||
/*! render from DB resultset
|
||||
@param res
|
||||
DB resultset
|
||||
process commands, output requested data as json
|
||||
*/
|
||||
public function render_set($res, $name, $dload, $sep, $config, $mix){
|
||||
$output=array();
|
||||
$index=0;
|
||||
$conn = $this->conn;
|
||||
$this->mix($config, $mix);
|
||||
$conn->event->trigger("beforeRenderSet",$conn,$res,$config);
|
||||
while ($data=$conn->sql->get_next($res)){
|
||||
$data = $this->complex_mix($mix, $data);
|
||||
$data = new $name($data,$config,$index);
|
||||
if ($data->get_id()===false)
|
||||
$data->set_id($conn->uuid());
|
||||
$conn->event->trigger("beforeRender",$data);
|
||||
$item = $data->to_xml();
|
||||
if ($item !== false)
|
||||
$output[]=$item;
|
||||
$index++;
|
||||
}
|
||||
$this->unmix($config, $mix);
|
||||
return $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, $config, $mix){
|
||||
$output="";
|
||||
$index=0;
|
||||
$conn = $this->conn;
|
||||
$config_copy = new DataConfig($config);
|
||||
$this->mix($config, $mix);
|
||||
while ($data=$conn->sql->get_next($res)){
|
||||
$data = $this->simple_mix($mix, $data);
|
||||
$data = new $name($data,$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_fieldset(implode(",",$config_copy->db_names_list($conn->sql)));
|
||||
$sub_request->set_relation($data->get_id());
|
||||
$output.=$this->render_set($conn->sql->select($sub_request), $name, $dload, $sep, $config_copy, $mix);
|
||||
}
|
||||
$output.=$data->to_xml_end();
|
||||
$index++;
|
||||
}
|
||||
$this->unmix($config, $mix);
|
||||
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, $config,$mix){
|
||||
$output=array();
|
||||
$index=0;
|
||||
$conn = $this->conn;
|
||||
$config_copy = new DataConfig($config);
|
||||
$this->mix($config, $mix);
|
||||
while ($data=$conn->sql->get_next($res)){
|
||||
$data = $this->complex_mix($mix, $data);
|
||||
$data = new $name($data,$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_fieldset(implode(",",$config_copy->db_names_list($conn->sql)));
|
||||
$sub_request->set_relation($data->get_id());
|
||||
//$sub_request->set_filters(array());
|
||||
$temp = $this->render_set($conn->sql->select($sub_request), $name, $dload, $sep, $config_copy, $mix);
|
||||
if (sizeof($temp))
|
||||
$record["data"] = $temp;
|
||||
}
|
||||
if ($record !== false)
|
||||
$output[] = $record;
|
||||
$index++;
|
||||
}
|
||||
$this->unmix($config, $mix);
|
||||
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, $config, $mix){
|
||||
$output="";
|
||||
$index=0;
|
||||
$conn = $this->conn;
|
||||
$this->mix($config, $mix);
|
||||
while ($data=$conn->sql->get_next($res)){
|
||||
$data = $this->simple_mix($mix, $data);
|
||||
$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++;
|
||||
}
|
||||
$this->unmix($config, $mix);
|
||||
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($this->sep, $id, 2);
|
||||
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, $config, $mix){
|
||||
$output=array();
|
||||
$index=0;
|
||||
$conn = $this->conn;
|
||||
$this->mix($config, $mix);
|
||||
while ($data=$conn->sql->get_next($res)){
|
||||
$data = $this->complex_mix($mix, $data);
|
||||
$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++;
|
||||
}
|
||||
$this->unmix($config, $mix);
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class GroupRenderStrategy extends RenderStrategy {
|
||||
|
||||
protected $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, $config, $mix, $usemix = false){
|
||||
$output="";
|
||||
$index=0;
|
||||
$conn = $this->conn;
|
||||
if ($usemix) $this->mix($config, $mix);
|
||||
while ($data=$conn->sql->get_next($res)){
|
||||
if (isset($data[$config->id['name']])) {
|
||||
$this->simple_mix($mix, $data);
|
||||
$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, $config, $mix, true);
|
||||
}
|
||||
$output.=$data->to_xml_end();
|
||||
$index++;
|
||||
}
|
||||
if ($usemix) $this->unmix($config, $mix);
|
||||
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, $config, $mix, $usemix = false){
|
||||
$output=array();
|
||||
$index=0;
|
||||
$conn = $this->conn;
|
||||
if ($usemix) $this->mix($config, $mix);
|
||||
while ($data=$conn->sql->get_next($res)){
|
||||
if (isset($data[$config->id['name']])) {
|
||||
$data = $this->complex_mix($mix, $data);
|
||||
$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, $config, $mix, true);
|
||||
if (sizeof($temp))
|
||||
$record["data"] = $temp;
|
||||
}
|
||||
$output[] = $record;
|
||||
$index++;
|
||||
}
|
||||
if ($usemix) $this->unmix($config, $mix);
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
267
libraries/dhtmlxgantt/connector/tools.php
Normal file
267
libraries/dhtmlxgantt/connector/tools.php
Normal file
|
|
@ -0,0 +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 $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:i:s")."\n====================================");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
231
libraries/dhtmlxgantt/connector/tree_connector.php
Normal file
231
libraries/dhtmlxgantt/connector/tree_connector.php
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
<?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';
|
||||
public $rootId = "0";
|
||||
|
||||
/*! 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($this->rootId);
|
||||
|
||||
$this->request->set_limit(0,0); //netralize default reaction on dyn. loading mode
|
||||
}
|
||||
|
||||
/*! renders self as xml, starting part
|
||||
*/
|
||||
public function xml_start(){
|
||||
$attributes = "";
|
||||
foreach($this->attributes as $k=>$v)
|
||||
$attributes .= " ".$k."='".$v."'";
|
||||
|
||||
return "<tree id='".$this->request->get_relation()."'".$attributes.">";
|
||||
}
|
||||
|
||||
/*! renders self as xml, ending part
|
||||
*/
|
||||
public function xml_end(){
|
||||
$this->fill_collections();
|
||||
return $this->extra_output."</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;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
89
libraries/dhtmlxgantt/connector/treedatagroup_connector.php
Normal file
89
libraries/dhtmlxgantt/connector/treedatagroup_connector.php
Normal file
|
|
@ -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'>";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("data_connector.php");
|
||||
|
||||
class TreeDataMultitableConnector extends TreeDataConnector{
|
||||
|
||||
protected $parent_name = 'parent';
|
||||
|
||||
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->dload = true;
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
/*! 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[$this->parent_name])) {
|
||||
return "<data parent='".$this->xmlentities($this->render->level_id($_GET[$this->parent_name], $this->render->get_level() - 1))."'>";
|
||||
} else {
|
||||
return "<data parent='0'>";
|
||||
}
|
||||
}
|
||||
|
||||
/*! set maximum level of tree
|
||||
@param max_level
|
||||
maximum level
|
||||
*/
|
||||
public function setMaxLevel($max_level) {
|
||||
$this->render->set_max_level($max_level);
|
||||
}
|
||||
|
||||
public function get_level() {
|
||||
return $this->render->get_level($this->parent_name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class JSONTreeDataMultitableConnector extends TreeDataMultitableConnector{
|
||||
|
||||
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";
|
||||
if (!$render_type) $render_type="JSONMultitableTreeRenderStrategy";
|
||||
parent::__construct($res,$type,$item_type,$data_type,$render_type);
|
||||
}
|
||||
|
||||
protected function output_as_xml($res){
|
||||
$result = $this->render_set($res);
|
||||
if ($this->simple) return $result;
|
||||
|
||||
$data = array();
|
||||
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"] = $result;
|
||||
|
||||
$result = json_encode($data);
|
||||
if ($this->as_string) return $result;
|
||||
|
||||
$out = new OutputWriter($result, "");
|
||||
$out->set_type("json");
|
||||
$this->event->trigger("beforeOutput", $this, $out);
|
||||
$out->output("", true, $this->encoding);
|
||||
}
|
||||
|
||||
public function xml_start(){
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
121
libraries/dhtmlxgantt/connector/treegrid_connector.php
Normal file
121
libraries/dhtmlxgantt/connector/treegrid_connector.php
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("grid_connector.php");
|
||||
|
||||
/*! DataItem class for TreeGrid component
|
||||
**/
|
||||
class TreeGridDataItem extends GridDataItem{
|
||||
private $kids=-1;//!< checked state
|
||||
|
||||
function __construct($data,$config,$index){
|
||||
parent::__construct($data,$config,$index);
|
||||
$this->im0=false;
|
||||
}
|
||||
/*! return id of parent record
|
||||
|
||||
@return
|
||||
id of parent record
|
||||
*/
|
||||
function get_parent_id(){
|
||||
return $this->data[$this->config->relation_id["name"]];
|
||||
}
|
||||
/*! assign image to treegrid's item
|
||||
longer description
|
||||
@param img
|
||||
relative path to the image
|
||||
*/
|
||||
function set_image($img){
|
||||
$this->set_cell_attribute($this->config->text[0]["name"],"image",$img);
|
||||
}
|
||||
|
||||
/*! 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;
|
||||
if ($value)
|
||||
$this->set_row_attribute("xmlkids",$value);
|
||||
}
|
||||
}
|
||||
/*! Connector for dhtmlxTreeGrid
|
||||
**/
|
||||
class TreeGridConnector extends GridConnector{
|
||||
protected $parent_name = 'id';
|
||||
protected $rootId = "0";
|
||||
|
||||
/*! 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="TreeGridDataItem";
|
||||
if (!$data_type) $data_type="TreeGridDataProcessor";
|
||||
if (!$render_type) $render_type="TreeRenderStrategy";
|
||||
parent::__construct($res,$type,$item_type,$data_type,$render_type);
|
||||
}
|
||||
|
||||
/*! process treegrid specific options in incoming request */
|
||||
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($this->rootId);
|
||||
|
||||
$this->request->set_limit(0,0); //netralize default reaction on dyn. loading mode
|
||||
}
|
||||
|
||||
/*! renders self as xml, starting part
|
||||
*/
|
||||
protected function xml_start(){
|
||||
return "<rows parent='".$this->xmlentities( $this->request->get_relation() )."'>";
|
||||
}
|
||||
}
|
||||
|
||||
/*! DataProcessor class for Grid component
|
||||
**/
|
||||
class TreeGridDataProcessor extends GridDataProcessor{
|
||||
|
||||
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=="gr_pid")
|
||||
return $this->config->relation_id["name"];
|
||||
else return parent::name_data($data);
|
||||
}
|
||||
}
|
||||
?>
|
||||
46
libraries/dhtmlxgantt/connector/treegridgroup_connector.php
Normal file
46
libraries/dhtmlxgantt/connector/treegridgroup_connector.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("treegrid_connector.php");
|
||||
|
||||
class TreeGridGroupConnector extends TreeGridConnector{
|
||||
|
||||
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
|
||||
*/
|
||||
protected function xml_start(){
|
||||
if (isset($_GET[$this->parent_name])) {
|
||||
return "<rows parent='".$_GET[$this->parent_name].$this->render->get_postfix()."'>";
|
||||
} else {
|
||||
return "<rows parent='0'>";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("treegrid_connector.php");
|
||||
|
||||
class TreeGridMultitableConnector extends TreeGridConnector{
|
||||
|
||||
public function __construct($res,$type=false,$item_type=false,$data_type=false,$render_type=false){
|
||||
$data_type="TreeGridMultitableDataProcessor";
|
||||
if (!$render_type) $render_type="MultitableTreeRenderStrategy";
|
||||
parent::__construct($res,$type,$item_type,$data_type,$render_type);
|
||||
}
|
||||
|
||||
public function render(){
|
||||
$this->dload = true;
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
/*! 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->xmlentities($this->render->level_id($_GET['id'], $this->get_level() - 1))."'>";
|
||||
} else {
|
||||
return "<rows parent='0'>";
|
||||
}
|
||||
}
|
||||
|
||||
/*! set maximum level of tree
|
||||
@param max_level
|
||||
maximum level
|
||||
*/
|
||||
public function setMaxLevel($max_level) {
|
||||
$this->render->set_max_level($max_level);
|
||||
}
|
||||
|
||||
public function get_level() {
|
||||
return $this->render->get_level($this->parent_name);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
class TreeGridMultitableDataProcessor extends DataProcessor {
|
||||
|
||||
function name_data($data){
|
||||
if ($data=="gr_pid")
|
||||
return $this->config->relation_id["name"];
|
||||
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"];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
46
libraries/dhtmlxgantt/connector/treegroup_connector.php
Normal file
46
libraries/dhtmlxgantt/connector/treegroup_connector.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("tree_connector.php");
|
||||
|
||||
class TreeGroupConnector extends TreeConnector{
|
||||
|
||||
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 "<tree id='".$_GET[$this->parent_name].$this->render->get_postfix()."'>";
|
||||
} else {
|
||||
return "<tree id='0'>";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
51
libraries/dhtmlxgantt/connector/treemultitable_connector.php
Normal file
51
libraries/dhtmlxgantt/connector/treemultitable_connector.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
require_once("tree_connector.php");
|
||||
|
||||
class TreeMultitableConnector extends TreeConnector{
|
||||
|
||||
protected $parent_name = 'id';
|
||||
|
||||
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->dload = true;
|
||||
return parent::render();
|
||||
}
|
||||
|
||||
/*! 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[$this->parent_name])) {
|
||||
return "<tree id='".$this->xmlentities($this->render->level_id($_GET[$this->parent_name], $this->get_level() - 1))."'>";
|
||||
} else {
|
||||
return "<tree id='0'>";
|
||||
}
|
||||
}
|
||||
|
||||
/*! set maximum level of tree
|
||||
@param max_level
|
||||
maximum level
|
||||
*/
|
||||
public function setMaxLevel($max_level) {
|
||||
$this->render->set_max_level($max_level);
|
||||
}
|
||||
|
||||
public function get_level() {
|
||||
return $this->render->get_level($this->parent_name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
266
libraries/dhtmlxgantt/connector/update.php
Normal file
266
libraries/dhtmlxgantt/connector/update.php
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
<?php
|
||||
/*
|
||||
@author dhtmlx.com
|
||||
@license GPL, see license.txt
|
||||
*/
|
||||
|
||||
/*! DataItemUpdate class for realization Optimistic concurrency control
|
||||
Wrapper for DataItem object
|
||||
It's used during outputing updates instead of DataItem object
|
||||
Create wrapper for every data item with update information.
|
||||
*/
|
||||
class DataItemUpdate extends DataItem {
|
||||
|
||||
|
||||
/*! constructor
|
||||
@param data
|
||||
hash of data
|
||||
@param config
|
||||
DataConfig object
|
||||
@param index
|
||||
index of element
|
||||
*/
|
||||
public function __construct($data,$config,$index,$type){
|
||||
$this->config=$config;
|
||||
$this->data=$data;
|
||||
$this->index=$index;
|
||||
$this->skip=false;
|
||||
$this->child = new $type($data, $config, $index);
|
||||
}
|
||||
|
||||
/*! returns parent_id (for Tree and TreeGrid components)
|
||||
*/
|
||||
public function get_parent_id(){
|
||||
if (method_exists($this->child, 'get_parent_id')) {
|
||||
return $this->child->get_parent_id();
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! generate XML on the data hash base
|
||||
*/
|
||||
public function to_xml(){
|
||||
$str= "<update ";
|
||||
$str .= 'status="'.$this->data['type'].'" ';
|
||||
$str .= 'id="'.$this->data['dataId'].'" ';
|
||||
$str .= 'parent="'.$this->get_parent_id().'"';
|
||||
$str .= '>';
|
||||
$str .= $this->child->to_xml();
|
||||
$str .= '</update>';
|
||||
return $str;
|
||||
}
|
||||
|
||||
/*! return starting tag for XML string
|
||||
*/
|
||||
public function to_xml_start(){
|
||||
$str="<update ";
|
||||
$str .= 'status="'.$this->data['type'].'" ';
|
||||
$str .= 'id="'.$this->data['dataId'].'" ';
|
||||
$str .= 'parent="'.$this->get_parent_id().'"';
|
||||
$str .= '>';
|
||||
$str .= $this->child->to_xml_start();
|
||||
return $str;
|
||||
}
|
||||
|
||||
/*! return ending tag for XML string
|
||||
*/
|
||||
public function to_xml_end(){
|
||||
$str = $this->child->to_xml_end();
|
||||
$str .= '</update>';
|
||||
return $str;
|
||||
}
|
||||
|
||||
/*! returns false for outputing only current item without child items
|
||||
*/
|
||||
public function has_kids(){
|
||||
return false;
|
||||
}
|
||||
|
||||
/*! sets count of child items
|
||||
@param value
|
||||
count of child items
|
||||
*/
|
||||
public function set_kids($value){
|
||||
if (method_exists($this->child, 'set_kids')) {
|
||||
$this->child->set_kids($value);
|
||||
}
|
||||
}
|
||||
|
||||
/*! sets attribute for item
|
||||
*/
|
||||
public function set_attribute($name, $value){
|
||||
if (method_exists($this->child, 'set_attribute')) {
|
||||
LogMaster::log("setting attribute: \nname = {$name}\nvalue = {$value}");
|
||||
$this->child->set_attribute($name, $value);
|
||||
} else {
|
||||
LogMaster::log("set_attribute method doesn't exists");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DataUpdate{
|
||||
|
||||
protected $table; //!< table , where actions are stored
|
||||
protected $url; //!< url for notification service, optional
|
||||
protected $sql; //!< DB wrapper object
|
||||
protected $config; //!< DBConfig object
|
||||
protected $request; //!< DBRequestConfig object
|
||||
protected $event;
|
||||
protected $item_class;
|
||||
protected $demu;
|
||||
|
||||
//protected $config;//!< DataConfig instance
|
||||
//protected $request;//!< DataRequestConfig instance
|
||||
|
||||
/*! constructor
|
||||
|
||||
@param connector
|
||||
Connector object
|
||||
@param config
|
||||
DataConfig object
|
||||
@param request
|
||||
DataRequestConfig object
|
||||
*/
|
||||
function __construct($sql, $config, $request, $table, $url){
|
||||
$this->config= $config;
|
||||
$this->request= $request;
|
||||
$this->sql = $sql;
|
||||
$this->table=$table;
|
||||
$this->url=$url;
|
||||
$this->demu = false;
|
||||
}
|
||||
|
||||
public function set_demultiplexor($path){
|
||||
$this->demu = $path;
|
||||
}
|
||||
|
||||
public function set_event($master, $name){
|
||||
$this->event = $master;
|
||||
$this->item_class = $name;
|
||||
}
|
||||
|
||||
private function select_update($actions_table, $join_table, $id_field_name, $version, $user) {
|
||||
$sql = "SELECT * FROM {$actions_table}";
|
||||
$sql .= " LEFT OUTER JOIN {$join_table} ON ";
|
||||
$sql .= "{$actions_table}.DATAID = {$join_table}.{$id_field_name} ";
|
||||
$sql .= "WHERE {$actions_table}.ID > '{$version}' AND {$actions_table}.USER <> '{$user}'";
|
||||
return $sql;
|
||||
}
|
||||
|
||||
private function get_update_max_version() {
|
||||
$sql = "SELECT MAX(id) as VERSION FROM {$this->table}";
|
||||
$res = $this->sql->query($sql);
|
||||
$data = $this->sql->get_next($res);
|
||||
|
||||
if ($data == false || $data['VERSION'] == false)
|
||||
return 1;
|
||||
else
|
||||
return $data['VERSION'];
|
||||
}
|
||||
|
||||
private function log_update_action($actions_table, $dataId, $status, $user) {
|
||||
$sql = "INSERT INTO {$actions_table} (DATAID, TYPE, USER) VALUES ('{$dataId}', '{$status}', '{$user}')";
|
||||
$this->sql->query($sql);
|
||||
if ($this->demu)
|
||||
file_get_contents($this->demu);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! records operations in actions_table
|
||||
@param action
|
||||
DataAction object
|
||||
*/
|
||||
public function log_operations($action) {
|
||||
$type = $this->sql->escape($action->get_status());
|
||||
$dataId = $this->sql->escape($action->get_new_id());
|
||||
$user = $this->sql->escape($this->request->get_user());
|
||||
if ($type!="error" && $type!="invalid" && $type !="collision") {
|
||||
$this->log_update_action($this->table, $dataId, $type, $user);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! return action version in XMl format
|
||||
*/
|
||||
public function get_version() {
|
||||
$version = $this->get_update_max_version();
|
||||
return "<userdata name='version'>".$version."</userdata>";
|
||||
}
|
||||
|
||||
|
||||
/*! adds action version in output XML as userdata
|
||||
*/
|
||||
public function version_output($conn, $out) {
|
||||
$out->add($this->get_version());
|
||||
}
|
||||
|
||||
|
||||
/*! create update actions in XML-format and sends it to output
|
||||
*/
|
||||
public function get_updates() {
|
||||
$sub_request = new DataRequestConfig($this->request);
|
||||
$version = $this->request->get_version();
|
||||
$user = $this->request->get_user();
|
||||
|
||||
$sub_request->parse_sql($this->select_update($this->table, $this->request->get_source(), $this->config->id['db_name'], $version, $user));
|
||||
$sub_request->set_relation(false);
|
||||
|
||||
$output = $this->render_set($this->sql->select($sub_request), $this->item_class);
|
||||
|
||||
ob_clean();
|
||||
header("Content-type:text/xml");
|
||||
|
||||
echo $this->updates_start();
|
||||
echo $this->get_version();
|
||||
echo $output;
|
||||
echo $this->updates_end();
|
||||
}
|
||||
|
||||
|
||||
protected function render_set($res, $name){
|
||||
$output="";
|
||||
$index=0;
|
||||
while ($data=$this->sql->get_next($res)){
|
||||
$data = new DataItemUpdate($data,$this->config,$index, $name);
|
||||
$this->event->trigger("beforeRender",$data);
|
||||
$output.=$data->to_xml();
|
||||
$index++;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/*! returns update start string
|
||||
*/
|
||||
protected function updates_start() {
|
||||
$start = '<updates>';
|
||||
return $start;
|
||||
}
|
||||
|
||||
/*! returns update end string
|
||||
*/
|
||||
protected function updates_end() {
|
||||
$start = '</updates>';
|
||||
return $start;
|
||||
}
|
||||
|
||||
/*! checks if action version given by client is deprecated
|
||||
@param action
|
||||
DataAction object
|
||||
*/
|
||||
public function check_collision($action) {
|
||||
$version = $this->sql->escape($this->request->get_version());
|
||||
//$user = $this->sql->escape($this->request->get_user());
|
||||
$last_version = $this->get_update_max_version();
|
||||
if (($last_version > $version)&&($action->get_status() == 'update')) {
|
||||
$action->error();
|
||||
$action->set_status('collision');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
199
libraries/dhtmlxgantt/connector/xss_filter.php
Normal file
199
libraries/dhtmlxgantt/connector/xss_filter.php
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 2001-2008 Liip AG |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Licensed under the Apache License, Version 2.0 (the "License"); |
|
||||
// | you may not use this file except in compliance with the License. |
|
||||
// | You may obtain a copy of the License at |
|
||||
// | http://www.apache.org/licenses/LICENSE-2.0 |
|
||||
// | Unless required by applicable law or agreed to in writing, software |
|
||||
// | distributed under the License is distributed on an "AS IS" BASIS, |
|
||||
// | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
|
||||
// | implied. See the License for the specific language governing |
|
||||
// | permissions and limitations under the License. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Author: Christian Stocker <christian.stocker@liip.ch> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
|
||||
//original name was lx_externalinput_clean
|
||||
//renamed to prevent possible conflicts
|
||||
class dhx_externalinput_clean {
|
||||
// this basic clean should clean html code from
|
||||
// lot of possible malicious code for Cross Site Scripting
|
||||
// use it whereever you get external input
|
||||
|
||||
// you can also set $filterOut to some use html cleaning, but I don't know of any code, which could
|
||||
// exploit that. But if you want to be sure, set it to eg. array("Tidy","Dom");
|
||||
static function basic($string, $filterIn = array("Tidy","Dom","Striptags"), $filterOut = "none") {
|
||||
$string = self::tidyUp($string, $filterIn);
|
||||
$string = str_replace(array("&", "<", ">"), array("&amp;", "&lt;", "&gt;"), $string);
|
||||
|
||||
// fix &entitiy\n;
|
||||
$string = preg_replace('#(&\#*\w+)[\x00-\x20]+;#u', "$1;", $string);
|
||||
$string = preg_replace('#(&\#x*)([0-9A-F]+);*#iu', "$1$2;", $string);
|
||||
|
||||
$string = html_entity_decode($string, ENT_COMPAT, "UTF-8");
|
||||
|
||||
// remove any attribute starting with "on" or xmlns
|
||||
$string = preg_replace('#(<[^>]+[\x00-\x20\"\'\/])(on|xmlns)[^>]*>#iUu', "$1>", $string);
|
||||
|
||||
// remove javascript: and vbscript: protocol
|
||||
$string = preg_replace('#([a-z]*)[\x00-\x20\/]*=[\x00-\x20\/]*([\`\'\"]*)[\x00-\x20\/]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iUu', '$1=$2nojavascript...', $string);
|
||||
$string = preg_replace('#([a-z]*)[\x00-\x20\/]*=[\x00-\x20\/]*([\`\'\"]*)[\x00-\x20\/]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iUu', '$1=$2novbscript...', $string);
|
||||
$string = preg_replace('#([a-z]*)[\x00-\x20\/]*=[\x00-\x20\/]*([\`\'\"]*)[\x00-\x20\/]*-moz-binding[\x00-\x20]*:#Uu', '$1=$2nomozbinding...', $string);
|
||||
$string = preg_replace('#([a-z]*)[\x00-\x20\/]*=[\x00-\x20\/]*([\`\'\"]*)[\x00-\x20\/]*data[\x00-\x20]*:#Uu', '$1=$2nodata...', $string);
|
||||
|
||||
//remove any style attributes, IE allows too much stupid things in them, eg.
|
||||
//<span style="width: expression(alert('Ping!'));"></span>
|
||||
// and in general you really don't want style declarations in your UGC
|
||||
|
||||
$string = preg_replace('#(<[^>]+[\x00-\x20\"\'\/])style[^>]*>#iUu', "$1>", $string);
|
||||
|
||||
//remove namespaced elements (we do not need them...)
|
||||
$string = preg_replace('#</*\w+:\w[^>]*>#i', "", $string);
|
||||
|
||||
//remove really unwanted tags
|
||||
do {
|
||||
$oldstring = $string;
|
||||
$string = preg_replace('#</*(applet|meta|xml|blink|link|style|script|embed|object|iframe|frame|frameset|ilayer|layer|bgsound|title|base)[^>]*>#i', "", $string);
|
||||
} while ($oldstring != $string);
|
||||
|
||||
return self::tidyUp($string, $filterOut);
|
||||
}
|
||||
|
||||
static function tidyUp($string, $filters) {
|
||||
if (is_array($filters)) {
|
||||
foreach ($filters as $filter) {
|
||||
$return = self::tidyUpWithFilter($string, $filter);
|
||||
if ($return !== false) {
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$return = self::tidyUpWithFilter($string, $filters);
|
||||
}
|
||||
// if no filter matched, use the Striptags filter to be sure.
|
||||
if ($return === false) {
|
||||
return self::tidyUpModuleStriptags($string);
|
||||
} else {
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
|
||||
static private function tidyUpWithFilter($string, $filter) {
|
||||
if (is_callable(array("self", "tidyUpModule" . $filter))) {
|
||||
return call_user_func(array("self", "tidyUpModule" . $filter), $string);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static private function tidyUpModuleStriptags($string) {
|
||||
|
||||
return strip_tags($string);
|
||||
}
|
||||
|
||||
static private function tidyUpModuleNone($string) {
|
||||
return $string;
|
||||
}
|
||||
|
||||
static private function tidyUpModuleDom($string) {
|
||||
$dom = new domdocument();
|
||||
@$dom->loadHTML("<html><body>" . $string . "</body></html>");
|
||||
$string = '';
|
||||
foreach ($dom->documentElement->firstChild->childNodes as $child) {
|
||||
$string .= $dom->saveXML($child);
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
static private function tidyUpModuleTidy($string) {
|
||||
if (class_exists("tidy")) {
|
||||
$tidy = new tidy();
|
||||
$tidyOptions = array("output-xhtml" => true,
|
||||
"show-body-only" => true,
|
||||
"clean" => true,
|
||||
"wrap" => "350",
|
||||
"indent" => true,
|
||||
"indent-spaces" => 1,
|
||||
"ascii-chars" => false,
|
||||
"wrap-attributes" => false,
|
||||
"alt-text" => "",
|
||||
"doctype" => "loose",
|
||||
"numeric-entities" => true,
|
||||
"drop-proprietary-attributes" => true,
|
||||
"enclose-text" => false,
|
||||
"enclose-block-text" => false
|
||||
|
||||
);
|
||||
$tidy->parseString($string, $tidyOptions, "utf8");
|
||||
$tidy->cleanRepair();
|
||||
return (string) $tidy;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define("DHX_SECURITY_SAFETEXT", 1);
|
||||
define("DHX_SECURITY_SAFEHTML", 2);
|
||||
define("DHX_SECURITY_TRUSTED", 3);
|
||||
|
||||
class ConnectorSecurity{
|
||||
static public $xss = DHX_SECURITY_SAFETEXT;
|
||||
static public $security_key = false;
|
||||
static public $security_var = "dhx_security";
|
||||
|
||||
static private $filterClass = null;
|
||||
static function filter($value, $mode = false){
|
||||
if ($mode === false)
|
||||
$mode = ConnectorSecurity::$xss;
|
||||
|
||||
if ($mode == DHX_SECURITY_TRUSTED)
|
||||
return $value;
|
||||
if ($mode == DHX_SECURITY_SAFETEXT)
|
||||
return filter_var($value, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
|
||||
if ($mode == DHX_SECURITY_SAFEHTML){
|
||||
if (ConnectorSecurity::$filterClass == null)
|
||||
ConnectorSecurity::$filterClass = new dhx_externalinput_clean();
|
||||
return ConnectorSecurity::$filterClass->basic($value);
|
||||
}
|
||||
throw new Error("Invalid security mode:"+$mode);
|
||||
}
|
||||
|
||||
static function CSRF_detected(){
|
||||
LogMaster::log("[SECURITY] Possible CSRF attack detected", array(
|
||||
"referer" => $_SERVER["HTTP_REFERER"],
|
||||
"remote" => $_SERVER["REMOTE_ADDR"]
|
||||
));
|
||||
LogMaster::log("Request data", $_POST);
|
||||
die();
|
||||
}
|
||||
static function checkCSRF($edit){
|
||||
if (ConnectorSecurity::$security_key){
|
||||
if (!isset($_SESSION))
|
||||
@session_start();
|
||||
|
||||
if ($edit=== true){
|
||||
if (!isset($_POST[ConnectorSecurity::$security_var]))
|
||||
return ConnectorSecurity::CSRF_detected();
|
||||
$master_key = $_SESSION[ConnectorSecurity::$security_var];
|
||||
$update_key = $_POST[ConnectorSecurity::$security_var];
|
||||
if ($master_key != $update_key)
|
||||
return ConnectorSecurity::CSRF_detected();
|
||||
|
||||
return "";
|
||||
}
|
||||
//data loading
|
||||
if (!array_key_exists(ConnectorSecurity::$security_var,$_SESSION)){
|
||||
$_SESSION[ConnectorSecurity::$security_var] = md5(uniqid());
|
||||
}
|
||||
|
||||
return $_SESSION[ConnectorSecurity::$security_var];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
9
libraries/dhtmlxgantt/dhtmlxgantt.css
Normal file
9
libraries/dhtmlxgantt/dhtmlxgantt.css
Normal file
File diff suppressed because one or more lines are too long
419
libraries/dhtmlxgantt/dhtmlxgantt.js
Normal file
419
libraries/dhtmlxgantt/dhtmlxgantt.js
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
function dhtmlxEvent(t,e,n){t.addEventListener?t.addEventListener(e,n,!1):t.attachEvent&&t.attachEvent("on"+e,n)}function dhtmlxDetachEvent(t,e,n){t.removeEventListener?t.removeEventListener(e,n,!1):t.detachEvent&&t.detachEvent("on"+e,n)}function dhtmlxDnD(t,e){e&&(this._settings=e),dhtmlxEventable(this),dhtmlxEvent(t,"mousedown",dhtmlx.bind(function(n){e.original_target={target:n.target||n.srcElement},this.dragStart(t,n)},this))}function dataProcessor(t){return this.serverProcessor=t,this.action_param="!nativeeditor_status",
|
||||
this.object=null,this.updatedRows=[],this.autoUpdate=!0,this.updateMode="cell",this._tMode="GET",this._headers=null,this._payload=null,this.post_delim="_",this._waitMode=0,this._in_progress={},this._invalid={},this.mandatoryFields=[],this.messages=[],this.styles={updated:"font-weight:bold;",inserted:"font-weight:bold;",deleted:"text-decoration : line-through;",invalid:"background-color:FFE0E0;",invalid_cell:"border-bottom:2px solid red;",error:"color:red;",clear:"font-weight:normal;text-decoration:none;"
|
||||
},this.enableUTFencoding(!0),dhx4._eventable(this),this}"undefined"==typeof window.dhx4&&(window.dhx4={version:"4.1.3",skin:null,skinDetect:function(t){return{10:"dhx_skyblue",20:"dhx_web",30:"dhx_terrace"}[this.readFromCss(t+"_skin_detect")]||null},readFromCss:function(t,e){var n=document.createElement("DIV");n.className=t,null!=document.body.firstChild?document.body.insertBefore(n,document.body.firstChild):document.body.appendChild(n);var i=n[e||"offsetWidth"];return n.parentNode.removeChild(n),
|
||||
n=null,i},lastId:1,newId:function(){return this.lastId++},zim:{data:{},step:5,first:function(){return 100},last:function(){var t=this.first();for(var e in this.data)t=Math.max(t,this.data[e]);return t},reserve:function(t){return this.data[t]=this.last()+this.step,this.data[t]},clear:function(t){null!=this.data[t]&&(this.data[t]=null,delete this.data[t])}},s2b:function(t){return"string"==typeof t&&(t=t.toLowerCase()),1==t||1==t||"true"==t||"1"==t||"yes"==t||"y"==t},s2j:function(s){var obj=null;dhx4.temp=null;
|
||||
|
||||
try{eval("dhx4.temp="+s)}catch(e){dhx4.temp=null}return obj=dhx4.temp,dhx4.temp=null,obj},absLeft:function(t){return"string"==typeof t&&(t=document.getElementById(t)),this.getOffset(t).left},absTop:function(t){return"string"==typeof t&&(t=document.getElementById(t)),this.getOffset(t).top},_aOfs:function(t){for(var e=0,n=0;t;)e+=parseInt(t.offsetTop),n+=parseInt(t.offsetLeft),t=t.offsetParent;return{top:e,left:n}},_aOfsRect:function(t){var e=t.getBoundingClientRect(),n=document.body,i=document.documentElement,a=window.pageYOffset||i.scrollTop||n.scrollTop,s=window.pageXOffset||i.scrollLeft||n.scrollLeft,r=i.clientTop||n.clientTop||0,o=i.clientLeft||n.clientLeft||0,l=e.top+a-r,d=e.left+s-o;
|
||||
|
||||
return{top:Math.round(l),left:Math.round(d)}},getOffset:function(t){return t.getBoundingClientRect?this._aOfsRect(t):this._aOfs(t)},_isObj:function(t){return null!=t&&"object"==typeof t&&"undefined"==typeof t.length},_copyObj:function(t){if(this._isObj(t)){var e={};for(var n in t)e[n]="object"==typeof t[n]&&null!=t[n]?this._copyObj(t[n]):t[n]}else for(var e=[],n=0;n<t.length;n++)e[n]="object"==typeof t[n]&&null!=t[n]?this._copyObj(t[n]):t[n];return e},screenDim:function(){var t=navigator.userAgent.indexOf("MSIE")>=0,e={};
|
||||
|
||||
return e.left=document.body.scrollLeft,e.right=e.left+(window.innerWidth||document.body.clientWidth),e.top=Math.max((t?document.documentElement:document.getElementsByTagName("html")[0]).scrollTop,document.body.scrollTop),e.bottom=e.top+(t?Math.max(document.documentElement.clientHeight||0,document.documentElement.offsetHeight||0):window.innerHeight),e},selectTextRange:function(t,e,n){t="string"==typeof t?document.getElementById(t):t;var i=t.value.length;if(e=Math.max(Math.min(e,i),0),n=Math.min(n,i),
|
||||
t.setSelectionRange)try{t.setSelectionRange(e,n)}catch(a){}else if(t.createTextRange){var s=t.createTextRange();s.moveStart("character",e),s.moveEnd("character",n-i);try{s.select()}catch(a){}}},transData:null,transDetect:function(){if(null==this.transData){this.transData={transProp:!1,transEv:null};var t={MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd",OTransition:"oTransitionEnd",msTransition:"transitionend",transition:"transitionend"};for(var e in t)0==this.transData.transProp&&null!=document.documentElement.style[e]&&(this.transData.transProp=e,
|
||||
this.transData.transEv=t[e]);t=null}return this.transData},_xmlNodeValue:function(t){for(var e="",n=0;n<t.childNodes.length;n++)e+=null!=t.childNodes[n].nodeValue?t.childNodes[n].nodeValue.toString().replace(/^[\n\r\s]{0,}/,"").replace(/[\n\r\s]{0,}$/,""):"";return e}},window.dhx4.isIE=navigator.userAgent.indexOf("MSIE")>=0||navigator.userAgent.indexOf("Trident")>=0,window.dhx4.isIE6=null==window.XMLHttpRequest&&navigator.userAgent.indexOf("MSIE")>=0,window.dhx4.isIE7=navigator.userAgent.indexOf("MSIE 7.0")>=0&&navigator.userAgent.indexOf("Trident")<0,
|
||||
window.dhx4.isIE8=navigator.userAgent.indexOf("MSIE 8.0")>=0&&navigator.userAgent.indexOf("Trident")>=0,window.dhx4.isOpera=navigator.userAgent.indexOf("Opera")>=0,window.dhx4.isChrome=navigator.userAgent.indexOf("Chrome")>=0,window.dhx4.isKHTML=navigator.userAgent.indexOf("Safari")>=0||navigator.userAgent.indexOf("Konqueror")>=0,window.dhx4.isFF=navigator.userAgent.indexOf("Firefox")>=0,window.dhx4.isIPad=navigator.userAgent.search(/iPad/gi)>=0),"undefined"==typeof window.dhx4.ajax&&(window.dhx4.ajax={
|
||||
cache:!1,method:"get",parse:function(t){if("string"!=typeof t)return t;if(t=t.replace(/^[\s]+/,""),window.DOMParser&&!dhx4.isIE)var e=(new window.DOMParser).parseFromString(t,"text/xml");else if(window.ActiveXObject!==window.undefined){var e=new window.ActiveXObject("Microsoft.XMLDOM");e.async="false",e.loadXML(t)}return e},xmltop:function(t,e,n){if("undefined"==typeof e.status||e.status<400){var i=e.responseXML?e.responseXML||e:dhx4.ajax.parse(e.responseText||e);if(i&&null!==i.documentElement&&!i.getElementsByTagName("parsererror").length)return i.getElementsByTagName(t)[0];
|
||||
|
||||
}return-1!==n&&dhx4.callEvent("onLoadXMLError",["Incorrect XML",arguments[1],n]),document.createElement("DIV")},xpath:function(t,e){if(e.nodeName||(e=e.responseXML||e),dhx4.isIE)return e.selectNodes(t)||[];for(var n,i=[],a=(e.ownerDocument||e).evaluate(t,e,null,XPathResult.ANY_TYPE,null);n=a.iterateNext();)i.push(n);return i},query:function(t){dhx4.ajax._call(t.method||"GET",t.url,t.data||"",t.async||!0,t.callback,null,t.headers)},get:function(t,e){this._call("GET",t,null,!0,e)},getSync:function(t){
|
||||
return this._call("GET",t,null,!1)},put:function(t,e,n){this._call("PUT",t,e,!0,n)},del:function(t,e,n){this._call("DELETE",t,e,!0,n)},post:function(t,e,n){1==arguments.length?e="":2!=arguments.length||"function"!=typeof e&&"function"!=typeof window[e]?e=String(e):(n=e,e=""),this._call("POST",t,e,!0,n)},postSync:function(t,e){return e=null==e?"":String(e),this._call("POST",t,e,!1)},getLong:function(t,e){this._call("GET",t,null,!0,e,{url:t})},postLong:function(t,e,n){2==arguments.length&&(n=e,e=""),
|
||||
this._call("POST",t,e,!0,n,{url:t,postData:e})},_call:function(t,e,n,i,a,s,r){var o=window.XMLHttpRequest&&!dhx4.isIE?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP"),l=null!=navigator.userAgent.match(/AppleWebKit/)&&null!=navigator.userAgent.match(/Qt/)&&null!=navigator.userAgent.match(/Safari/);if(1==i&&(o.onreadystatechange=function(){if(4==o.readyState||1==l&&3==o.readyState){if((200!=o.status||""==o.responseText)&&!dhx4.callEvent("onAjaxError",[o]))return;window.setTimeout(function(){
|
||||
"function"==typeof a&&a.apply(window,[{xmlDoc:o}]),null!=s&&("undefined"!=typeof s.postData?dhx4.ajax.postLong(s.url,s.postData,a):dhx4.ajax.getLong(s.url,a)),a=null,o=null},1)}}),"GET"==t&&1!=this.cache&&(e+=(e.indexOf("?")>=0?"&":"?")+"dhxr"+(new Date).getTime()+"=1"),o.open(t,e,i),r)for(var d in r)o.setRequestHeader(d,r[d]);else"POST"==t.toUpperCase()||"PUT"==t||"DELETE"==t?o.setRequestHeader("Content-Type","application/x-www-form-urlencoded"):"GET"==t&&(n=null);return o.setRequestHeader("X-Requested-With","XMLHttpRequest"),
|
||||
o.send(n),i?void 0:{xmlDoc:o}}}),"undefined"==typeof window.dhx4._eventable&&(window.dhx4._eventable=function(t,e){return"clear"==e?(t.detachAllEvents(),t.dhxevs=null,t.attachEvent=null,t.detachEvent=null,t.checkEvent=null,t.callEvent=null,t.detachAllEvents=null,void(t=null)):(t.dhxevs={data:{}},t.attachEvent=function(t,e){t=String(t).toLowerCase(),this.dhxevs.data[t]||(this.dhxevs.data[t]={});var n=window.dhx4.newId();return this.dhxevs.data[t][n]=e,n},t.detachEvent=function(t){for(var e in this.dhxevs.data){
|
||||
var n=0;for(var i in this.dhxevs.data[e])i==t?(this.dhxevs.data[e][i]=null,delete this.dhxevs.data[e][i]):n++;0==n&&(this.dhxevs.data[e]=null,delete this.dhxevs.data[e])}},t.checkEvent=function(t){return t=String(t).toLowerCase(),null!=this.dhxevs.data[t]},t.callEvent=function(t,e){if(t=String(t).toLowerCase(),null==this.dhxevs.data[t])return!0;var n=!0;for(var i in this.dhxevs.data[t])n=this.dhxevs.data[t][i].apply(this,e)&&n;return n},t.detachAllEvents=function(){for(var t in this.dhxevs.data){
|
||||
for(var e in this.dhxevs.data[t])this.dhxevs.data[t][e]=null,delete this.dhxevs.data[t][e];this.dhxevs.data[t]=null,delete this.dhxevs.data[t]}},void(t=null))},dhx4._eventable(dhx4)),"undefined"==typeof window.dhtmlx&&(window.dhtmlx={extend:function(t,e){for(var n in e)t[n]||(t[n]=e[n]);return t},extend_api:function(t,e,n){var i=window[t];i&&(window[t]=function(t){if(t&&"object"==typeof t&&!t.tagName){var n=i.apply(this,e._init?e._init(t):arguments);for(var a in dhtmlx)e[a]&&this[e[a]](dhtmlx[a]);
|
||||
|
||||
for(var a in t)e[a]?this[e[a]](t[a]):0===a.indexOf("on")&&this.attachEvent(a,t[a])}else var n=i.apply(this,arguments);return e._patch&&e._patch(this),n||this},window[t].prototype=i.prototype,n&&dhtmlx.extend(window[t].prototype,n))},url:function(t){return-1!=t.indexOf("?")?"&":"?"}}),_isFF=!1,_isIE=!1,_isOpera=!1,_isKHTML=!1,_isMacOS=!1,_isChrome=!1,_FFrv=!1,_KHTMLrv=!1,_OperaRv=!1,-1!=navigator.userAgent.indexOf("Macintosh")&&(_isMacOS=!0),navigator.userAgent.toLowerCase().indexOf("chrome")>-1&&(_isChrome=!0),
|
||||
-1!=navigator.userAgent.indexOf("Safari")||-1!=navigator.userAgent.indexOf("Konqueror")?(_KHTMLrv=parseFloat(navigator.userAgent.substr(navigator.userAgent.indexOf("Safari")+7,5)),_KHTMLrv>525?(_isFF=!0,_FFrv=1.9):_isKHTML=!0):-1!=navigator.userAgent.indexOf("Opera")?(_isOpera=!0,_OperaRv=parseFloat(navigator.userAgent.substr(navigator.userAgent.indexOf("Opera")+6,3))):-1!=navigator.appName.indexOf("Microsoft")?(_isIE=!0,(-1!=navigator.appVersion.indexOf("MSIE 8.0")||-1!=navigator.appVersion.indexOf("MSIE 9.0")||-1!=navigator.appVersion.indexOf("MSIE 10.0")||document.documentMode>7)&&"BackCompat"!=document.compatMode&&(_isIE=8)):"Netscape"==navigator.appName&&-1!=navigator.userAgent.indexOf("Trident")?_isIE=8:(_isFF=!0,
|
||||
_FFrv=parseFloat(navigator.userAgent.split("rv:")[1])),"undefined"==typeof window.dhtmlxEvent,null==dhtmlxEvent.touchDelay&&(dhtmlxEvent.touchDelay=2e3),"undefined"==typeof dhtmlxEvent.initTouch&&(dhtmlxEvent.initTouch=function(){function t(){if(n){var t=document.createEvent("HTMLEvents");t.initEvent("dblclick",!0,!0),n.dispatchEvent(t),e=n=null}}var e,n,i,a;dhtmlxEvent(document.body,"touchstart",function(s){n=s.touches[0].target,i=s.touches[0].clientX,a=s.touches[0].clientY,e=window.setTimeout(t,dhtmlxEvent.touchDelay);
|
||||
|
||||
}),dhtmlxEvent(document.body,"touchmove",function(t){e&&(Math.abs(t.touches[0].clientX-i)>50||Math.abs(t.touches[0].clientY-a)>50)&&(window.clearTimeout(e),e=n=!1)}),dhtmlxEvent(document.body,"touchend",function(){e&&(window.clearTimeout(e),e=n=!1)}),dhtmlxEvent.initTouch=function(){}}),window.dhtmlx||(window.dhtmlx={}),function(){function t(t,e){var i=t.callback;n(!1),t.box.parentNode.removeChild(t.box),c=t.box=null,i&&i(e)}function e(e){if(c){e=e||event;var n=e.which||event.keyCode;return dhtmlx.message.keyboard&&((13==n||32==n)&&t(c,!0),
|
||||
27==n&&t(c,!1)),e.preventDefault&&e.preventDefault(),!(e.cancelBubble=!0)}}function n(t){n.cover||(n.cover=document.createElement("DIV"),n.cover.onkeydown=e,n.cover.className="dhx_modal_cover",document.body.appendChild(n.cover));document.body.scrollHeight;n.cover.style.display=t?"inline-block":"none"}function i(t,e){var n="dhtmlx_"+t.toLowerCase().replace(/ /g,"_")+"_button";return"<div class='dhtmlx_popup_button "+n+"' result='"+e+"' ><div>"+t+"</div></div>"}function a(t){g.area||(g.area=document.createElement("DIV"),
|
||||
g.area.className="dhtmlx_message_area",g.area.style[g.position]="5px",document.body.appendChild(g.area)),g.hide(t.id);var e=document.createElement("DIV");return e.innerHTML="<div>"+t.text+"</div>",e.className="dhtmlx-info dhtmlx-"+t.type,e.onclick=function(){g.hide(t.id),t=null},"bottom"==g.position&&g.area.firstChild?g.area.insertBefore(e,g.area.firstChild):g.area.appendChild(e),t.expire>0&&(g.timers[t.id]=window.setTimeout(function(){g.hide(t.id)},t.expire)),g.pull[t.id]=e,e=null,t.id}function s(e,n,a){
|
||||
var s=document.createElement("DIV");s.className=" dhtmlx_modal_box dhtmlx-"+e.type,s.setAttribute("dhxbox",1);var r="";if(e.width&&(s.style.width=e.width),e.height&&(s.style.height=e.height),e.title&&(r+='<div class="dhtmlx_popup_title">'+e.title+"</div>"),r+='<div class="dhtmlx_popup_text"><span>'+(e.content?"":e.text)+'</span></div><div class="dhtmlx_popup_controls">',n&&(r+=i(e.ok||"OK",!0)),a&&(r+=i(e.cancel||"Cancel",!1)),e.buttons)for(var o=0;o<e.buttons.length;o++)r+=i(e.buttons[o],o);if(r+="</div>",
|
||||
s.innerHTML=r,e.content){var l=e.content;"string"==typeof l&&(l=document.getElementById(l)),"none"==l.style.display&&(l.style.display=""),s.childNodes[e.title?1:0].appendChild(l)}return s.onclick=function(n){n=n||event;var i=n.target||n.srcElement;if(i.className||(i=i.parentNode),"dhtmlx_popup_button"==i.className.split(" ")[0]){var a=i.getAttribute("result");a="true"==a||("false"==a?!1:a),t(e,a)}},e.box=s,(n||a)&&(c=e),s}function r(t,i,a){var r=t.tagName?t:s(t,i,a);t.hidden||n(!0),document.body.appendChild(r);
|
||||
|
||||
var o=Math.abs(Math.floor(((window.innerWidth||document.documentElement.offsetWidth)-r.offsetWidth)/2)),l=Math.abs(Math.floor(((window.innerHeight||document.documentElement.offsetHeight)-r.offsetHeight)/2));return r.style.top="top"==t.position?"-3px":l+"px",r.style.left=o+"px",r.onkeydown=e,r.focus(),t.hidden&&dhtmlx.modalbox.hide(r),r}function o(t){return r(t,!0,!1)}function l(t){return r(t,!0,!0)}function d(t){return r(t)}function _(t,e,n){return"object"!=typeof t&&("function"==typeof e&&(n=e,e=""),
|
||||
t={text:t,type:e,callback:n}),t}function h(t,e,n,i){return"object"!=typeof t&&(t={text:t,type:e,expire:n,id:i}),t.id=t.id||g.uid(),t.expire=t.expire||g.expire,t}var c=null;document.attachEvent?document.attachEvent("onkeydown",e):document.addEventListener("keydown",e,!0),dhtmlx.alert=function(){var t=_.apply(this,arguments);return t.type=t.type||"confirm",o(t)},dhtmlx.confirm=function(){var t=_.apply(this,arguments);return t.type=t.type||"alert",l(t)},dhtmlx.modalbox=function(){var t=_.apply(this,arguments);
|
||||
|
||||
return t.type=t.type||"alert",d(t)},dhtmlx.modalbox.hide=function(t){for(;t&&t.getAttribute&&!t.getAttribute("dhxbox");)t=t.parentNode;t&&(t.parentNode.removeChild(t),n(!1))};var g=dhtmlx.message=function(t){t=h.apply(this,arguments),t.type=t.type||"info";var e=t.type.split("-")[0];switch(e){case"alert":return o(t);case"confirm":return l(t);case"modalbox":return d(t);default:return a(t)}};g.seed=(new Date).valueOf(),g.uid=function(){return g.seed++},g.expire=4e3,g.keyboard=!0,g.position="top",g.pull={},
|
||||
g.timers={},g.hideAll=function(){for(var t in g.pull)g.hide(t)},g.hide=function(t){var e=g.pull[t];e&&e.parentNode&&(window.setTimeout(function(){e.parentNode.removeChild(e),e=null},2e3),e.className+=" hidden",g.timers[t]&&window.clearTimeout(g.timers[t]),delete g.pull[t])}}(),gantt={version:"3.2.0"},dhtmlxEventable=function(obj){obj._silent_mode=!1,obj._silentStart=function(){this._silent_mode=!0},obj._silentEnd=function(){this._silent_mode=!1},obj.attachEvent=function(t,e,n){return t="ev_"+t.toLowerCase(),
|
||||
this[t]||(this[t]=new this._eventCatcher(n||this)),t+":"+this[t].addEvent(e)},obj.callEvent=function(t,e){return this._silent_mode?!0:(t="ev_"+t.toLowerCase(),this[t]?this[t].apply(this,e):!0)},obj.checkEvent=function(t){return!!this["ev_"+t.toLowerCase()]},obj._eventCatcher=function(obj){var dhx_catch=[],z=function(){for(var t=!0,e=0;e<dhx_catch.length;e++)if(dhx_catch[e]){var n=dhx_catch[e].apply(obj,arguments);t=t&&n}return t};return z.addEvent=function(ev){return"function"!=typeof ev&&(ev=eval(ev)),
|
||||
ev?dhx_catch.push(ev)-1:!1},z.removeEvent=function(t){dhx_catch[t]=null},z},obj.detachEvent=function(t){if(t){var e=t.split(":");this[e[0]].removeEvent(e[1])}},obj.detachAllEvents=function(){for(var t in this)0===t.indexOf("ev_")&&delete this[t]},obj=null},dhtmlx.copy=function(t){var e,n,i;if(t&&"object"==typeof t){for(i={},n=[Array,Date,Number,String,Boolean],e=0;e<n.length;e++)t instanceof n[e]&&(i=e?new n[e](t):new n[e]);for(e in t)Object.prototype.hasOwnProperty.apply(t,[e])&&(i[e]=dhtmlx.copy(t[e]));
|
||||
|
||||
}return i||t},dhtmlx.mixin=function(t,e,n){for(var i in e)(!t[i]||n)&&(t[i]=e[i]);return t},dhtmlx.defined=function(t){return"undefined"!=typeof t},dhtmlx.uid=function(){return this._seed||(this._seed=(new Date).valueOf()),this._seed++,this._seed},dhtmlx.bind=function(t,e){return t.bind?t.bind(e):function(){return t.apply(e,arguments)}},gantt._get_position=function(t){var e=0,n=0;if(t.getBoundingClientRect){var i=t.getBoundingClientRect(),a=document.body,s=document.documentElement,r=window.pageYOffset||s.scrollTop||a.scrollTop,o=window.pageXOffset||s.scrollLeft||a.scrollLeft,l=s.clientTop||a.clientTop||0,d=s.clientLeft||a.clientLeft||0;
|
||||
|
||||
return e=i.top+r-l,n=i.left+o-d,{y:Math.round(e),x:Math.round(n),width:t.offsetWidth,height:t.offsetHeight}}for(;t;)e+=parseInt(t.offsetTop,10),n+=parseInt(t.offsetLeft,10),t=t.offsetParent;return{y:e,x:n,width:t.offsetWidth,height:t.offsetHeight}},gantt._detectScrollSize=function(){var t=document.createElement("div");t.style.cssText="visibility:hidden;position:absolute;left:-1000px;width:100px;padding:0px;margin:0px;height:110px;min-height:100px;overflow-y:scroll;",document.body.appendChild(t);var e=t.offsetWidth-t.clientWidth;
|
||||
|
||||
return document.body.removeChild(t),e},window.dhtmlx&&(dhtmlx.attaches||(dhtmlx.attaches={}),dhtmlx.attaches.attachGantt=function(t,e,n){var i=document.createElement("DIV");i.id="gantt_"+dhtmlx.uid(),i.style.width="100%",i.style.height="100%",i.cmp="grid",n=n||window.gantt,document.body.appendChild(i),this.attachObject(i.id);var a=this.vs[this.av];a.grid=n,n.init(i.id,t,e),i.firstChild.style.border="none",a.gridId=i.id,a.gridObj=i;var s="_viewRestore";return this.vs[this[s]()].grid}),"undefined"!=typeof window.dhtmlXCellObject&&(dhtmlXCellObject.prototype.attachGantt=function(t,e,n){
|
||||
var i=document.createElement("DIV");i.id="gantt_"+dhtmlx.uid(),i.style.width="100%",i.style.height="100%",i.cmp="grid",document.body.appendChild(i),this.attachObject(i.id),n=n||window.gantt,n.init(i.id,t,e),i.firstChild.style.border="none";return i=null,this.callEvent("_onContentAttach",[]),this.dataObj}),dhtmlxEventable(gantt),dhx4.ajax.cache=!0,gantt._click={},gantt._dbl_click={},gantt._context_menu={},gantt._on_click=function(t){t=t||window.event;var e=t.target||t.srcElement,n=gantt.locate(t),i=!0;
|
||||
|
||||
if(null!==n?i=!gantt.checkEvent("onTaskClick")||gantt.callEvent("onTaskClick",[n,t]):gantt.callEvent("onEmptyClick",[t]),i){var a=gantt._find_ev_handler(t,e,gantt._click,n);if(!a)return;n&&gantt.getTask(n)&&gantt.config.select_task&&gantt.selectTask(n)}},gantt._on_contextmenu=function(t){t=t||window.event;var e=t.target||t.srcElement,n=gantt.locate(e),i=gantt.locate(e,gantt.config.link_attribute),a=!gantt.checkEvent("onContextMenu")||gantt.callEvent("onContextMenu",[n,i,t]);return a||(t.preventDefault?t.preventDefault():t.returnValue=!1),
|
||||
a},gantt._find_ev_handler=function(t,e,n,i){for(var a=!0;e;){var s=e.className||"";if(s){s=s.split(" ");for(var r=0;r<s.length;r++)if(s[r]&&n[s[r]]){var o=n[s[r]].call(gantt,t,i,e);a=a&&!("undefined"!=typeof o&&o!==!0)}}e=e.parentNode}return a},gantt._on_dblclick=function(t){t=t||window.event;var e=t.target||t.srcElement,n=gantt.locate(t),i=!gantt.checkEvent("onTaskDblClick")||gantt.callEvent("onTaskDblClick",[n,t]);if(i){var a=gantt._find_ev_handler(t,e,gantt._dbl_click,n);if(!a)return;null!==n&&gantt.getTask(n)&&i&&gantt.config.details_on_dblclick&&gantt.showLightbox(n);
|
||||
|
||||
}},gantt._on_mousemove=function(t){if(gantt.checkEvent("onMouseMove")){var e=gantt.locate(t);gantt._last_move_event=t,gantt.callEvent("onMouseMove",[e,t])}},dhtmlxDnD.prototype={dragStart:function(t,e){this.config={obj:t,marker:null,started:!1,pos:this.getPosition(e),sensitivity:4},this._settings&&dhtmlx.mixin(this.config,this._settings,!0);var n=dhtmlx.bind(function(e){return this.dragMove(t,e)},this),i=(dhtmlx.bind(function(e){return this.dragScroll(t,e)},this),dhtmlx.bind(function(t){return dhtmlx.defined(this.config.updates_per_second)&&!gantt._checkTimeout(this,this.config.updates_per_second)?!0:n(t);
|
||||
|
||||
},this)),a=dhtmlx.bind(function(){return dhtmlxDetachEvent(document.body,"mousemove",i),dhtmlxDetachEvent(document.body,"mouseup",a),this.dragEnd(t)},this);dhtmlxEvent(document.body,"mousemove",i),dhtmlxEvent(document.body,"mouseup",a),document.body.className+=" gantt_noselect"},dragMove:function(t,e){if(!this.config.marker&&!this.config.started){var n=this.getPosition(e),i=n.x-this.config.pos.x,a=n.y-this.config.pos.y,s=Math.sqrt(Math.pow(Math.abs(i),2)+Math.pow(Math.abs(a),2));if(s>this.config.sensitivity){
|
||||
if(this.config.started=!0,this.config.ignore=!1,this.callEvent("onBeforeDragStart",[t,this.config.original_target])===!1)return this.config.ignore=!0,!0;var r=this.config.marker=document.createElement("div");r.className="gantt_drag_marker",r.innerHTML="Dragging object",document.body.appendChild(r),this.callEvent("onAfterDragStart",[t,this.config.original_target])}else this.config.ignore=!0}this.config.ignore||(e.pos=this.getPosition(e),this.config.marker.style.left=e.pos.x+"px",this.config.marker.style.top=e.pos.y+"px",
|
||||
this.callEvent("onDragMove",[t,e]))},dragEnd:function(){this.config.marker&&(this.config.marker.parentNode.removeChild(this.config.marker),this.config.marker=null,this.callEvent("onDragEnd",[])),document.body.className=document.body.className.replace(" gantt_noselect","")},getPosition:function(t){var e=0,n=0;return t=t||window.event,t.pageX||t.pageY?(e=t.pageX,n=t.pageY):(t.clientX||t.clientY)&&(e=t.clientX+document.body.scrollLeft+document.documentElement.scrollLeft,n=t.clientY+document.body.scrollTop+document.documentElement.scrollTop),
|
||||
{x:e,y:n}}},gantt._init_grid=function(){this._click.gantt_close=dhtmlx.bind(function(t,e){return this.close(e),!1},this),this._click.gantt_open=dhtmlx.bind(function(t,e){return this.open(e),!1},this),this._click.gantt_row=dhtmlx.bind(function(t,e,n){if(null!==e){var i=this.getTask(e);this.config.scroll_on_click&&this.showDate(i.start_date),this.callEvent("onTaskRowClick",[e,n])}},this),this._click.gantt_grid_head_cell=dhtmlx.bind(function(t,e,n){var i=n.getAttribute("column_id");if(this.callEvent("onGridHeaderClick",[i,t]))if("add"==i)this._click.gantt_add(t,this.config.root_id);
|
||||
else if(this.config.sort){var a=this._sort&&this._sort.direction&&this._sort.name==i?this._sort.direction:"desc";a="desc"==a?"asc":"desc",this._sort={name:i,direction:a},this.sort(i,"desc"==a)}},this),!this.config.sort&&this.config.order_branch&&this._init_dnd(),this._click.gantt_add=dhtmlx.bind(function(t,e){if(!this.config.readonly){var n={};return this.createTask(n,e?e:this.config.root_id),!1}},this),this._init_resize&&this._init_resize()},gantt._render_grid=function(){this._is_grid_visible()&&(this._calc_grid_width(),
|
||||
this._render_grid_header())},gantt._calc_grid_width=function(){for(var t=this.getGridColumns(),e=0,n=[],i=[],a=0;a<t.length;a++){var s=parseInt(t[a].width,10);window.isNaN(s)&&(s=50,n.push(a)),i[a]=s,e+=s}if(this.config.autofit||n.length){{var r=this._get_grid_width()-e;r/(n.length>0?n.length:i.length>0?i.length:1)}if(n.length>0)for(var o=r/(n.length?n.length:1),a=0;a<n.length;a++){var l=n[a];i[l]+=o}else for(var o=r/(i.length?i.length:1),a=0;a<i.length;a++)i[a]+=o;for(var a=0;a<i.length;a++)t[a].width=i[a];
|
||||
|
||||
}else this.config.grid_width=e},gantt._render_grid_header=function(){for(var t=this.getGridColumns(),e=[],n=0,i=this.locale.labels,a=this.config.scale_height-2,s=0;s<t.length;s++){var r=s==t.length-1,o=t[s];r&&this._get_grid_width()>n+o.width&&(o.width=this._get_grid_width()-n),n+=o.width;var l=this._sort&&o.name==this._sort.name?"<div class='gantt_sort gantt_"+this._sort.direction+"'></div>":"",d=["gantt_grid_head_cell","gantt_grid_head_"+o.name,r?"gantt_last_cell":"",this.templates.grid_header_class(o.name,o)].join(" "),_="width:"+(o.width-(r?1:0))+"px;",h=o.label||i["column_"+o.name];
|
||||
|
||||
h=h||"";var c="<div class='"+d+"' style='"+_+"' column_id='"+o.name+"'>"+h+l+"</div>";e.push(c)}this.$grid_scale.style.height=this.config.scale_height-1+"px",this.$grid_scale.style.lineHeight=a+"px",this.$grid_scale.style.width=n-1+"px",this.$grid_scale.innerHTML=e.join("")},gantt._render_grid_item=function(t){if(!gantt._is_grid_visible())return null;for(var e=this.getGridColumns(),n=[],i=0;i<e.length;i++){var a,s,r=i==e.length-1,o=e[i];"add"==o.name?s="<div class='gantt_add'></div>":(s=o.template?o.template(t):t[o.name],
|
||||
s instanceof Date&&(s=this.templates.date_grid(s)),s="<div class='gantt_tree_content'>"+s+"</div>");var l="gantt_cell"+(r?" gantt_last_cell":""),d="";if(o.tree){for(var _=0;_<t.$level;_++)d+=this.templates.grid_indent(t);var h=this._has_children(t.id);h?(d+=this.templates.grid_open(t),d+=this.templates.grid_folder(t)):(d+=this.templates.grid_blank(t),d+=this.templates.grid_file(t))}var c="width:"+(o.width-(r?1:0))+"px;";dhtmlx.defined(o.align)&&(c+="text-align:"+o.align+";"),a="<div class='"+l+"' style='"+c+"'>"+d+s+"</div>",
|
||||
n.push(a)}var l=t.$index%2===0?"":" odd";if(l+=t.$transparent?" gantt_transparent":"",this.templates.grid_row_class){var g=this.templates.grid_row_class.call(this,t.start_date,t.end_date,t);g&&(l+=" "+g)}this.getState().selected_task==t.id&&(l+=" gantt_selected");var u=document.createElement("div");return u.className="gantt_row"+l,u.style.height=this.config.row_height+"px",u.style.lineHeight=gantt.config.row_height+"px",u.setAttribute(this.config.task_attribute,t.id),u.innerHTML=n.join(""),u},gantt.open=function(t){
|
||||
gantt._set_item_state(t,!0),this.callEvent("onTaskOpened",[t])},gantt.close=function(t){gantt._set_item_state(t,!1),this.callEvent("onTaskClosed",[t])},gantt._set_item_state=function(t,e){t&&this._pull[t]&&(this._pull[t].$open=e,this.refreshData())},gantt._is_grid_visible=function(){return this.config.grid_width&&this.config.show_grid},gantt._get_grid_width=function(){return this._is_grid_visible()?this._is_chart_visible()?this.config.grid_width:this._x:0},gantt.getTaskIndex=function(t){for(var e=this.getChildren(this.getParent(t)),n=0;n<e.length;n++)if(e[n]==t)return n;
|
||||
|
||||
return-1},gantt.getGlobalTaskIndex=function(t){for(var e=this._order,n=0;n<e.length;n++)if(e[n]==t)return n;return-1},gantt.moveTask=function(t,e,n){var i=arguments[3];if(i){if(i===t)return;n=this.getParent(i),e=this.getTaskIndex(i)}if(t!=n){n=n||this.config.root_id;var a=this.getTask(t),s=this.getParent(a.id),r=(this.getChildren(this.getParent(a.id)),this.getChildren(n));if(-1==e&&(e=r.length+1),s==n){var o=this.getTaskIndex(t);if(o==e)return}if(this.callEvent("onBeforeTaskMove",[t,n,e])!==!1){this._replace_branch_child(s,t),
|
||||
r=this.getChildren(n);var l=r[e];l?r=r.slice(0,e).concat([t]).concat(r.slice(e)):r.push(t),this.setParent(a,n),this._branches[n]=r;for(var d=this._getTaskTree(t),_=0;_<d.length;_++){var h=this._pull[d[_]];h&&(h.$level=this.calculateTaskLevel(h))}a.$drop_target=1*e>0?i?(this.getTaskIndex(t)>this.getTaskIndex(i)?"next:":"")+i:"next:"+gantt.getPrevSibling(t):r[1*e+1]?r[1*e+1]:n,this.callEvent("onAfterTaskMove",[t,n,e])&&this.refreshData()}}},gantt._init_dnd=function(){var t=new dhtmlxDnD(this.$grid_data,{
|
||||
updates_per_second:60});dhtmlx.defined(this.config.dnd_sensitivity)&&(t.config.sensitivity=this.config.dnd_sensitivity),t.attachEvent("onBeforeDragStart",dhtmlx.bind(function(e,n){var i=this._locateHTML(n);if(!i)return!1;this.hideQuickInfo&&this._hideQuickInfo();var a=this.locate(n),s=gantt.getTask(a);return gantt._is_readonly(s)?!1:(t.config.initial_open_state=s.$open,this.callEvent("onRowDragStart",[a,n.target||n.srcElement,n])?void 0:!1)},this)),t.attachEvent("onAfterDragStart",dhtmlx.bind(function(e,n){
|
||||
var i=this._locateHTML(n);t.config.marker.innerHTML=i.outerHTML,t.config.id=this.locate(n);var a=this.getTask(t.config.id);t.config.index=this.getTaskIndex(t.config.id),t.config.parent=a.parent,a.$open=!1,a.$transparent=!0,this.refreshData()},this)),t.lastTaskOfLevel=function(t){for(var e=gantt._order,n=gantt._pull,i=null,a=0,s=e.length;s>a;a++)n[e[a]].$level==t&&(i=n[e[a]]);return i?i.id:null},t._getGridPos=dhtmlx.bind(function(t){var e=this._get_position(this.$grid_data),n=e.x,i=t.pos.y-10;return i<e.y&&(i=e.y),
|
||||
i>e.y+this.$grid_data.offsetHeight-this.config.row_height&&(i=e.y+this.$grid_data.offsetHeight-this.config.row_height),e.x=n,e.y=i,e},this),t.attachEvent("onDragMove",dhtmlx.bind(function(e,n){var i=t.config,a=t._getGridPos(n);i.marker.style.left=a.x+10+"px",i.marker.style.top=a.y+"px",a=t._getGridPos(n);var s=(a.x,a.y),r=document.elementFromPoint(a.x-document.body.scrollLeft+1,s-document.body.scrollTop),o=this.locate(r),l=this.getTask(t.config.id);if(this.isTaskExists(o)||(o=t.lastTaskOfLevel(l.$level),
|
||||
o==t.config.id&&(o=null)),this.isTaskExists(o)){var d=gantt._get_position(r),_=this.getTask(o);if(d.y+r.offsetHeight/2<s){var h=this.getGlobalTaskIndex(_.id),c=this._pull[this._order[h+1]];if(c){if(c.id==l.id)return;_=c}else if(c=this._pull[this._order[h]],c.$level==l.$level&&c.id!=l.id)return void this.moveTask(l.id,-1,this.getParent(c.id))}for(var h=this.getGlobalTaskIndex(_.id),g=this._pull[this._order[h-1]],u=1;(!g||g.id==_.id)&&h-u>=0;)g=this._pull[this._order[h-u]],u++;if(l.id==_.id)return;
|
||||
_.$level==l.$level&&l.id!=_.id?this.moveTask(l.id,0,0,_.id):_.$level!=l.$level-1||gantt.getChildren(_.id).length?g&&g.$level==l.$level&&l.id!=g.id&&this.moveTask(l.id,-1,this.getParent(g.id)):this.moveTask(l.id,0,_.id)}return!0},this)),t.attachEvent("onDragEnd",dhtmlx.bind(function(){var e=this.getTask(t.config.id);this.callEvent("onBeforeRowDragEnd",[t.config.id,t.config.index,t.config.parent])===!1?(this.moveTask(t.config.id,t.config.index,t.config.parent),e.$drop_target=null):this.callEvent("onRowDragEnd",[t.config.id,e.$drop_target]),
|
||||
e.$transparent=!1,e.$open=t.config.initial_open_state,this.refreshData()},this))},gantt.getGridColumns=function(){return this.config.columns},gantt._has_children=function(t){return this.getChildren(t).length>0},gantt._scale_helpers={getSum:function(t,e,n){void 0===n&&(n=t.length-1),void 0===e&&(e=0);for(var i=0,a=e;n>=a;a++)i+=t[a];return i},setSumWidth:function(t,e,n,i){var a=e.width;void 0===i&&(i=a.length-1),void 0===n&&(n=0);var s=i-n+1;if(!(n>a.length-1||0>=s||i>a.length-1)){var r=this.getSum(a,n,i),o=t-r;
|
||||
|
||||
this.adjustSize(o,a,n,i),this.adjustSize(-o,a,i+1),e.full_width=this.getSum(a)}},splitSize:function(t,e){for(var n=[],i=0;e>i;i++)n[i]=0;return this.adjustSize(t,n),n},adjustSize:function(t,e,n,i){n||(n=0),void 0===i&&(i=e.length-1);for(var a=i-n+1,s=this.getSum(e,n,i),r=0,o=n;i>=o;o++){var l=Math.floor(t*(s?e[o]/s:1/a));s-=e[o],t-=l,a--,e[o]+=l,r+=l}e[e.length-1]+=t},sortScales:function(t){function e(t,e){var n=new Date(1970,0,1);return gantt.date.add(n,e,t)-n}t.sort(function(t,n){return e(t.unit,t.step)<e(n.unit,n.step)?1:e(t.unit,t.step)>e(n.unit,n.step)?-1:0;
|
||||
|
||||
})},primaryScale:function(){return gantt._init_template("date_scale"),{unit:gantt.config.scale_unit,step:gantt.config.step,template:gantt.templates.date_scale,date:gantt.config.date_scale,css:gantt.templates.scale_cell_class}},prepareConfigs:function(t,e,n,i){for(var a=this.splitSize(i,t.length),s=n,r=[],o=t.length-1;o>=0;o--){var l=o==t.length-1,d=this.initScaleConfig(t[o]);l&&this.processIgnores(d),this.initColSizes(d,e,s,a[o]),this.limitVisibleRange(d),l&&(s=d.full_width),r.unshift(d)}for(var o=0;o<r.length-1;o++)this.alineScaleColumns(r[r.length-1],r[o]);
|
||||
|
||||
for(var o=0;o<r.length;o++)this.setPosSettings(r[o]);return r},setPosSettings:function(t){for(var e=0,n=t.trace_x.length;n>e;e++)t.left.push((t.width[e-1]||0)+(t.left[e-1]||0))},_ignore_time_config:function(t){return this.config.skip_off_time?!this.isWorkTime(t):!1},processIgnores:function(t){t.ignore_x={},t.display_count=t.count},initColSizes:function(t,e,n,i){var a=n;t.height=i;var s=void 0===t.display_count?t.count:t.display_count;s||(s=1),t.col_width=Math.floor(a/s),e&&t.col_width<e&&(t.col_width=e,
|
||||
a=t.col_width*s),t.width=[];for(var r=t.ignore_x||{},o=0;o<t.trace_x.length;o++)t.width[o]=r[t.trace_x[o].valueOf()]||t.display_count==t.count?0:1;this.adjustSize(a-this.getSum(t.width),t.width),t.full_width=this.getSum(t.width)},initScaleConfig:function(t){var e=dhtmlx.mixin({count:0,col_width:0,full_width:0,height:0,width:[],left:[],trace_x:[]},t);return this.eachColumn(t.unit,t.step,function(t){e.count++,e.trace_x.push(new Date(t))}),e},iterateScales:function(t,e,n,i,a){for(var s=e.trace_x,r=t.trace_x,o=n||0,l=i||r.length-1,d=0,_=1;_<s.length;_++)for(var h=o;l>=h;h++)+r[h]!=+s[_]||(a&&a.apply(this,[d,_,o,h]),
|
||||
o=h,d=_)},alineScaleColumns:function(t,e,n,i){this.iterateScales(t,e,n,i,function(n,i,a,s){var r=this.getSum(t.width,a,s-1),o=this.getSum(e.width,n,i-1);o!=r&&this.setSumWidth(r,e,n,i-1)})},eachColumn:function(t,e,n){var i=new Date(gantt._min_date),a=new Date(gantt._max_date);gantt.date[t+"_start"]&&(i=gantt.date[t+"_start"](i));var s=new Date(i);for(+s>=+a&&(a=gantt.date.add(s,e,t));+a>+s;)n.call(this,new Date(s)),s=gantt.date.add(s,e,t),s=gantt.date[t+"_start"](s)},limitVisibleRange:function(t){
|
||||
var e=t.trace_x,n=0,i=t.width.length-1,a=0;if(+e[0]<+gantt._min_date&&n!=i){var s=Math.floor(t.width[0]*((e[1]-gantt._min_date)/(e[1]-e[0])));a+=t.width[0]-s,t.width[0]=s,e[0]=new Date(gantt._min_date)}var r=e.length-1,o=e[r],l=gantt.date.add(o,t.step,t.unit);if(+l>+gantt._max_date&&r>0){var s=t.width[r]-Math.floor(t.width[r]*((l-gantt._max_date)/(l-o)));a+=t.width[r]-s,t.width[r]=s}if(a){for(var d=this.getSum(t.width),_=0,h=0;h<t.width.length;h++){var c=Math.floor(a*(t.width[h]/d));t.width[h]+=c,
|
||||
_+=c}this.adjustSize(a-_,t.width)}}},gantt._tasks_dnd={drag:null,_events:{before_start:{},before_finish:{},after_finish:{}},_handlers:{},init:function(){this.clear_drag_state();var t=gantt.config.drag_mode;this.set_actions();var e={before_start:"onBeforeTaskDrag",before_finish:"onBeforeTaskChanged",after_finish:"onAfterTaskDrag"};for(var n in this._events)for(var i in t)this._events[n][i]=e[n];this._handlers[t.move]=this._move,this._handlers[t.resize]=this._resize,this._handlers[t.progress]=this._resize_progress;
|
||||
|
||||
},set_actions:function(){var t=gantt.$task_data;dhtmlxEvent(t,"mousemove",dhtmlx.bind(function(t){this.on_mouse_move(t||event)},this)),dhtmlxEvent(t,"mousedown",dhtmlx.bind(function(t){this.on_mouse_down(t||event)},this)),dhtmlxEvent(t,"mouseup",dhtmlx.bind(function(t){this.on_mouse_up(t||event)},this))},clear_drag_state:function(){this.drag={id:null,mode:null,pos:null,start_x:null,start_y:null,obj:null,left:null}},_resize:function(t,e,n){var i=gantt.config,a=this._drag_task_coords(t,n);n.left?(t.start_date=gantt.dateFromPos(a.start+e),
|
||||
t.start_date||(t.start_date=new Date(gantt.getState().min_date))):(t.end_date=gantt.dateFromPos(a.end+e),t.end_date||(t.end_date=new Date(gantt.getState().max_date))),t.end_date-t.start_date<i.min_duration&&(n.left?t.start_date=gantt.calculateEndDate(t.end_date,-1):t.end_date=gantt.calculateEndDate(t.start_date,1)),gantt._init_task_timing(t)},_resize_progress:function(t,e,n){var i=this._drag_task_coords(t,n),a=Math.max(0,n.pos.x-i.start);t.progress=Math.min(1,a/(i.end-i.start))},_move:function(t,e,n){
|
||||
var i=this._drag_task_coords(t,n),a=gantt.dateFromPos(i.start+e),s=gantt.dateFromPos(i.end+e);a?s?(t.start_date=a,t.end_date=s):(t.end_date=new Date(gantt.getState().max_date),t.start_date=gantt.dateFromPos(gantt.posFromDate(t.end_date)-(i.end-i.start))):(t.start_date=new Date(gantt.getState().min_date),t.end_date=gantt.dateFromPos(gantt.posFromDate(t.start_date)+(i.end-i.start)))},_drag_task_coords:function(t,e){var n=e.obj_s_x=e.obj_s_x||gantt.posFromDate(t.start_date),i=e.obj_e_x=e.obj_e_x||gantt.posFromDate(t.end_date);
|
||||
|
||||
return{start:n,end:i}},on_mouse_move:function(t){this.drag.start_drag&&this._start_dnd(t);var e=this.drag;if(e.mode){if(!gantt._checkTimeout(this,40))return;this._update_on_move(t)}},_update_on_move:function(t){var e=this.drag;if(e.mode){var n=gantt._get_mouse_pos(t);if(e.pos&&e.pos.x==n.x)return;e.pos=n;var i=gantt.dateFromPos(n.x);if(!i||isNaN(i.getTime()))return;var a=n.x-e.start_x,s=gantt.getTask(e.id);if(this._handlers[e.mode]){var r=dhtmlx.mixin({},s),o=dhtmlx.mixin({},s);this._handlers[e.mode].apply(this,[o,a,e]),
|
||||
dhtmlx.mixin(s,o,!0),gantt._update_parents(e.id,!0),gantt.callEvent("onTaskDrag",[s.id,e.mode,o,r,t]),dhtmlx.mixin(s,o,!0),gantt._update_parents(e.id),gantt.refreshTask(e.id)}}},on_mouse_down:function(t,e){if(2!=t.button){var n=gantt.locate(t),i=null;if(gantt.isTaskExists(n)&&(i=gantt.getTask(n)),!gantt._is_readonly(i)&&!this.drag.mode){this.clear_drag_state(),e=e||t.target||t.srcElement;var a=gantt._trim(e.className||"");if(!a||!this._get_drag_mode(a))return e.parentNode?this.on_mouse_down(t,e.parentNode):void 0;
|
||||
|
||||
var s=this._get_drag_mode(a);if(s)if(s.mode&&s.mode!=gantt.config.drag_mode.ignore&&gantt.config["drag_"+s.mode]){if(n=gantt.locate(e),i=dhtmlx.copy(gantt.getTask(n)||{}),gantt._is_readonly(i))return this.clear_drag_state(),!1;if(gantt._is_flex_task(i)&&s.mode!=gantt.config.drag_mode.progress)return void this.clear_drag_state();s.id=n;var r=gantt._get_mouse_pos(t);s.start_x=r.x,s.start_y=r.y,s.obj=i,this.drag.start_drag=s}else this.clear_drag_state();else if(gantt.checkEvent("onMouseDown")&&gantt.callEvent("onMouseDown",[a.split(" ")[0]])&&e.parentNode)return this.on_mouse_down(t,e.parentNode);
|
||||
|
||||
}}},_fix_dnd_scale_time:function(t,e){function n(t){gantt.isWorkTime(t.start_date)||(t.start_date=gantt.calculateEndDate(t.start_date,-1,gantt.config.duration_unit))}function i(t){gantt.isWorkTime(new Date(t.end_date-1))||(t.end_date=gantt.calculateEndDate(t.end_date,1,gantt.config.duration_unit))}var a=gantt._tasks.unit,s=gantt._tasks.step;gantt.config.round_dnd_dates||(a="minute",s=gantt.config.time_step),e.mode==gantt.config.drag_mode.resize?e.left?(t.start_date=gantt.roundDate({date:t.start_date,
|
||||
unit:a,step:s}),n(t)):(t.end_date=gantt.roundDate({date:t.end_date,unit:a,step:s}),i(t)):e.mode==gantt.config.drag_mode.move&&(t.start_date=gantt.roundDate({date:t.start_date,unit:a,step:s}),n(t),t.end_date=gantt.calculateEndDate(t.start_date,t.duration,gantt.config.duration_unit))},_fix_working_times:function(t,e){var e=e||{mode:gantt.config.drag_mode.move};gantt.config.work_time&&gantt.config.correct_work_time&&(e.mode==gantt.config.drag_mode.resize?e.left?t.start_date=gantt.getClosestWorkTime({
|
||||
date:t.start_date,dir:"future"}):t.end_date=gantt.getClosestWorkTime({date:t.end_date,dir:"past"}):e.mode==gantt.config.drag_mode.move&&gantt.correctTaskWorkTime(t))},on_mouse_up:function(t){var e=this.drag;if(e.mode&&e.id){var n=gantt.getTask(e.id);if(gantt.config.work_time&&gantt.config.correct_work_time&&this._fix_working_times(n,e),this._fix_dnd_scale_time(n,e),gantt._init_task_timing(n),this._fireEvent("before_finish",e.mode,[e.id,e.mode,dhtmlx.copy(e.obj),t])){var i=e.id;gantt._init_task_timing(n),
|
||||
this._fireEvent("after_finish",e.mode,[i,e.mode,t]),this.clear_drag_state(),gantt.updateTask(n.id)}else e.obj._dhx_changed=!1,dhtmlx.mixin(n,e.obj,!0),gantt.updateTask(n.id)}this.clear_drag_state()},_get_drag_mode:function(t){var e=gantt.config.drag_mode,n=(t||"").split(" "),i=n[0],a={mode:null,left:null};switch(i){case"gantt_task_line":case"gantt_task_content":a.mode=e.move;break;case"gantt_task_drag":a.mode=e.resize,a.left=n[1]&&-1!==n[1].indexOf("left",n[1].length-"left".length)?!0:!1;break;case"gantt_task_progress_drag":
|
||||
a.mode=e.progress;break;case"gantt_link_control":case"gantt_link_point":a.mode=e.ignore;break;default:a=null}return a},_start_dnd:function(t){var e=this.drag=this.drag.start_drag;delete e.start_drag;var n=gantt.config,i=e.id;n["drag_"+e.mode]&&gantt.callEvent("onBeforeDrag",[i,e.mode,t])&&this._fireEvent("before_start",e.mode,[i,e.mode,t])?delete e.start_drag:this.clear_drag_state()},_fireEvent:function(t,e,n){dhtmlx.assert(this._events[t],"Invalid stage:{"+t+"}");var i=this._events[t][e];return dhtmlx.assert(i,"Unknown after drop mode:{"+e+"}"),
|
||||
dhtmlx.assert(n,"Invalid event arguments"),gantt.checkEvent(i)?gantt.callEvent(i,n):!0}},gantt.roundTaskDates=function(t){var e=gantt._tasks_dnd.drag;e||(e={mode:gantt.config.drag_mode.move}),gantt._tasks_dnd._fix_dnd_scale_time(t,e)},gantt._render_link=function(t){for(var e=this.getLink(t),n=gantt._get_link_renderers(),i=0;i<n.length;i++)n[i].render_item(e)},gantt._get_link_type=function(t,e){var n=null;return t&&e?n=gantt.config.links.start_to_start:!t&&e?n=gantt.config.links.finish_to_start:t||e?t&&!e&&(n=gantt.config.links.start_to_finish):n=gantt.config.links.finish_to_finish,
|
||||
n},gantt.isLinkAllowed=function(t,e,n,i){var a=null;if(a="object"==typeof t?t:{source:t,target:e,type:this._get_link_type(n,i)},!a)return!1;if(!(a.source&&a.target&&a.type))return!1;if(a.source==a.target)return!1;var s=!0;return this.checkEvent("onLinkValidation")&&(s=this.callEvent("onLinkValidation",[a])),s},gantt._render_link_element=function(t){var e=this._path_builder.get_points(t),n=gantt._drawer,i=n.get_lines(e),a=document.createElement("div"),s="gantt_task_link";t.color&&(s+=" gantt_link_inline_color");
|
||||
|
||||
var r=this.templates.link_class?this.templates.link_class(t):"";r&&(s+=" "+r),this.config.highlight_critical_path&&this.isCriticalLink&&this.isCriticalLink(t)&&(s+=" gantt_critical_link"),a.className=s,a.setAttribute(gantt.config.link_attribute,t.id);for(var o=0;o<i.length;o++){o==i.length-1&&(i[o].size-=gantt.config.link_arrow_size);var l=n.render_line(i[o],i[o+1]);t.color&&(l.firstChild.style.backgroundColor=t.color),a.appendChild(l)}var d=i[i.length-1].direction,_=gantt._render_link_arrow(e[e.length-1],d);
|
||||
|
||||
return t.color&&(_.style.borderColor=t.color),a.appendChild(_),a},gantt._render_link_arrow=function(t,e){var n=document.createElement("div"),i=gantt._drawer,a=t.y,s=t.x,r=gantt.config.link_arrow_size,o=gantt.config.row_height,l="gantt_link_arrow gantt_link_arrow_"+e;switch(e){case i.dirs.right:a-=(r-o)/2,s-=r;break;case i.dirs.left:a-=(r-o)/2;break;case i.dirs.up:s-=(r-o)/2;break;case i.dirs.down:a-=r,s-=(r-o)/2}return n.style.cssText=["top:"+a+"px","left:"+s+"px"].join(";"),n.className=l,n},gantt._drawer={
|
||||
current_pos:null,dirs:{left:"left",right:"right",up:"up",down:"down"},path:[],clear:function(){this.current_pos=null,this.path=[]},point:function(t){this.current_pos=dhtmlx.copy(t)},get_lines:function(t){this.clear(),this.point(t[0]);for(var e=1;e<t.length;e++)this.line_to(t[e]);return this.get_path()},line_to:function(t){var e=dhtmlx.copy(t),n=this.current_pos,i=this._get_line(n,e);this.path.push(i),this.current_pos=e},get_path:function(){return this.path},get_wrapper_sizes:function(t){var e,n=gantt.config.link_wrapper_width,i=(gantt.config.link_line_width,
|
||||
t.y+(gantt.config.row_height-n)/2);switch(t.direction){case this.dirs.left:e={top:i,height:n,lineHeight:n,left:t.x-t.size-n/2,width:t.size+n};break;case this.dirs.right:e={top:i,lineHeight:n,height:n,left:t.x-n/2,width:t.size+n};break;case this.dirs.up:e={top:i-t.size,lineHeight:t.size+n,height:t.size+n,left:t.x-n/2,width:n};break;case this.dirs.down:e={top:i,lineHeight:t.size+n,height:t.size+n,left:t.x-n/2,width:n}}return e},get_line_sizes:function(t){var e,n=gantt.config.link_line_width,i=gantt.config.link_wrapper_width,a=t.size+n;
|
||||
|
||||
switch(t.direction){case this.dirs.left:case this.dirs.right:e={height:n,width:a,marginTop:(i-n)/2,marginLeft:(i-n)/2};break;case this.dirs.up:case this.dirs.down:e={height:a,width:n,marginTop:(i-n)/2,marginLeft:(i-n)/2}}return e},render_line:function(t){var e=this.get_wrapper_sizes(t),n=document.createElement("div");n.style.cssText=["top:"+e.top+"px","left:"+e.left+"px","height:"+e.height+"px","width:"+e.width+"px"].join(";"),n.className="gantt_line_wrapper";var i=this.get_line_sizes(t),a=document.createElement("div");
|
||||
|
||||
return a.style.cssText=["height:"+i.height+"px","width:"+i.width+"px","margin-top:"+i.marginTop+"px","margin-left:"+i.marginLeft+"px"].join(";"),a.className="gantt_link_line_"+t.direction,n.appendChild(a),n},_get_line:function(t,e){var n=this.get_direction(t,e),i={x:t.x,y:t.y,direction:this.get_direction(t,e)};return i.size=Math.abs(n==this.dirs.left||n==this.dirs.right?t.x-e.x:t.y-e.y),i},get_direction:function(t,e){var n=0;return n=e.x<t.x?this.dirs.left:e.x>t.x?this.dirs.right:e.y>t.y?this.dirs.down:this.dirs.up;
|
||||
|
||||
}},gantt._y_from_ind=function(t){return t*gantt.config.row_height},gantt._path_builder={path:[],clear:function(){this.path=[]},current:function(){return this.path[this.path.length-1]},point:function(t){return t?(this.path.push(dhtmlx.copy(t)),t):this.current()},point_to:function(t,e,n){n=n?{x:n.x,y:n.y}:dhtmlx.copy(this.point());var i=gantt._drawer.dirs;switch(t){case i.left:n.x-=e;break;case i.right:n.x+=e;break;case i.up:n.y-=e;break;case i.down:n.y+=e}return this.point(n)},get_points:function(t){
|
||||
var e=this.get_endpoint(t),n=gantt.config,i=e.e_y-e.y,a=e.e_x-e.x,s=gantt._drawer.dirs;this.clear(),this.point({x:e.x,y:e.y});var r=2*n.link_arrow_size,o=e.e_x>e.x;if(t.type==gantt.config.links.start_to_start)this.point_to(s.left,r),o?(this.point_to(s.down,i),this.point_to(s.right,a)):(this.point_to(s.right,a),this.point_to(s.down,i)),this.point_to(s.right,r);else if(t.type==gantt.config.links.finish_to_start)if(o=e.e_x>e.x+2*r,this.point_to(s.right,r),o)a-=r,this.point_to(s.down,i),this.point_to(s.right,a);
|
||||
else{a-=2*r;var l=i>0?1:-1;this.point_to(s.down,l*(n.row_height/2)),this.point_to(s.right,a),this.point_to(s.down,l*(Math.abs(i)-n.row_height/2)),this.point_to(s.right,r)}else if(t.type==gantt.config.links.finish_to_finish)this.point_to(s.right,r),o?(this.point_to(s.right,a),this.point_to(s.down,i)):(this.point_to(s.down,i),this.point_to(s.right,a)),this.point_to(s.left,r);else if(t.type==gantt.config.links.start_to_finish)if(o=e.e_x>e.x-2*r,this.point_to(s.left,r),o){a+=2*r;var l=i>0?1:-1;this.point_to(s.down,l*(n.row_height/2)),
|
||||
this.point_to(s.right,a),this.point_to(s.down,l*(Math.abs(i)-n.row_height/2)),this.point_to(s.left,r)}else a+=r,this.point_to(s.down,i),this.point_to(s.right,a);return this.path},get_endpoint:function(t){var e=gantt.config.links,n=!1,i=!1;t.type==e.start_to_start?n=i=!0:t.type==e.finish_to_finish?n=i=!1:t.type==e.finish_to_start?(n=!1,i=!0):t.type==e.start_to_finish?(n=!0,i=!1):dhtmlx.assert(!1,"Invalid link type");var a=gantt._get_task_visible_pos(gantt._pull[t.source],n),s=gantt._get_task_visible_pos(gantt._pull[t.target],i);
|
||||
|
||||
return{x:a.x,e_x:s.x,y:a.y,e_y:s.y}}},gantt._init_links_dnd=function(){function t(t,e,n){var i=gantt._get_task_pos(t,!!e);return i.y+=gantt._get_task_height()/2,n=n||0,i.x+=(e?-1:1)*n,i}function e(t){var e=i(),n=["gantt_link_tooltip"];e.from&&e.to&&n.push(gantt.isLinkAllowed(e.from,e.to,e.from_start,e.to_start)?"gantt_allowed_link":"gantt_invalid_link");var a=gantt.templates.drag_link_class(e.from,e.from_start,e.to,e.to_start);a&&n.push(a);var s="<div class='"+a+"'>"+gantt.templates.drag_link(e.from,e.from_start,e.to,e.to_start)+"</div>";
|
||||
|
||||
t.innerHTML=s}function n(t,e){t.style.left=e.x+5+"px",t.style.top=e.y+5+"px"}function i(){return{from:gantt._link_source_task,to:gantt._link_target_task,from_start:gantt._link_source_task_start,to_start:gantt._link_target_task_start}}function a(){gantt._link_source_task=gantt._link_source_task_start=gantt._link_target_task=null,gantt._link_target_task_start=!0}function s(t,e,n,a){var s=l(),d=i(),_=["gantt_link_direction"];gantt.templates.link_direction_class&&_.push(gantt.templates.link_direction_class(d.from,d.from_start,d.to,d.to_start));
|
||||
|
||||
var h=Math.sqrt(Math.pow(n-t,2)+Math.pow(a-e,2));if(h=Math.max(0,h-3)){s.className=_.join(" ");var c=(a-e)/(n-t),g=Math.atan(c);2==o(t,n,e,a)?g+=Math.PI:3==o(t,n,e,a)&&(g-=Math.PI);var u=Math.sin(g),f=Math.cos(g),p=Math.round(e),v=Math.round(t),m=["-webkit-transform: rotate("+g+"rad)","-moz-transform: rotate("+g+"rad)","-ms-transform: rotate("+g+"rad)","-o-transform: rotate("+g+"rad)","transform: rotate("+g+"rad)","width:"+Math.round(h)+"px"];if(-1!=window.navigator.userAgent.indexOf("MSIE 8.0")){
|
||||
m.push('-ms-filter: "'+r(u,f)+'"');var k=Math.abs(Math.round(t-n)),x=Math.abs(Math.round(a-e));switch(o(t,n,e,a)){case 1:p-=x;break;case 2:v-=k,p-=x;break;case 3:v-=k}}m.push("top:"+p+"px"),m.push("left:"+v+"px"),s.style.cssText=m.join(";")}}function r(t,e){return"progid:DXImageTransform.Microsoft.Matrix(M11 = "+e+",M12 = -"+t+",M21 = "+t+",M22 = "+e+",SizingMethod = 'auto expand')"}function o(t,e,n,i){return e>=t?n>=i?1:4:n>=i?2:3}function l(){return _._direction||(_._direction=document.createElement("div"),
|
||||
gantt.$task_links.appendChild(_._direction)),_._direction}function d(){_._direction&&(_._direction.parentNode&&_._direction.parentNode.removeChild(_._direction),_._direction=null)}var _=new dhtmlxDnD(this.$task_bars,{sensitivity:0,updates_per_second:60}),h="task_left",c="task_right",g="gantt_link_point",u="gantt_link_control";_.attachEvent("onBeforeDragStart",dhtmlx.bind(function(e,n){var i=n.target||n.srcElement;if(a(),gantt.getState().drag_id)return!1;if(gantt._locate_css(i,g)){gantt._locate_css(i,h)&&(gantt._link_source_task_start=!0);
|
||||
|
||||
var s=gantt._link_source_task=this.locate(n),r=gantt.getTask(s);if(gantt._is_readonly(r))return a(),!1;var o=0;return gantt._get_safe_type(r.type)==gantt.config.types.milestone&&(o=(gantt._get_visible_milestone_width()-gantt._get_milestone_width())/2),this._dir_start=t(r,!!gantt._link_source_task_start,o),!0}return!1},this)),_.attachEvent("onAfterDragStart",dhtmlx.bind(function(){e(_.config.marker)},this)),_.attachEvent("onDragMove",dhtmlx.bind(function(i,a){var r=_.config,o=_.getPosition(a);n(r.marker,o);
|
||||
|
||||
var l=gantt._is_link_drop_area(a),d=gantt._link_target_task,h=gantt._link_landing,g=gantt._link_target_task_start,f=gantt.locate(a),p=!0;if(l&&(p=!gantt._locate_css(a,c),l=!!f),gantt._link_target_task=f,gantt._link_landing=l,gantt._link_target_task_start=p,l){var v=gantt.getTask(f),m=gantt._locate_css(a,u),k=0;m&&(k=Math.floor(m.offsetWidth/2)),this._dir_end=t(v,!!gantt._link_target_task_start,k)}else this._dir_end=gantt._get_mouse_pos(a);var x=!(h==l&&d==f&&g==p);return x&&(d&&gantt.refreshTask(d,!1),
|
||||
f&&gantt.refreshTask(f,!1)),x&&e(r.marker),s(this._dir_start.x,this._dir_start.y,this._dir_end.x,this._dir_end.y),!0},this)),_.attachEvent("onDragEnd",dhtmlx.bind(function(){var t=i();if(t.from&&t.to&&t.from!=t.to){var e=gantt._get_link_type(t.from_start,t.to_start),n={source:t.from,target:t.to,type:e};n.type&&gantt.isLinkAllowed(n)&&gantt.addLink(n)}a(),t.from&&gantt.refreshTask(t.from,!1),t.to&&gantt.refreshTask(t.to,!1),d()},this)),gantt._is_link_drop_area=function(t){return!!gantt._locate_css(t,u);
|
||||
|
||||
}},gantt._get_link_state=function(){return{link_landing_area:this._link_landing,link_target_id:this._link_target_task,link_target_start:this._link_target_task_start,link_source_id:this._link_source_task,link_source_start:this._link_source_task_start}},gantt._init_tasks=function(){function t(t,e,n,i){for(var a=0;a<t.length;a++)t[a].change_id(e,n),t[a].render_item(i)}this._tasks={col_width:this.config.columnWidth,width:[],full_width:0,trace_x:[],rendered:{}},this._click.gantt_task_link=dhtmlx.bind(function(t){
|
||||
var e=this.locate(t,gantt.config.link_attribute);e&&this.callEvent("onLinkClick",[e,t])},this),this._click.gantt_scale_cell=dhtmlx.bind(function(t){var e=gantt._get_mouse_pos(t),n=gantt.dateFromPos(e.x),i=Math.floor(gantt._day_index_by_date(n)),a=gantt._tasks.trace_x[i];gantt.callEvent("onScaleClick",[t,a])},this),this._dbl_click.gantt_task_link=dhtmlx.bind(function(t,e){var e=this.locate(t,gantt.config.link_attribute);this._delete_link_handler(e,t)},this),this._dbl_click.gantt_link_point=dhtmlx.bind(function(t,e,n){
|
||||
var e=this.locate(t),i=this.getTask(e),a=null;return n.parentNode&&n.parentNode.className&&(a=n.parentNode.className.indexOf("_left")>-1?i.$target[0]:i.$source[0]),a&&this._delete_link_handler(a,t),!1},this),this._tasks_dnd.init(),this._init_links_dnd(),this._link_layers.clear();var e=this.addLinkLayer({renderer:this._render_link_element,container:this.$task_links,filter:gantt._create_filter(["_filter_link","_is_chart_visible"])});this._linkRenderer=this._link_layers.getRenderer(e),this._task_layers.clear();
|
||||
|
||||
var n=this.addTaskLayer({renderer:this._render_task_element,container:this.$task_bars,filter:gantt._create_filter(["_filter_task","_is_chart_visible"])});this._taskRenderer=this._task_layers.getRenderer(n),this.addTaskLayer({renderer:this._render_grid_item,container:this.$grid_data,filter:gantt._create_filter(["_filter_task","_is_grid_visible"])}),this.addTaskLayer({renderer:this._render_bg_line,container:this.$task_bg,filter:gantt._create_filter(["_filter_task","_is_chart_visible","_is_std_background"])
|
||||
}),this._onTaskIdChange&&this.detachEvent(this._onTaskIdChange),this._onTaskIdChange=this.attachEvent("onTaskIdChange",function(e,n){var i=this._get_task_renderers();t(i,e,n,this.getTask(n))}),this._onLinkIdChange&&this.detachEvent(this._onLinkIdChange),this._onLinkIdChange=this.attachEvent("onLinkIdChange",function(e,n){var i=this._get_link_renderers();t(i,e,n,this.getLink(n))})},gantt._create_filter=function(t){return t instanceof Array||(t=Array.prototype.slice.call(arguments,0)),function(e){for(var n=!0,i=0,a=t.length;a>i;i++){
|
||||
var s=t[i];gantt[s]&&(n=n&&gantt[s].apply(gantt,[e.id,e])!==!1)}return n}},gantt._is_chart_visible=function(){return!!this.config.show_chart},gantt._filter_task=function(t,e){var n=null,i=null;return this.config.start_date&&this.config.end_date&&(n=this.config.start_date.valueOf(),i=this.config.end_date.valueOf(),+e.start_date>i||+e.end_date<+n)?!1:!0},gantt._filter_link=function(t,e){return this.config.show_links&&gantt.isTaskVisible(e.source)&&gantt.isTaskVisible(e.target)?this.callEvent("onBeforeLinkDisplay",[t,e]):!1;
|
||||
|
||||
},gantt._is_std_background=function(){return!this.config.static_background},gantt._delete_link_handler=function(t,e){if(t&&this.callEvent("onLinkDblClick",[t,e])){var n=gantt.getLink(t);if(gantt._is_readonly(n))return;var i="",a=gantt.locale.labels.link+" "+this.templates.link_description(this.getLink(t))+" "+gantt.locale.labels.confirm_link_deleting;window.setTimeout(function(){gantt._dhtmlx_confirm(a,i,function(){gantt.deleteLink(t)})},gantt.config.touch?300:1)}},gantt.getTaskNode=function(t){return this._taskRenderer.rendered[t];
|
||||
|
||||
},gantt.getLinkNode=function(t){return this._linkRenderer.rendered[t]},gantt._get_tasks_data=function(){for(var t=[],e=0;e<this._order.length;e++){var n=this._pull[this._order[e]];n.$index=e,this.resetProjectDates(n),t.push(n)}return t},gantt._get_links_data=function(){var t=[];for(var e in this._lpull)t.push(this._lpull[e]);return t},gantt._render_data=function(){if(this.callEvent("onBeforeDataRender",[]),this._is_render_active()){this._sync_order(),this._update_layout_sizes(),this.config.static_background&&this._render_bg_canvas();
|
||||
|
||||
for(var t=this._get_tasks_data(),e=this._get_task_renderers(),n=0;n<e.length;n++)e[n].render_items(t);var i=gantt._get_links_data();e=this._get_link_renderers();for(var n=0;n<e.length;n++)e[n].render_items(i);this.callEvent("onDataRender",[])}},gantt._update_layout_sizes=function(){var t=this._tasks;t.bar_height=this._get_task_height(),this.$task_data.style.height=Math.max(this.$task.offsetHeight-this.config.scale_height,0)+"px",this.$task_bg.style.height="",this.$task_bg.style.backgroundImage="";
|
||||
|
||||
for(var e=this.$task_data.childNodes,n=0,i=e.length;i>n;n++){var a=e[n];this._is_layer(a)&&a.style&&(a.style.width=t.full_width+"px")}if(this._is_grid_visible()){for(var s=this.getGridColumns(),r=0,n=0;n<s.length;n++)r+=s[n].width;this.$grid_data.style.width=Math.max(r-1,0)+"px"}},gantt._scale_range_unit=function(){var t=this.config.scale_unit;if(this.config.scale_offset_minimal){var e=this._get_scales();t=e[e.length-1].unit}return t},gantt._init_tasks_range=function(){var t=this._scale_range_unit();
|
||||
|
||||
if(this.config.start_date&&this.config.end_date)return this._min_date=this.date[t+"_start"](new Date(this.config.start_date)),void(this._max_date=this.date[t+"_start"](new Date(this.config.end_date)));this._get_tasks_data();var e=this.getSubtaskDates();this._min_date=e.start_date,this._max_date=e.end_date,this._max_date&&this._max_date||(this._min_date=new Date,this._max_date=new Date(this._min_date)),this._min_date=this.date[t+"_start"](this._min_date),this._min_date=this.calculateEndDate(this.date[t+"_start"](this._min_date),-1,t),
|
||||
this._max_date=this.date[t+"_start"](this._max_date),this._max_date=this.calculateEndDate(this._max_date,2,t)},gantt._prepare_scale_html=function(t){var e=[],n=null,i=null,a=null;(t.template||t.date)&&(i=t.template||this.date.date_to_str(t.date)),a=t.css||function(){},!t.css&&this.config.inherit_scale_class&&(a=gantt.templates.scale_cell_class);for(var s=0;s<t.count;s++){n=new Date(t.trace_x[s]);var r=i.call(this,n),o=t.width[s],l="",d="",_="";if(o){l="width:"+o+"px;",_="gantt_scale_cell"+(s==t.count-1?" gantt_last_cell":""),
|
||||
d=a.call(this,n),d&&(_+=" "+d);var h="<div class='"+_+"' style='"+l+"'>"+r+"</div>";e.push(h)}}return e.join("")},gantt._get_scales=function(){var t=this._scale_helpers,e=[t.primaryScale()].concat(this.config.subscales);return t.sortScales(e),e},gantt._render_tasks_scales=function(){this._init_tasks_range(),this._scroll_resize(),this._set_sizes();var t="",e=0,n=0,i=0;if(this._is_chart_visible()){var a=this._scale_helpers,s=this._get_scales();i=this.config.scale_height-1;for(var r=this._get_resize_options(),o=r.x?Math.max(this.config.autosize_min_width,0):this.$task.offsetWidth,l=a.prepareConfigs(s,this.config.min_column_width,o,i),d=this._tasks=l[l.length-1],_=[],h=this.templates.scale_row_class,c=0;c<l.length;c++){
|
||||
var g="gantt_scale_line",u=h(l[c]);u&&(g+=" "+u),_.push('<div class="'+g+'" style="height:'+l[c].height+"px;line-height:"+l[c].height+'px">'+this._prepare_scale_html(l[c])+"</div>")}t=_.join(""),e=d.full_width+this.$scroll_ver.offsetWidth+"px",n=d.full_width+"px",i+="px"}this.$task.style.display=this._is_chart_visible()?"":"none",this.$task_scale.style.height=i,this.$task_data.style.width=this.$task_scale.style.width=e,this.$task_scale.innerHTML=t},gantt._render_bg_line=function(t){var e=gantt._tasks,n=e.count,i=document.createElement("div");
|
||||
|
||||
if(gantt.config.show_task_cells)for(var a=0;n>a;a++){var s=e.width[a],r="";if(s>0){var o=document.createElement("div");o.style.width=s+"px",r="gantt_task_cell"+(a==n-1?" gantt_last_cell":""),d=this.templates.task_cell_class(t,e.trace_x[a]),d&&(r+=" "+d),o.className=r,i.appendChild(o)}}var l=t.$index%2!==0,d=gantt.templates.task_row_class(t.start_date,t.end_date,t),_="gantt_task_row"+(l?" odd":"")+(d?" "+d:"");return this.getState().selected_task==t.id&&(_+=" gantt_selected"),i.className=_,i.style.height=gantt.config.row_height+"px",
|
||||
i.setAttribute(this.config.task_attribute,t.id),i},gantt._render_bg_canvas=function(){},gantt._adjust_scales=function(){if(this.config.fit_tasks){var t=+this._min_date,e=+this._max_date;if(this._init_tasks_range(),+this._min_date!=t||+this._max_date!=e)return this.render(),this.callEvent("onScaleAdjusted",[]),!0}return!1},gantt.refreshTask=function(t,e){if(this._is_render_active()){var n=this._get_task_renderers(),i=this.getTask(t);if(i&&this.isTaskVisible(t)){for(var a=0;a<n.length;a++)n[a].render_item(i);
|
||||
|
||||
if(void 0!==e&&!e)return;for(var a=0;a<i.$source.length;a++)gantt.refreshLink(i.$source[a]);for(var a=0;a<i.$target.length;a++)gantt.refreshLink(i.$target[a])}else this._render_data()}},gantt.refreshLink=function(t){if(this._is_render_active())if(this.isLinkExists(t))this._render_link(t);else for(var e=this._get_link_renderers(),n=0;n<e.length;n++)e[n].remove_item(t)},gantt._combine_item_class=function(t,e,n){var i=[t];e&&i.push(e);var a=gantt.getState(),s=this.getTask(n);this._get_safe_type(s.type)==this.config.types.milestone&&i.push("gantt_milestone"),
|
||||
this._get_safe_type(s.type)==this.config.types.project&&i.push("gantt_project"),this._is_flex_task(s)&&i.push("gantt_dependent_task"),this.config.select_task&&n==a.selected_task&&i.push("gantt_selected"),n==a.drag_id&&(i.push("gantt_drag_"+a.drag_mode),a.touch_drag&&i.push("gantt_touch_"+a.drag_mode));var r=gantt._get_link_state();if(r.link_source_id==n&&i.push("gantt_link_source"),r.link_target_id==n&&i.push("gantt_link_target"),this.config.highlight_critical_path&&this.isCriticalTask&&this.isCriticalTask(s)&&i.push("gantt_critical_task"),
|
||||
r.link_landing_area&&r.link_target_id&&r.link_source_id&&r.link_target_id!=r.link_source_id){var o=r.link_source_id,l=r.link_source_start,d=r.link_target_start,_=gantt.isLinkAllowed(o,n,l,d),h="";h=_?d?"link_start_allow":"link_finish_allow":d?"link_start_deny":"link_finish_deny",i.push(h)}return i.join(" ")},gantt._render_pair=function(t,e,n,i){var a=gantt.getState();+n.end_date<=+a.max_date&&t.appendChild(i(e+" task_right")),+n.start_date>=+a.min_date&&t.appendChild(i(e+" task_left"))},gantt._get_task_height=function(){
|
||||
var t=this.config.task_height;return"full"==t&&(t=this.config.row_height-5),t=Math.min(t,this.config.row_height),Math.max(t,0)},gantt._get_milestone_width=function(){return this._get_task_height()},gantt._get_visible_milestone_width=function(){var t=gantt._get_task_height();return Math.sqrt(2*t*t)},gantt.getTaskPosition=function(t,e,n){var i=this.posFromDate(e||t.start_date),a=this.posFromDate(n||t.end_date);a=Math.max(i,a);var s=this.getTaskTop(t.id),r=this.config.task_height;return{left:i,top:s,
|
||||
height:r,width:Math.max(a-i,0)}},gantt._get_task_width=function(t){return Math.round(this._get_task_pos(t,!1).x-this._get_task_pos(t,!0).x)},gantt._is_readonly=function(t){return t&&t[this.config.editable_property]?!1:t&&t[this.config.readonly_property]||this.config.readonly},gantt._task_default_render=function(t){var e=this._get_task_pos(t),n=this.config,i=this._get_task_height(),a=Math.floor((this.config.row_height-i)/2);this._get_safe_type(t.type)==n.types.milestone&&n.link_line_width>1&&(a+=1);
|
||||
|
||||
var s=document.createElement("div"),r=gantt._get_task_width(t),o=this._get_safe_type(t.type);s.setAttribute(this.config.task_attribute,t.id),n.show_progress&&o!=this.config.types.milestone&&this._render_task_progress(t,s,r);var l=gantt._render_task_content(t,r);t.textColor&&(l.style.color=t.textColor),s.appendChild(l);var d=this._combine_item_class("gantt_task_line",this.templates.task_class(t.start_date,t.end_date,t),t.id);(t.color||t.progressColor||t.textColor)&&(d+=" gantt_task_inline_color"),
|
||||
s.className=d;var _=["left:"+e.x+"px","top:"+(a+e.y)+"px","height:"+i+"px","line-height:"+i+"px","width:"+r+"px"];t.color&&_.push("background-color:"+t.color),t.textColor&&_.push("color:"+t.textColor),s.style.cssText=_.join(";");var h=this._render_leftside_content(t);return h&&s.appendChild(h),h=this._render_rightside_content(t),h&&s.appendChild(h),this._is_readonly(t)||(n.drag_resize&&!this._is_flex_task(t)&&o!=this.config.types.milestone&&gantt._render_pair(s,"gantt_task_drag",t,function(t){var e=document.createElement("div");
|
||||
|
||||
return e.className=t,e}),n.drag_links&&this.config.show_links&&gantt._render_pair(s,"gantt_link_control",t,function(t){var e=document.createElement("div");e.className=t,e.style.cssText=["height:"+i+"px","line-height:"+i+"px"].join(";");var n=document.createElement("div");return n.className="gantt_link_point",e.appendChild(n),e})),s},gantt._render_task_element=function(t){var e=this.config.type_renderers,n=e[this._get_safe_type(t.type)],i=this._task_default_render;return n||(n=i),n.call(this,t,dhtmlx.bind(i,this));
|
||||
|
||||
},gantt._render_side_content=function(t,e,n){if(!e)return null;var i=e(t.start_date,t.end_date,t);if(!i)return null;var a=document.createElement("div");return a.className="gantt_side_content "+n,a.innerHTML=i,a},gantt._render_leftside_content=function(t){var e="gantt_left "+gantt._get_link_crossing_css(!0,t);return gantt._render_side_content(t,this.templates.leftside_text,e)},gantt._render_rightside_content=function(t){var e="gantt_right "+gantt._get_link_crossing_css(!1,t);return gantt._render_side_content(t,this.templates.rightside_text,e);
|
||||
|
||||
},gantt._get_conditions=function(t){return t?{$source:[gantt.config.links.start_to_start],$target:[gantt.config.links.start_to_start,gantt.config.links.finish_to_start]}:{$source:[gantt.config.links.finish_to_start,gantt.config.links.finish_to_finish],$target:[gantt.config.links.finish_to_finish]}},gantt._get_link_crossing_css=function(t,e){var n=gantt._get_conditions(t);for(var i in n)for(var a=e[i],s=0;s<a.length;s++)for(var r=gantt.getLink(a[s]),o=0;o<n[i].length;o++)if(r.type==n[i][o])return"gantt_link_crossing";
|
||||
|
||||
return""},gantt._render_task_content=function(t){var e=document.createElement("div");return this._get_safe_type(t.type)!=this.config.types.milestone&&(e.innerHTML=this.templates.task_text(t.start_date,t.end_date,t)),e.className="gantt_task_content",e},gantt._render_task_progress=function(t,e,n){var i=1*t.progress||0;n=Math.max(n-2,0);var a=document.createElement("div"),s=Math.round(n*i);if(s=Math.min(n,s),t.progressColor&&(a.style.backgroundColor=t.progressColor,a.style.opacity=1),a.style.width=s+"px",
|
||||
a.className="gantt_task_progress",a.innerHTML=this.templates.progress_text(t.start_date,t.end_date,t),e.appendChild(a),this.config.drag_progress&&!gantt._is_readonly(t)){var r=document.createElement("div");r.style.left=s+"px",r.className="gantt_task_progress_drag",a.appendChild(r),e.appendChild(r)}},gantt._get_line=function(t){var e={second:1,minute:60,hour:3600,day:86400,week:604800,month:2592e3,year:31536e3};return e[t]||0},gantt.dateFromPos=function(t){var e=this._tasks;if(0>t||t>e.full_width||!e.full_width)return null;
|
||||
|
||||
var n=this._findBinary(this._tasks.left,t),i=this._tasks.left[n],a=e.width[n]||e.col_width,s=0;a&&(s=(t-i)/a);var r=0;s&&(r=gantt._get_coll_duration(e,e.trace_x[n]));var o=new Date(e.trace_x[n].valueOf()+Math.round(s*r));return o},gantt.posFromDate=function(t){var e=gantt._day_index_by_date(t);dhtmlx.assert(e>=0,"Invalid day index");var n=Math.floor(e),i=e%1,a=gantt._tasks.left[Math.min(n,gantt._tasks.width.length-1)];return n==gantt._tasks.width.length&&(a+=gantt._tasks.width[gantt._tasks.width.length-1]),
|
||||
i&&(a+=n<gantt._tasks.width.length?gantt._tasks.width[n]*(i%1):1),a},gantt._day_index_by_date=function(t){var e=new Date(t).valueOf(),n=gantt._tasks.trace_x,i=gantt._tasks.ignore_x;if(e<=this._min_date)return 0;if(e>=this._max_date)return n.length;for(var a=gantt._findBinary(n,e),s=+gantt._tasks.trace_x[a];i[s];)s=gantt._tasks.trace_x[++a];return s?a+(t-n[a])/gantt._get_coll_duration(gantt._tasks,n[a]):0},gantt._findBinary=function(t,e){for(var n,i,a,s=0,r=t.length-1;r>=s;)if(n=Math.floor((s+r)/2),
|
||||
i=+t[n],a=+t[n-1],e>i)s=n+1;else{if(!(i>e))return n;if(!isNaN(a)&&e>a)return n-1;r=n-1}return t.length-1},gantt._get_coll_duration=function(t,e){return gantt.date.add(e,t.step,t.unit)-e},gantt._get_x_pos=function(t,e){e=e!==!1;gantt.posFromDate(e?t.start_date:t.end_date)},gantt.getTaskTop=function(t){return this._y_from_ind(this._get_visible_order(t))},gantt._get_task_coord=function(t,e,n){e=e!==!1,n=n||0;var i=this._get_safe_type(t.type)==this.config.types.milestone,a=null;a=e||i?t.start_date||this._default_task_date(t):t.end_date||this.calculateEndDate(this._default_task_date(t));
|
||||
|
||||
var s=this.posFromDate(a),r=this.getTaskTop(t.id);return i&&(e?s-=n:s+=n),{x:s,y:r}},gantt._get_task_pos=function(t,e){e=e!==!1;var n=gantt._get_milestone_width()/2;return this._get_task_coord(t,e,n)},gantt._get_task_visible_pos=function(t,e){e=e!==!1;var n=gantt._get_visible_milestone_width()/2;return this._get_task_coord(t,e,n)},gantt._correct_shift=function(t,e){return t-=6e4*(new Date(gantt._min_date).getTimezoneOffset()-new Date(t).getTimezoneOffset())*(e?-1:1)},gantt._get_mouse_pos=function(t){
|
||||
if(t.pageX||t.pageY)var e={x:t.pageX,y:t.pageY};var n=_isIE?document.documentElement:document.body,e={x:t.clientX+n.scrollLeft-n.clientLeft,y:t.clientY+n.scrollTop-n.clientTop},i=gantt._get_position(gantt.$task_data);return e.x=e.x-i.x+gantt.$task_data.scrollLeft,e.y=e.y-i.y+gantt.$task_data.scrollTop,e},gantt._is_layer=function(t){return t&&t.hasAttribute&&t.hasAttribute(this.config.layer_attribute)},gantt._task_renderer=function(t,e,n,i){return this._task_area_pulls||(this._task_area_pulls={}),
|
||||
this._task_area_renderers||(this._task_area_renderers={}),this._task_area_renderers[t]?this._task_area_renderers[t]:(e||dhtmlx.assert(!1,"Invalid renderer call"),n&&n.setAttribute(this.config.layer_attribute,!0),this._task_area_renderers[t]={render_item:function(a,s){var r=gantt._task_area_pulls[t];if(s=s||n,i&&!i(a))return void this.remove_item(a.id);var o=e.call(gantt,a);o&&(r[a.id]?this.replace_item(a.id,o):(r[a.id]=o,s.appendChild(o)))},clear:function(e){this.rendered=gantt._task_area_pulls[t]={},
|
||||
e=e||n,e&&(e.innerHTML="")},render_items:function(t,e){e=e||n,this.clear(e);for(var i=document.createDocumentFragment(),a=0,s=t.length;s>a;a++)this.render_item(t[a],i);e.appendChild(i)},replace_item:function(t,e){var n=this.rendered[t];n&&n.parentNode&&n.parentNode.replaceChild(e,n),this.rendered[t]=e},remove_item:function(t){var e=this.rendered[t];e&&e.parentNode&&e.parentNode.removeChild(e),delete this.rendered[t]},change_id:function(t,e){this.rendered[e]=this.rendered[t],delete this.rendered[t];
|
||||
|
||||
},rendered:this._task_area_pulls[t],node:n,unload:function(){this.clear(),delete gantt._task_area_renderers[t],delete gantt._task_area_pulls[t]}},this._task_area_renderers[t])},gantt._clear_renderers=function(){for(var t in this._task_area_renderers)this._task_renderer(t).unload()},gantt.attachEvent("onGanttReady",function(){gantt._task_layers.add(),gantt._link_layers.add()}),gantt._layers={prepareConfig:function(t){"function"==typeof t&&(t={renderer:t});t.id=dhtmlx.uid();return t.container||(t.container=document.createElement("div")),
|
||||
t},create:function(t,e){return{tempCollection:[],renderers:{},container:t,getRenderers:function(){var t=[];for(var e in this.renderers)t.push(this.renderers[e]);return t},getRenderer:function(t){return this.renderers[t]},add:function(t){if(t&&this.tempCollection.push(t),this.container())for(var n=this.container(),i=this.tempCollection,a=0;a<i.length;a++){var t=i[a],s=t.container,r=t.id,o=t.topmost;if(!s.parentNode)if(o)n.appendChild(s);else{var l=e?e():n.firstChild;l?n.insertBefore(s,l):n.appendChild(s);
|
||||
|
||||
}this.renderers[r]=gantt._task_renderer(r,t.renderer,s,t.filter),this.tempCollection.splice(a,1),a--}},remove:function(t){this.renderers[t].unload(),delete this.renderers[t]},clear:function(){for(var t in this.renderers)this.renderers[t].unload();this.renderers={}}}}},gantt._create_filter=function(t){return t instanceof Array||(t=Array.prototype.slice.call(arguments,0)),function(e){for(var n=!0,i=0,a=t.length;a>i;i++){var s=t[i];gantt[s]&&(n=n&&gantt[s].call(gantt,e.id,e)!==!1)}return n}},gantt._add_generic_layer=function(t,e){
|
||||
return function(n){return void 0===n.filter&&(n.filter=gantt._create_filter(e)),n=gantt._layers.prepareConfig(n),t.add(n),n.id}},gantt._task_layers=gantt._layers.create(function(){return gantt.$task_data},function(){return gantt.$task_links}),gantt._link_layers=gantt._layers.create(function(){return gantt.$task_data}),gantt.addTaskLayer=gantt._add_generic_layer(gantt._task_layers,["_filter_task","_is_chart_visible"]),gantt.removeTaskLayer=function(t){gantt._task_layers.remove(t)},gantt.addLinkLayer=gantt._add_generic_layer(gantt._link_layers,["_filter_link","_is_chart_visible"]),
|
||||
gantt.removeLinkLayer=function(t){gantt._link_layers.remove(t)},gantt._get_task_renderers=function(){return this._task_layers.getRenderers()},gantt._get_link_renderers=function(){return this._link_layers.getRenderers()},gantt._pull={},gantt._branches={},gantt._order=[],gantt._lpull={},gantt.load=function(t,e,n){this._load_url=t,dhtmlx.assert(arguments.length,"Invalid load arguments"),this.callEvent("onLoadStart",[]);var i="json",a=null;arguments.length>=3?(i=e,a=n):"string"==typeof arguments[1]?i=arguments[1]:"function"==typeof arguments[1]&&(a=arguments[1]),
|
||||
this._load_type=i,dhx4.ajax.get(t,dhtmlx.bind(function(t){this.on_load(t,i),this.callEvent("onLoadEnd",[]),"function"==typeof a&&a.call(this)},this))},gantt.parse=function(t,e){this.on_load({xmlDoc:{responseText:t}},e)},gantt.serialize=function(t){return t=t||"json",this[t].serialize()},gantt.on_load=function(t,e){this.callEvent("onBeforeParse",[]),e||(e="json"),dhtmlx.assert(this[e],"Invalid data type:'"+e+"'");var n=t.xmlDoc.responseText,i=this[e].parse(n,t);this._process_loading(i)},gantt._process_loading=function(t){
|
||||
t.collections&&this._load_collections(t.collections);for(var e,n=t.data,i=0;i<n.length;i++)e=n[i],this._init_task(e),this.callEvent("onTaskLoading",[e])&&(this._pull[e.id]=e);for(var i in this._pull)e=this._pull[i],this.setParent(e,this.getParent(e)||this.config.root_id);for(var i in this._pull)e=this._pull[i],this._add_branch(e,!0),e.$level=this.calculateTaskLevel(e);if(this._sync_order(),this._init_links(t.links||(t.collections?t.collections.links:[])),this.callEvent("onParse",[]),this.render(),
|
||||
this.config.initial_scroll){var a=this._order[0]||this.config.root_id;a&&this.showTask(a)}},gantt._init_links=function(t){if(t)for(var e=0;e<t.length;e++)if(t[e]){var n=this._init_link(t[e]);this._lpull[n.id]=n}this._sync_links()},gantt._load_collections=function(t){var e=!1;for(var n in t)if(t.hasOwnProperty(n)){e=!0;var i=t[n],a=this.serverList[n];if(!a)continue;a.splice(0,a.length);for(var s=0;s<i.length;s++){var r=i[s],o=dhtmlx.copy(r);o.key=o.value;for(var l in r)if(r.hasOwnProperty(l)){if("value"==l||"label"==l)continue;
|
||||
|
||||
o[l]=r[l]}a.push(o)}}e&&this.callEvent("onOptionsLoad",[])},gantt._sync_order=function(t){this._order=[],this._sync_order_item({parent:this.config.root_id,$open:!0,$ignore:!0,id:this.config.root_id}),t||(this._scroll_resize(),this._set_sizes())},gantt.attachEvent("onBeforeTaskDisplay",function(t,e){return!e.$ignore}),gantt._sync_order_item=function(t){if(t.id&&this._filter_task(t.id,t)&&this.callEvent("onBeforeTaskDisplay",[t.id,t])&&this._order.push(t.id),t.$open){var e=this.getChildren(t.id);if(e)for(var n=0;n<e.length;n++)this._sync_order_item(this._pull[e[n]]);
|
||||
|
||||
}},gantt._get_visible_order=function(t){dhtmlx.assert(t,"Invalid argument");for(var e=this._order,n=0,i=e.length;i>n;n++)if(e[n]==t)return n;return-1},gantt.eachTask=function(t,e,n){e=e||this.config.root_id,n=n||this;var i=this.getChildren(e);if(i)for(var a=0;a<i.length;a++){var s=this._pull[i[a]];t.call(n,s),this.hasChild(s.id)&&this.eachTask(t,s.id,n)}},gantt.json={parse:function(data){return dhtmlx.assert(data,"Invalid data"),"string"==typeof data&&(window.JSON?data=JSON.parse(data):(gantt._temp=eval("("+data+")"),
|
||||
data=gantt._temp||{},gantt._temp=null)),data.dhx_security&&(dhtmlx.security_key=data.dhx_security),data},_copyLink:function(t){var e={};for(var n in t)e[n]=t[n];return e},_copyObject:function(t){var e={};for(var n in t)"$"!=n.charAt(0)&&(e[n]=t[n],e[n]instanceof Date&&(e[n]=gantt.templates.xml_format(e[n])));return e},serialize:function(){var t=[],e=[];gantt.eachTask(function(e){gantt.resetProjectDates(e),t.push(this._copyObject(e))},gantt.config.root_id,this);for(var n in gantt._lpull)e.push(this._copyLink(gantt._lpull[n]));
|
||||
|
||||
return{data:t,links:e}}},gantt.xml={_xmlNodeToJSON:function(t,e){for(var n={},i=0;i<t.attributes.length;i++)n[t.attributes[i].name]=t.attributes[i].value;if(!e){for(var i=0;i<t.childNodes.length;i++){var a=t.childNodes[i];1==a.nodeType&&(n[a.tagName]=a.firstChild?a.firstChild.nodeValue:"")}n.text||(n.text=t.firstChild?t.firstChild.nodeValue:"")}return n},_getCollections:function(t){for(var e={},n=dhx4.ajax.xpath("//coll_options",t),i=0;i<n.length;i++)for(var a=n[i].getAttribute("for"),s=e[a]=[],r=dhx4.ajax.xpath(".//item",n[i]),o=0;o<r.length;o++){
|
||||
for(var l=r[o],d=l.attributes,_={key:r[o].getAttribute("value"),label:r[o].getAttribute("label")},h=0;h<d.length;h++){var c=d[h];"value"!=c.nodeName&&"label"!=c.nodeName&&(_[c.nodeName]=c.nodeValue)}s.push(_)}return e},_getXML:function(t,e,n){n=n||"data",e.getXMLTopNode||(e=dhx4.ajax.parse(e));var i=dhx4.ajax.xmltop(n,e.xmlDoc);if(i.tagName!=n)throw"Invalid XML data";var a=i.getAttribute("dhx_security");return a&&(dhtmlx.security_key=a),i},parse:function(t,e){e=this._getXML(t,e);for(var n={},i=n.data=[],a=dhx4.ajax.xpath("//task",e),s=0;s<a.length;s++)i[s]=this._xmlNodeToJSON(a[s]);
|
||||
|
||||
return n.collections=this._getCollections(e),n},_copyLink:function(t){return"<item id='"+t.id+"' source='"+t.source+"' target='"+t.target+"' type='"+t.type+"' />"},_copyObject:function(t){return"<task id='"+t.id+"' parent='"+(t.parent||"")+"' start_date='"+t.start_date+"' duration='"+t.duration+"' open='"+!!t.open+"' progress='"+t.progress+"' end_date='"+t.end_date+"'><![CDATA["+t.text+"]]></task>"},serialize:function(){for(var t=[],e=[],n=gantt.json.serialize(),i=0,a=n.data.length;a>i;i++)t.push(this._copyObject(n.data[i]));
|
||||
|
||||
for(var i=0,a=n.links.length;a>i;i++)e.push(this._copyLink(n.links[i]));return"<data>"+t.join("")+"<coll_options for='links'>"+e.join("")+"</coll_options></data>"}},gantt.oldxml={parse:function(t,e){e=gantt.xml._getXML(t,e,"projects");for(var n={collections:{links:[]}},i=n.data=[],a=dhx4.ajax.xpath("//task",e),s=0;s<a.length;s++){i[s]=gantt.xml._xmlNodeToJSON(a[s]);var r=a[s].parentNode;i[s].parent="project"==r.tagName?"project-"+r.getAttribute("id"):r.parentNode.getAttribute("id")}a=dhx4.ajax.xpath("//project",e);
|
||||
|
||||
for(var s=0;s<a.length;s++){var o=gantt.xml._xmlNodeToJSON(a[s],!0);o.id="project-"+o.id,i.push(o)}for(var s=0;s<i.length;s++){var o=i[s];o.start_date=o.startdate||o.est,o.end_date=o.enddate,o.text=o.name,o.duration=o.duration/8,o.open=1,o.duration||o.end_date||(o.duration=1),o.predecessortasks&&n.collections.links.push({target:o.id,source:o.predecessortasks,type:gantt.config.links.finish_to_start})}return n},serialize:function(){dhtmlx.message("Serialization to 'old XML' is not implemented")}},gantt.serverList=function(t,e){
|
||||
return e?this.serverList[t]=e.slice(0):this.serverList[t]||(this.serverList[t]=[]),this.serverList[t]},gantt._working_time_helper={units:["year","month","week","day","hour","minute"],hours:[8,17],dates:{0:!1,6:!1},_working_units_cache:{_cache:{},get:function(t,e){if(!t||!e)return-1;var n=this._cache,i=e.getTime(),a=-1;return n&&n[t]&&void 0!==n[t][i]&&(a=n[t][i]),a},put:function(t,e,n){if(!t||!e)return!1;var i=this._cache,a=e.getTime();return n=!!n,i?(i[t]||(i[t]={}),i[t][a]=n,!0):!1},clear:function(){
|
||||
this._cache={}}},_get_unit_order:function(t){for(var e=0,n=this.units.length;n>e;e++)if(this.units[e]==t)return e;dhtmlx.assert(!1,"Incorrect duration unit")},_timestamp:function(t){var e=null;return t.day||0===t.day?e=t.day:t.date&&(e=gantt.date.date_part(new Date(t.date)).valueOf()),e},set_time:function(t){var e=void 0!==t.hours?t.hours:!0,n=this._timestamp(t);null!==n?this.dates[n]=e:this.hours=e,this._working_units_cache.clear()},unset_time:function(t){if(t){var e=this._timestamp(t);null!==e&&delete this.dates[e];
|
||||
|
||||
}else this.hours=[];this._working_units_cache.clear()},is_working_unit:function(t,e,n){if(!gantt.config.work_time)return!0;var i=this._working_units_cache.get(e,t);return-1==i&&(i=this._check_is_working_unit(t,e,n),this._working_units_cache.put(e,t,i)),i},_check_is_working_unit:function(t,e,n){return void 0===n&&(n=this._get_unit_order(e)),void 0===n?!1:n&&!this.is_working_unit(t,this.units[n-1],n-1)?!1:this["is_work_"+e]?this["is_work_"+e](t):!0},is_work_day:function(t){var e=this.get_working_hours(t);
|
||||
|
||||
return e instanceof Array?e.length>0:!1},is_work_hour:function(t){for(var e=this.get_working_hours(t),n=t.getHours(),i=0;i<e.length;i+=2){if(void 0===e[i+1])return e[i]==n;if(n>=e[i]&&n<e[i+1])return!0}return!1},get_working_hours:function(t){var e=this._timestamp({date:t}),n=!0;return void 0!==this.dates[e]?n=this.dates[e]:void 0!==this.dates[t.getDay()]&&(n=this.dates[t.getDay()]),n===!0?this.hours:n?n:[]},get_work_units_between:function(t,e,n,i){if(!n)return!1;for(var a=new Date(t),s=new Date(e),i=i||1,r=0;a.valueOf()<s.valueOf();)this.is_working_unit(a,n)&&r++,
|
||||
a=gantt.date.add(a,i,n);return r},is_work_units_between:function(t,e,n,i){if(!n)return!1;for(var a=new Date(t),s=new Date(e),i=i||1;a.valueOf()<s.valueOf();){if(this.is_working_unit(a,n))return!0;a=gantt.date.add(a,i,n)}return!1},add_worktime:function(t,e,n,i){if(!n)return!1;var a=new Date(t),s=0,i=i||1,e=1*e;if(gantt.config.work_time){for(;e>s;){var r=gantt.date.add(a,i,n);this.is_working_unit(i>0?a:r,n)&&s++,a=r}return a}return gantt.date.add(a,i*e,n)},get_closest_worktime:function(t){if(this.is_working_unit(t.date,t.unit))return t.date;
|
||||
|
||||
var e=t.unit,n=gantt.date[e+"_start"](t.date),i=new Date(n),a=new Date(n),s=!0,r=3e3,o=0,l="any"==t.dir||!t.dir,d=1;for("past"==t.dir&&(d=-1);!this.is_working_unit(n,e);)if(l&&(n=s?i:a,d=-1*d),n=gantt.date.add(n,d,e),n=gantt.date[e+"_start"](n),l&&(s?i=n:a=n),s=!s,o++,o>r)return dhtmlx.assert(!1,"Invalid working time check"),!1;return(n==a||"past"==t.dir)&&(n=gantt.date.add(n,1,e)),n}},gantt.getTask=function(t){return dhtmlx.assert(t,"Invalid argument for gantt.getTask"),dhtmlx.assert(this._pull[t],"Task not found id="+t),
|
||||
this._pull[t]},gantt.getTaskByTime=function(t,e){var n=this._pull,i=[];if(t||e){t=+t||-(1/0),e=+e||1/0;for(var a in n){var s=n[a];+s.start_date<e&&+s.end_date>t&&i.push(s)}}else for(var a in n)i.push(n[a]);return i},gantt.isTaskExists=function(t){return dhtmlx.defined(this._pull[t])},gantt.isTaskVisible=function(t){if(!this._pull[t])return!1;if(!(+this._pull[t].start_date<+this._max_date&&+this._pull[t].end_date>+this._min_date))return!1;for(var e=0,n=this._order.length;n>e;e++)if(this._order[e]==t)return!0;
|
||||
|
||||
return!1},gantt.updateTask=function(t,e){return dhtmlx.defined(e)||(e=this.getTask(t)),this.callEvent("onBeforeTaskUpdate",[t,e])===!1?!1:(this._pull[e.id]=e,this._is_parent_sync(e)||this._resync_parent(e),this._update_parents(e.id),this.refreshTask(e.id),this.callEvent("onAfterTaskUpdate",[t,e]),this._sync_order(),void this._adjust_scales())},gantt._add_branch=function(t,e){var n=this.getParent(t);this.hasChild(n)||(this._branches[n]=[]);for(var i=this.getChildren(n),a=!1,s=0,r=i.length;r>s;s++)if(i[s]==t.id){
|
||||
a=!0;break}a||i.push(t.id),this._sync_parent(t),this._sync_order(e)},gantt._move_branch=function(t,e,n){this.setParent(t,n),this._sync_parent(t),this._replace_branch_child(e,t.id),this.isTaskExists(n)||n==this.config.root_id?this._add_branch(t):delete this._branches[t.id],t.$level=this.calculateTaskLevel(t),this._sync_order()},gantt._resync_parent=function(t){this._move_branch(t,t.$rendered_parent,this.getParent(t))},gantt._sync_parent=function(t){t.$rendered_parent=this.getParent(t)},gantt._is_parent_sync=function(t){
|
||||
return t.$rendered_parent==this.getParent(t)},gantt._replace_branch_child=function(t,e,n){var i=this.getChildren(t);if(i){for(var a=[],s=0;s<i.length;s++)i[s]!=e?a.push(i[s]):n&&a.push(n);this._branches[t]=a}this._sync_order()},gantt.addTask=function(t,e){return dhtmlx.defined(e)||(e=this.getParent(t)||0),this.isTaskExists(e)||(e=0),this.setParent(t,e),t=this._init_task(t),this.callEvent("onBeforeTaskAdd",[t.id,t])===!1?!1:(this._pull[t.id]=t,this._add_branch(t),this.refreshData(),this._adjust_scales(),
|
||||
this.callEvent("onAfterTaskAdd",[t.id,t]),t.id)},gantt._default_task_date=function(t,e){var n=e&&e!=this.config.root_id?this.getTask(e):!1,i="";if(n)i=n.start_date;else{var a=this._order[0];i=a?this.getTask(a).start_date:this.getState().min_date}return new Date(i)},gantt._set_default_task_timing=function(t){t.start_date=t.start_date||gantt._default_task_date(t,this.getParent(t)),t.duration=t.duration||this.config.duration_step,t.end_date=t.end_date||this.calculateEndDate(t.start_date,t.duration)},
|
||||
gantt.createTask=function(t,e){return t=t||{},t.id=dhtmlx.uid(),t.start_date||(t.start_date=gantt._default_task_date(t,e)),void 0===t.text&&(t.text=gantt.locale.labels.new_task),void 0===t.duration&&(t.duration=1),e&&(this.setParent(t,e),e=this.getTask(e),e.$open=!0),this.callEvent("onTaskCreated",[t])?(this.config.details_on_create?(t.$new=!0,this._pull[t.id]=this._init_task(t),this._add_branch(t),t.$level=this.calculateTaskLevel(t),this.selectTask(t.id),this.refreshData(),this.showLightbox(t.id)):this.addTask(t)&&(this.showTask(t.id),
|
||||
this.selectTask(t.id)),t.id):null},gantt.deleteTask=function(t){return this._deleteTask(t)},gantt._getChildLinks=function(t){var e=this.getTask(t);if(!e)return[];for(var n=e.$source.concat(e.$target),i=this.getChildren(e.id),a=0;a<i.length;a++)n=n.concat(this._getChildLinks(i[a]));for(var s={},a=0;a<n.length;a++)s[n[a]]=!0;n=[];for(var a in s)n.push(a);return n},gantt._getTaskTree=function(t){var e=this.getTask(t);if(!e)return[];for(var n=[],i=this.getChildren(e.id),a=0;a<i.length;a++)n.push(i[a]),
|
||||
n=n.concat(this._getTaskTree(i[a]));return n},gantt._deleteRelatedLinks=function(t,e){var n=this._dp&&!e,i="",a=n?"off"!=this._dp.updateMode:!1;n&&(i=this._dp.updateMode,this._dp.setUpdateMode("off"));for(var s=0;s<t.length;s++)n&&(this._dp.setGanttMode("links"),this._dp.setUpdated(t[s],!0,"deleted")),this._deleteLink(t[s],!0);n&&(this._dp.setUpdateMode(i),a&&this._dp.sendAllData())},gantt._deleteRelatedTasks=function(t,e){var n=this._dp&&!e,i="";n&&(i=this._dp.updateMode,this._dp.setGanttMode("tasks"),
|
||||
this._dp.setUpdateMode("off"));for(var a=this._getTaskTree(t),s=0;s<a.length;s++){var r=a[s];this._unset_task(r),n&&this._dp.setUpdated(r,!0,"deleted")}n&&this._dp.setUpdateMode(i)},gantt._unset_task=function(t){var e=this.getTask(t);this._update_flags(t,null),delete this._pull[t],this._move_branch(e,this.getParent(e),null)},gantt._deleteTask=function(t,e){var n=this.getTask(t);if(!e&&this.callEvent("onBeforeTaskDelete",[t,n])===!1)return!1;var i=gantt._getChildLinks(t);return this._deleteRelatedTasks(t,e),
|
||||
this._deleteRelatedLinks(i,e),this._unset_task(t),e||(this.callEvent("onAfterTaskDelete",[t,n]),this.refreshData()),!0},gantt.clearAll=function(){this._clear_data(),this.callEvent("onClear",[]),this.refreshData()},gantt._clear_data=function(){this._pull={},this._branches={},this._order=[],this._order_full=[],this._lpull={},this._update_flags(),this.userdata={}},gantt._update_flags=function(t,e){void 0===t?(this._lightbox_id=this._selected_task=null,this._tasks_dnd.drag&&(this._tasks_dnd.drag.id=null)):(this._lightbox_id==t&&(this._lightbox_id=e),
|
||||
this._selected_task==t&&(this._selected_task=e),this._tasks_dnd.drag&&this._tasks_dnd.drag.id==t&&(this._tasks_dnd.drag.id=e))},gantt.changeTaskId=function(t,e){var n=this._pull[e]=this._pull[t];this._pull[e].id=e,delete this._pull[t];for(var i in this._pull){var a=this._pull[i];this.getParent(a)==t&&this.setParent(a,e)}this._update_flags(t,e),this._replace_branch_child(this.getParent(n),t,e),this.callEvent("onTaskIdChange",[t,e])},gantt._get_duration_unit=function(){return 1e3*gantt._get_line(this.config.duration_unit)||this.config.duration_unit;
|
||||
|
||||
},gantt._get_safe_type=function(){return"task"},gantt._get_type_name=function(t){for(var e in this.config.types)if(this.config.types[e]==t)return e;return"task"},gantt.getWorkHours=function(t){return this._working_time_helper.get_working_hours(t)},gantt.setWorkTime=function(t){this._working_time_helper.set_time(t)},gantt.isWorkTime=function(t,e){var n=this._working_time_helper;return n.is_working_unit(t,e||this.config.duration_unit)},gantt.correctTaskWorkTime=function(t){gantt.config.work_time&&gantt.config.correct_work_time&&(gantt.isWorkTime(t.start_date)?gantt.isWorkTime(new Date(+t.end_date-1))||(t.end_date=gantt.calculateEndDate(t.start_date,t.duration)):(t.start_date=gantt.getClosestWorkTime({
|
||||
date:t.start_date,dir:"future"}),t.end_date=gantt.calculateEndDate(t.start_date,t.duration)))},gantt.getClosestWorkTime=function(t){var e=this._working_time_helper;return t instanceof Date&&(t={date:t}),t.dir=t.dir||"any",t.unit=t.unit||this.config.duration_unit,e.get_closest_worktime(t)},gantt.calculateDuration=function(t,e){var n=this._working_time_helper;return n.get_work_units_between(t,e,this.config.duration_unit,this.config.duration_step)},gantt._hasDuration=function(t,e){var n=this._working_time_helper;
|
||||
|
||||
return n.is_work_units_between(t,e,this.config.duration_unit,this.config.duration_step)},gantt.calculateEndDate=function(t,e,n){var i=this._working_time_helper,a=e>=0?1:-1;return i.add_worktime(t,Math.abs(e),n||this.config.duration_unit,a*this.config.duration_step)},gantt._init_task=function(t){return dhtmlx.defined(t.id)||(t.id=dhtmlx.uid()),t.start_date&&(t.start_date=gantt.date.parseDate(t.start_date,"xml_date")),t.end_date&&(t.end_date=gantt.date.parseDate(t.end_date,"xml_date")),t.start_date&&!t.end_date&&t.duration&&(t.end_date=this.calculateEndDate(t.start_date,t.duration)),
|
||||
gantt._init_task_timing(t),t.start_date&&t.end_date&&gantt.correctTaskWorkTime(t),t.$source=[],t.$target=[],void 0===t.parent&&this.setParent(t,this.config.root_id),t.$open=dhtmlx.defined(t.open)?t.open:this.config.open_tree_initially,t.$level=this.calculateTaskLevel(t),t},gantt._init_task_timing=function(t){var e=this._get_safe_type(t.type);void 0===t.$rendered_type?t.$rendered_type=e:t.$rendered_type!=e&&(delete t.$no_end,delete t.$no_start,t.$rendered_type=e),void 0!==t.$no_end&&void 0!==t.$no_start||e==this.config.types.milestone||(e==this.config.types.project?(t.$no_end=t.$no_start=!0,
|
||||
this._set_default_task_timing(t)):(t.$no_end=!(t.end_date||t.duration),t.$no_start=!t.start_date)),e==this.config.types.milestone&&(t.end_date=t.start_date),t.start_date&&t.end_date&&(t.duration=this.calculateDuration(t.start_date,t.end_date)),t.duration=t.duration||0},gantt._is_flex_task=function(t){return!(!t.$no_end&&!t.$no_start)},gantt.resetProjectDates=function(t){if(t.$no_end||t.$no_start){var e=this.getSubtaskDates(t.id);this._assign_project_dates(t,e.start_date,e.end_date)}},gantt.getSubtaskDates=function(t){
|
||||
var e=null,n=null,i=void 0!==t?t:gantt.config.root_id;return this.eachTask(function(t){this._get_safe_type(t.type)!=gantt.config.types.project&&(t.start_date&&!t.$no_start&&(!e||e>t.start_date.valueOf())&&(e=t.start_date.valueOf()),t.end_date&&!t.$no_end&&(!n||n<t.end_date.valueOf())&&(n=t.end_date.valueOf()))},i),{start_date:e?new Date(e):null,end_date:n?new Date(n):null}},gantt._assign_project_dates=function(t,e,n){t.$no_start&&(t.start_date=e&&e!=1/0?new Date(e):this._default_task_date(t,this.getParent(t))),
|
||||
t.$no_end&&(t.end_date=n&&n!=-(1/0)?new Date(n):this.calculateEndDate(t.start_date,this.config.duration_step)),(t.$no_start||t.$no_end)&&this._init_task_timing(t)},gantt._update_parents=function(t,e){if(t){for(var n=this.getTask(t),i=this.getParent(n);!n.$no_end&&!n.$no_start&&i&&this.isTaskExists(i);)n=this.getTask(i),i=this.getParent(n);(n.$no_start||n.$no_end)&&(gantt.resetProjectDates(n),e||this.refreshTask(n.id,!0)),i&&this.isTaskExists(i)&&this._update_parents(i,e)}},gantt.isChildOf=function(t,e){
|
||||
if(!this.isTaskExists(t))return!1;if(e===this.config.root_id)return this.isTaskExists(t);for(var n=this.getTask(t),i=this.getParent(t);n&&this.isTaskExists(i);){if(n=this.getTask(i),n&&n.id==e)return!0;i=this.getParent(n)}return!1},gantt.roundDate=function(t){t instanceof Date&&(t={date:t,unit:gantt._tasks.unit,step:gantt._tasks.step});for(var e=t.date,n=t.step,i=t.unit,a=gantt.date[i+"_start"](new Date(this._min_date));+e>+a;)a=gantt.date[i+"_start"](gantt.date.add(a,n,i));var s=gantt.date.add(a,-1*n,i);
|
||||
|
||||
return t.dir&&"future"==t.dir?a:t.dir&&"past"==t.dir?s:Math.abs(e-s)<Math.abs(a-e)?s:a},gantt.attachEvent("onBeforeTaskUpdate",function(t,e){return gantt._init_task_timing(e),!0}),gantt.attachEvent("onBeforeTaskAdd",function(t,e){return gantt._init_task_timing(e),!0}),gantt.calculateTaskLevel=function(t){for(var e=0;this.getParent(t)&&this.isTaskExists(this.getParent(t));)t=this.getTask(this.getParent(t)),e++;return e},gantt.sort=function(t,e,n,i){var a=!i;this.isTaskExists(n)||(n=this.config.root_id),
|
||||
t||(t="order");var s="string"==typeof t?function(n,i){if(n[t]==i[t])return 0;var a=n[t]>i[t];return e&&(a=!a),a?1:-1}:t,r=this.getChildren(n);if(r){for(var o=[],l=r.length-1;l>=0;l--)o[l]=this._pull[r[l]];o.sort(s);for(var l=0;l<o.length;l++)r[l]=o[l].id,this.sort(t,e,r[l],!0)}a&&this.render()},gantt.getNext=function(t){for(var e=0;e<this._order.length-1;e++)if(this._order[e]==t)return this._order[e+1];return null},gantt.getPrev=function(t){for(var e=1;e<this._order.length;e++)if(this._order[e]==t)return this._order[e-1];
|
||||
|
||||
return null},gantt._get_parent_id=function(t){var e=this.config.root_id;return t&&(e=t.parent),e},gantt.getParent=function(t){var e=null;return t.id?e=t:this.isTaskExists(t)&&(e=gantt.getTask(t)),this._get_parent_id(e)},gantt.setParent=function(t,e){t.parent=e},gantt.getSiblings=function(t){if(!this.isTaskExists(t))return[];var e=this.getParent(t);return this.getChildren(e)},gantt.getNextSibling=function(t){for(var e=this.getSiblings(t),n=0,i=e.length;i>n;n++)if(e[n]==t)return e[n+1]||null;return null;
|
||||
|
||||
},gantt.getPrevSibling=function(t){for(var e=this.getSiblings(t),n=0,i=e.length;i>n;n++)if(e[n]==t)return e[n-1]||null;return null},gantt._dp_init=function(t){t.setTransactionMode("POST",!0),t.serverProcessor+=(-1!=t.serverProcessor.indexOf("?")?"&":"?")+"editing=true",t._serverProcessor=t.serverProcessor,t.styles={updated:"gantt_updated",inserted:"gantt_inserted",deleted:"gantt_deleted",invalid:"gantt_invalid",error:"gantt_error",clear:""},t._methods=["_row_style","setCellTextStyle","_change_id","_delete_task"],
|
||||
t.setGanttMode=function(e){var n=t.modes||{};t._ganttMode&&(n[t._ganttMode]={_in_progress:t._in_progress,_invalid:t._invalid,updatedRows:t.updatedRows});var i=n[e];i||(i=n[e]={_in_progress:{},_invalid:{},updatedRows:[]}),t._in_progress=i._in_progress,t._invalid=i._invalid,t.updatedRows=i.updatedRows,t.modes=n,t._ganttMode=e},this._sendTaskOrder=function(e,n){n.$drop_target&&(t.setGanttMode("tasks"),this.getTask(e).target=n.$drop_target,t.setUpdated(e,!0,"order"),delete this.getTask(e).$drop_target);
|
||||
|
||||
},this.attachEvent("onAfterTaskAdd",function(e){t.setGanttMode("tasks"),t.setUpdated(e,!0,"inserted")}),this.attachEvent("onAfterTaskUpdate",function(e,n){t.setGanttMode("tasks"),t.setUpdated(e,!0),gantt._sendTaskOrder(e,n)}),this.attachEvent("onAfterTaskDelete",function(e){t.setGanttMode("tasks"),t.setUpdated(e,!0,"deleted"),"off"==t.updateMode||t._tSend||t.sendAllData()}),this.attachEvent("onAfterLinkUpdate",function(e){t.setGanttMode("links"),t.setUpdated(e,!0)}),this.attachEvent("onAfterLinkAdd",function(e){
|
||||
t.setGanttMode("links"),t.setUpdated(e,!0,"inserted")}),this.attachEvent("onAfterLinkDelete",function(e){t.setGanttMode("links"),t.setUpdated(e,!0,"deleted")}),this.attachEvent("onRowDragEnd",function(t){gantt._sendTaskOrder(t,gantt.getTask(t))}),t.attachEvent("onBeforeDataSending",function(){if("REST"==this._tMode){var t=this._ganttMode.substr(0,this._ganttMode.length-1);this.serverProcessor=this._serverProcessor+("/"==this._serverProcessor.slice(-1)?"":"/")+t}else this.serverProcessor=this._serverProcessor+window.dhtmlx.url(this._serverProcessor)+"gantt_mode="+this._ganttMode;
|
||||
|
||||
return!0});var e=t.afterUpdate;t.afterUpdate=function(){var n;n=3==arguments.length?arguments[1]:arguments[4];var i=t._ganttMode,a=n.filePath||(n.xmlDoc?n.xmlDoc.responseURL:"");i="REST"!=this._tMode?-1!=a.indexOf("gantt_mode=links")?"links":"tasks":a.indexOf("/link")>a.indexOf("/task")?"links":"tasks",t.setGanttMode(i);var s=e.apply(t,arguments);return t.setGanttMode(i),s},t._getRowData=dhtmlx.bind(function(e){var n;n="tasks"==t._ganttMode?this.isTaskExists(e)?this.getTask(e):{id:e}:this.isLinkExists(e)?this.getLink(e):{
|
||||
id:e},n=dhtmlx.copy(n);var i={};for(var a in n)if("$"!=a.substr(0,1)){var s=n[a];i[a]=s instanceof Date?this.templates.xml_format(s):null===s?"":s}return n.$no_start&&(n.start_date="",n.duration=""),n.$no_end&&(n.end_date="",n.duration=""),i[t.action_param]=this.getUserData(e,t.action_param),i},this),this._change_id=dhtmlx.bind(function(e,n){"tasks"!=t._ganttMode?this.changeLinkId(e,n):this.changeTaskId(e,n)},this),this._row_style=function(e,n){if("tasks"==t._ganttMode){var i=gantt.getTaskRowNode(e);
|
||||
|
||||
if(i)if(n)i.className+=" "+n;else{var a=/ (gantt_updated|gantt_inserted|gantt_deleted|gantt_invalid|gantt_error)/g;i.className=i.className.replace(a,"")}}},this._delete_task=function(){},this._dp=t},gantt.getUserData=function(t,e){return this.userdata||(this.userdata={}),this.userdata[t]&&this.userdata[t][e]?this.userdata[t][e]:""},gantt.setUserData=function(t,e,n){this.userdata||(this.userdata={}),this.userdata[t]||(this.userdata[t]={}),this.userdata[t][e]=n},gantt._init_link=function(t){return dhtmlx.defined(t.id)||(t.id=dhtmlx.uid()),
|
||||
t},gantt._sync_links=function(){for(var t in this._pull)this._pull[t].$source=[],this._pull[t].$target=[];for(var t in this._lpull){var e=this._lpull[t];this._pull[e.source]&&this._pull[e.source].$source.push(t),this._pull[e.target]&&this._pull[e.target].$target.push(t)}},gantt.getLink=function(t){return dhtmlx.assert(this._lpull[t],"Link doesn't exist"),this._lpull[t]},gantt.getLinks=function(){var t=[];for(var e in gantt._lpull)t.push(gantt._lpull[e]);return t},gantt.isLinkExists=function(t){return dhtmlx.defined(this._lpull[t]);
|
||||
|
||||
},gantt.addLink=function(t){return t=this._init_link(t),this.callEvent("onBeforeLinkAdd",[t.id,t])===!1?!1:(this._lpull[t.id]=t,this._sync_links(),this._render_link(t.id),this.callEvent("onAfterLinkAdd",[t.id,t]),t.id)},gantt.updateLink=function(t,e){return dhtmlx.defined(e)||(e=this.getLink(t)),this.callEvent("onBeforeLinkUpdate",[t,e])===!1?!1:(this._lpull[t]=e,this._sync_links(),this._render_link(t),this.callEvent("onAfterLinkUpdate",[t,e]),!0)},gantt.deleteLink=function(t){return this._deleteLink(t);
|
||||
|
||||
},gantt._deleteLink=function(t,e){var n=this.getLink(t);return e||this.callEvent("onBeforeLinkDelete",[t,n])!==!1?(delete this._lpull[t],this._sync_links(),this.refreshLink(t),e||this.callEvent("onAfterLinkDelete",[t,n]),!0):!1},gantt.changeLinkId=function(t,e){this._lpull[e]=this._lpull[t],this._lpull[e].id=e,delete this._lpull[t],this._sync_links(),this.callEvent("onLinkIdChange",[t,e])},gantt.getChildren=function(t){return dhtmlx.defined(this._branches[t])?this._branches[t]:[]},gantt.hasChild=function(t){
|
||||
return dhtmlx.defined(this._branches[t])&&this._branches[t].length},gantt.refreshData=function(){this._render_data()},gantt._configure=function(t,e,n){for(var i in e)("undefined"==typeof t[i]||n)&&(t[i]=e[i])},gantt._init_skin=function(){gantt._get_skin(!1),gantt._init_skin=function(){}},gantt._get_skin=function(t){if(!gantt.skin||t)for(var e=document.getElementsByTagName("link"),n=0;n<e.length;n++){var i=e[n].href.match("dhtmlxgantt_([a-z]+).css");if(i){gantt.skin=i[1];break}}gantt.skin||(gantt.skin="terrace");
|
||||
|
||||
var a=gantt.skins[gantt.skin];this._configure(gantt.config,a.config,t);var s=gantt.getGridColumns();s[1]&&"undefined"==typeof s[1].width&&(s[1].width=a._second_column_width),s[2]&&"undefined"==typeof s[2].width&&(s[2].width=a._third_column_width),a._lightbox_template&&(gantt._lightbox_template=a._lightbox_template),gantt.resetLightbox()},gantt.resetSkin=function(){this.skin="",this._get_skin(!0)},gantt.skins={},gantt._lightbox_methods={},gantt._lightbox_template="<div class='gantt_cal_ltitle'><span class='gantt_mark'> </span><span class='gantt_time'></span><span class='gantt_title'></span></div><div class='gantt_cal_larea'></div>",
|
||||
gantt.showLightbox=function(t){if(t&&!gantt._is_readonly(this.getTask(t))&&this.callEvent("onBeforeLightbox",[t])){var e=this.getTask(t),n=this.getLightbox(this._get_safe_type(e.type));this._center_lightbox(n),this.showCover(),this._fill_lightbox(t,n),this.callEvent("onLightbox",[t])}},gantt._get_timepicker_step=function(){if(this.config.round_dnd_dates){var t=gantt._tasks,e=this._get_line(t.unit)*t.step/60;return(e>=1440||!this._is_chart_visible())&&(e=this.config.time_step),e}return this.config.time_step;
|
||||
|
||||
},gantt.getLabel=function(t,e){for(var n=this._get_typed_lightbox_config(),i=0;i<n.length;i++)if(n[i].map_to==t)for(var a=n[i].options,s=0;s<a.length;s++)if(a[s].key==e)return a[s].label;return""},gantt.updateCollection=function(t,e){e=e.slice(0);var n=gantt.serverList(t);return n?(n.splice(0,n.length),n.push.apply(n,e||[]),void gantt.resetLightbox()):!1},gantt.getLightboxType=function(){return this._get_safe_type(this._lightbox_type)},gantt.getLightbox=function(t){if(void 0===t&&(t=this.getLightboxType()),
|
||||
!this._lightbox||this.getLightboxType()!=this._get_safe_type(t)){this._lightbox_type=this._get_safe_type(t);var e=document.createElement("DIV");e.className="gantt_cal_light";var n=this._is_lightbox_timepicker();(gantt.config.wide_form||n)&&(e.className+=" gantt_cal_light_wide"),n&&(gantt.config.wide_form=!0,e.className+=" gantt_cal_light_full"),e.style.visibility="hidden";for(var i=this._lightbox_template,a=this.config.buttons_left,s=0;s<a.length;s++){var r=this.config._migrate_buttons[a[s]]?this.config._migrate_buttons[a[s]]:a[s];
|
||||
|
||||
i+="<div class='gantt_btn_set gantt_left_btn_set "+r+"_set'><div dhx_button='1' class='"+r+"'></div><div>"+this.locale.labels[r]+"</div></div>"}a=this.config.buttons_right;for(var s=0;s<a.length;s++){var r=this.config._migrate_buttons[a[s]]?this.config._migrate_buttons[a[s]]:a[s];i+="<div class='gantt_btn_set gantt_right_btn_set "+r+"_set' style='float:right;'><div dhx_button='1' class='"+r+"'></div><div>"+this.locale.labels[r]+"</div></div>"}i+="</div>",e.innerHTML=i,gantt.config.drag_lightbox&&(e.firstChild.onmousedown=gantt._ready_to_dnd,
|
||||
e.firstChild.onselectstart=function(){return!1},e.firstChild.style.cursor="pointer",gantt._init_dnd_events()),document.body.insertBefore(e,document.body.firstChild),this._lightbox=e;var o=this._get_typed_lightbox_config(t);i=this._render_sections(o);for(var l=e.getElementsByTagName("div"),s=0;s<l.length;s++){var d=l[s];if("gantt_cal_larea"==d.className){d.innerHTML=i;break}}this.resizeLightbox(),this._init_lightbox_events(this),e.style.display="none",e.style.visibility="visible"}return this._lightbox;
|
||||
|
||||
},gantt._render_sections=function(t){for(var e="",n=0;n<t.length;n++){var i=this.form_blocks[t[n].type];if(i){t[n].id="area_"+dhtmlx.uid();var a=t[n].hidden?" style='display:none'":"",s="";t[n].button&&(s="<div class='gantt_custom_button' index='"+n+"'><div class='gantt_custom_button_"+t[n].button+"'></div><div>"+this.locale.labels["button_"+t[n].button]+"</div></div>"),this.config.wide_form&&(e+="<div class='gantt_wrap_section' "+a+">"),e+="<div id='"+t[n].id+"' class='gantt_cal_lsection'>"+s+this.locale.labels["section_"+t[n].name]+"</div>"+i.render.call(this,t[n]),
|
||||
e+="</div>"}}return e},gantt.resizeLightbox=function(){var t=this._lightbox;if(t){var e=t.childNodes[1];e.style.height="0px",e.style.height=e.scrollHeight+"px",t.style.height=e.scrollHeight+this.config.lightbox_additional_height+"px",e.style.height=e.scrollHeight+"px"}},gantt._center_lightbox=function(t){if(t){t.style.display="block";var e=window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop,n=window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft,i=window.innerHeight||document.documentElement.clientHeight;
|
||||
|
||||
t.style.top=e?Math.round(e+Math.max((i-t.offsetHeight)/2,0))+"px":Math.round(Math.max((i-t.offsetHeight)/2,0)+9)+"px",t.style.left=document.documentElement.scrollWidth>document.body.offsetWidth?Math.round(n+(document.body.offsetWidth-t.offsetWidth)/2)+"px":Math.round((document.body.offsetWidth-t.offsetWidth)/2)+"px"}},gantt.showCover=function(){if(!this._cover){this._cover=document.createElement("DIV"),this._cover.className="gantt_cal_cover";var t=void 0!==document.height?document.height:document.body.offsetHeight,e=document.documentElement?document.documentElement.scrollHeight:0;
|
||||
|
||||
this._cover.style.height=Math.max(t,e)+"px",document.body.appendChild(this._cover)}},gantt._init_lightbox_events=function(){gantt.lightbox_events={},gantt.lightbox_events.gantt_save_btn=function(){gantt._save_lightbox()},gantt.lightbox_events.gantt_delete_btn=function(){gantt.callEvent("onLightboxDelete",[gantt._lightbox_id])&&(gantt.isTaskExists(gantt._lightbox_id)?gantt.$click.buttons["delete"](gantt._lightbox_id):gantt.hideLightbox())},gantt.lightbox_events.gantt_cancel_btn=function(){gantt._cancel_lightbox();
|
||||
|
||||
},gantt.lightbox_events["default"]=function(t,e){if(e.getAttribute("dhx_button"))gantt.callEvent("onLightboxButton",[e.className,e,t]);else{var n,i,a;-1!=e.className.indexOf("gantt_custom_button")&&(-1!=e.className.indexOf("gantt_custom_button_")?(n=e.parentNode.getAttribute("index"),a=e.parentNode.parentNode):(n=e.getAttribute("index"),a=e.parentNode,e=e.firstChild));var s=gantt._get_typed_lightbox_config();n&&(i=gantt.form_blocks[s[n].type],i.button_click(n,e,a,a.nextSibling))}},dhtmlxEvent(gantt.getLightbox(),"click",function(t){
|
||||
t=t||window.event;var e=t.target?t.target:t.srcElement;if(e.className||(e=e.previousSibling),e&&e.className&&0===e.className.indexOf("gantt_btn_set")&&(e=e.firstChild),e&&e.className){var n=dhtmlx.defined(gantt.lightbox_events[e.className])?gantt.lightbox_events[e.className]:gantt.lightbox_events["default"];return n(t,e)}return!1}),gantt.getLightbox().onkeydown=function(t){switch((t||event).keyCode){case gantt.keys.edit_save:if((t||event).shiftKey)return;gantt._save_lightbox();break;case gantt.keys.edit_cancel:
|
||||
gantt._cancel_lightbox()}}},gantt._cancel_lightbox=function(){var t=this.getLightboxValues();this.callEvent("onLightboxCancel",[this._lightbox_id,t.$new]),gantt.isTaskExists(t.id)&&t.$new&&this._deleteTask(t.id,!0),this.refreshData(),this.hideLightbox()},gantt._save_lightbox=function(){var t=this.getLightboxValues();this.callEvent("onLightboxSave",[this._lightbox_id,t,!!t.$new])&&(t.$new?(delete t.$new,this.addTask(t)):this.isTaskExists(t.id)&&(dhtmlx.mixin(this.getTask(t.id),t,!0),this.updateTask(t.id)),
|
||||
this.refreshData(),this.hideLightbox())},gantt._resolve_default_mapping=function(t){var e=t.map_to,n={time:!0,duration:!0};return n[t.type]&&("auto"==t.map_to?e={start_date:"start_date",end_date:"end_date",duration:"duration"}:"string"==typeof t.map_to&&(e={start_date:t.map_to})),e},gantt.getLightboxValues=function(){var t={};gantt.isTaskExists(this._lightbox_id)&&(t=dhtmlx.mixin({},this.getTask(this._lightbox_id)));for(var e=this._get_typed_lightbox_config(),n=0;n<e.length;n++){var i=document.getElementById(e[n].id);
|
||||
|
||||
i=i?i.nextSibling:i;var a=this.form_blocks[e[n].type];if(a){var s=a.get_value.call(this,i,t,e[n]),r=gantt._resolve_default_mapping(e[n]);if("string"==typeof r&&"auto"!=r)t[r]=s;else if("object"==typeof r)for(var o in r)r[o]&&(t[r[o]]=s[o])}}return t},gantt.hideLightbox=function(){var t=this.getLightbox();t&&(t.style.display="none"),this._lightbox_id=null,this.hideCover(),this.callEvent("onAfterLightbox",[])},gantt.hideCover=function(){this._cover&&this._cover.parentNode.removeChild(this._cover),this._cover=null;
|
||||
|
||||
},gantt.resetLightbox=function(){gantt._lightbox&&!gantt._custom_lightbox&&gantt._lightbox.parentNode.removeChild(gantt._lightbox),gantt._lightbox=null},gantt._set_lightbox_values=function(t,e){var n=t,i=e.getElementsByTagName("span");gantt.templates.lightbox_header?(i[1].innerHTML="",i[2].innerHTML=gantt.templates.lightbox_header(n.start_date,n.end_date,n)):(i[1].innerHTML=this.templates.task_time(n.start_date,n.end_date,n),i[2].innerHTML=(this.templates.task_text(n.start_date,n.end_date,n)||"").substr(0,70));
|
||||
|
||||
for(var a=this._get_typed_lightbox_config(this.getLightboxType()),s=0;s<a.length;s++){var r=a[s];if(this.form_blocks[r.type]){var o=document.getElementById(r.id).nextSibling,l=this.form_blocks[r.type],d=gantt._resolve_default_mapping(a[s]),_=dhtmlx.defined(n[d])?n[d]:r.default_value;l.set_value.call(gantt,o,_,n,r),r.focus&&l.focus.call(gantt,o)}}t.id&&(gantt._lightbox_id=t.id)},gantt._fill_lightbox=function(t,e){var n=this.getTask(t);this._set_lightbox_values(n,e)},gantt.getLightboxSection=function(t){
|
||||
var e=this._get_typed_lightbox_config(),n=0;for(n;n<e.length&&e[n].name!=t;n++);var i=e[n];if(!i)return null;this._lightbox||this.getLightbox();var a=document.getElementById(i.id),s=a.nextSibling,r={section:i,header:a,node:s,getValue:function(t){return gantt.form_blocks[i.type].get_value.call(gantt,s,t||{},i)},setValue:function(t,e){return gantt.form_blocks[i.type].set_value.call(gantt,s,t,e||{},i)}},o=this._lightbox_methods["get_"+i.type+"_control"];return o?o(r):r},gantt._lightbox_methods.get_template_control=function(t){
|
||||
return t.control=t.node,t},gantt._lightbox_methods.get_select_control=function(t){return t.control=t.node.getElementsByTagName("select")[0],t},gantt._lightbox_methods.get_textarea_control=function(t){return t.control=t.node.getElementsByTagName("textarea")[0],t},gantt._lightbox_methods.get_time_control=function(t){return t.control=t.node.getElementsByTagName("select"),t},gantt._init_dnd_events=function(){dhtmlxEvent(document.body,"mousemove",gantt._move_while_dnd),dhtmlxEvent(document.body,"mouseup",gantt._finish_dnd),
|
||||
gantt._init_dnd_events=function(){}},gantt._move_while_dnd=function(t){if(gantt._dnd_start_lb){document.gantt_unselectable||(document.body.className+=" gantt_unselectable",document.gantt_unselectable=!0);var e=gantt.getLightbox(),n=t&&t.target?[t.pageX,t.pageY]:[event.clientX,event.clientY];e.style.top=gantt._lb_start[1]+n[1]-gantt._dnd_start_lb[1]+"px",e.style.left=gantt._lb_start[0]+n[0]-gantt._dnd_start_lb[0]+"px"}},gantt._ready_to_dnd=function(t){var e=gantt.getLightbox();gantt._lb_start=[parseInt(e.style.left,10),parseInt(e.style.top,10)],
|
||||
gantt._dnd_start_lb=t&&t.target?[t.pageX,t.pageY]:[event.clientX,event.clientY]},gantt._finish_dnd=function(){gantt._lb_start&&(gantt._lb_start=gantt._dnd_start_lb=!1,document.body.className=document.body.className.replace(" gantt_unselectable",""),document.gantt_unselectable=!1)},gantt._focus=function(t,e){if(t&&t.focus)if(gantt.config.touch);else try{e&&t.select&&t.select(),t.focus()}catch(n){}},gantt.form_blocks={getTimePicker:function(t,e){var n=t.time_format;if(!n){var n=["%d","%m","%Y"];gantt._get_line(gantt._tasks.unit)<gantt._get_line("day")&&n.push("%H:%i");
|
||||
|
||||
}t._time_format_order={size:0};var i=this.config,a=this.date.date_part(new Date(gantt._min_date.valueOf())),s=1440,r=0;gantt.config.limit_time_select&&(s=60*i.last_hour+1,r=60*i.first_hour,a.setHours(i.first_hour));for(var o="",l=0;l<n.length;l++){var d=n[l];l>0&&(o+=" ");var _="";switch(d){case"%Y":t._time_format_order[2]=l,t._time_format_order.size++;var h,c,g,u;t.year_range&&(isNaN(t.year_range)?t.year_range.push&&(g=t.year_range[0],u=t.year_range[1]):h=t.year_range),h=h||10,c=c||Math.floor(h/2),
|
||||
g=g||a.getFullYear()-c,u=u||g+h;for(var f=g;u>f;f++)_+="<option value='"+f+"'>"+f+"</option>";break;case"%m":t._time_format_order[1]=l,t._time_format_order.size++;for(var f=0;12>f;f++)_+="<option value='"+f+"'>"+this.locale.date.month_full[f]+"</option>";break;case"%d":t._time_format_order[0]=l,t._time_format_order.size++;for(var f=1;32>f;f++)_+="<option value='"+f+"'>"+f+"</option>";break;case"%H:%i":t._time_format_order[3]=l,t._time_format_order.size++;var f=r,p=a.getDate();for(t._time_values=[];s>f;){
|
||||
var v=this.templates.time_picker(a);_+="<option value='"+f+"'>"+v+"</option>",t._time_values.push(f),a.setTime(a.valueOf()+60*this._get_timepicker_step()*1e3);var m=a.getDate()!=p?1:0;f=24*m*60+60*a.getHours()+a.getMinutes()}}if(_){var k=t.readonly?"disabled='disabled'":"",x=e?" style='display:none'":"";o+="<select "+k+x+">"+_+"</select>"}}return o},_fill_lightbox_select:function(t,e,n,i){if(t[e+i[0]].value=n.getDate(),t[e+i[1]].value=n.getMonth(),t[e+i[2]].value=n.getFullYear(),dhtmlx.defined(i[3])){
|
||||
var a=60*n.getHours()+n.getMinutes();a=Math.round(a/gantt._get_timepicker_step())*gantt._get_timepicker_step();var s=t[e+i[3]];s.value=a,s.setAttribute("data-value",a)}},template:{render:function(t){var e=(t.height||"30")+"px";return"<div class='gantt_cal_ltext gantt_cal_template' style='height:"+e+";'></div>"},set_value:function(t,e){t.innerHTML=e||""},get_value:function(t){return t.innerHTML||""},focus:function(){}},textarea:{render:function(t){var e=(t.height||"130")+"px";return"<div class='gantt_cal_ltext' style='height:"+e+";'><textarea></textarea></div>";
|
||||
|
||||
},set_value:function(t,e){t.firstChild.value=e||""},get_value:function(t){return t.firstChild.value},focus:function(t){var e=t.firstChild;gantt._focus(e,!0)}},select:{render:function(t){for(var e=(t.height||"23")+"px",n="<div class='gantt_cal_ltext' style='height:"+e+";'><select style='width:100%;'>",i=0;i<t.options.length;i++)n+="<option value='"+t.options[i].key+"'>"+t.options[i].label+"</option>";return n+="</select></div>"},set_value:function(t,e,n,i){var a=t.firstChild;!a._dhx_onchange&&i.onchange&&(a.onchange=i.onchange,
|
||||
a._dhx_onchange=!0),"undefined"==typeof e&&(e=(a.options[0]||{}).value),a.value=e||""},get_value:function(t){return t.firstChild.value},focus:function(t){var e=t.firstChild;gantt._focus(e,!0)}},time:{render:function(t){var e=this.form_blocks.getTimePicker.call(this,t),n=["<div style='height:"+(t.height||30)+"px;padding-top:0px;font-size:inherit;text-align:center;' class='gantt_section_time'>"];return n.push(e),t.single_date?(e=this.form_blocks.getTimePicker.call(this,t,!0),n.push("<span></span>")):n.push("<span style='font-weight:normal; font-size:10pt;'> – </span>"),
|
||||
n.push(e),n.push("</div>"),n.join("")},set_value:function(t,e,n,i){{var a=i,s=t.getElementsByTagName("select"),r=i._time_format_order;i._time_format_size}if(a.auto_end_date)for(var o=function(){_=new Date(s[r[2]].value,s[r[1]].value,s[r[0]].value,0,0),h=gantt.calculateEndDate(_,1),this.form_blocks._fill_lightbox_select(s,r.size,h,r,a)},l=0;4>l;l++)s[l].onchange=o;var d=gantt._resolve_default_mapping(i);"string"==typeof d&&(d={start_date:d});var _=n[d.start_date]||new Date,h=n[d.end_date]||gantt.calculateEndDate(_,1);
|
||||
|
||||
this.form_blocks._fill_lightbox_select(s,0,_,r,a),this.form_blocks._fill_lightbox_select(s,r.size,h,r,a)},get_value:function(t,e,n){var i=t.getElementsByTagName("select"),a=n._time_format_order,s=0,r=0;if(dhtmlx.defined(a[3])){var o=parseInt(i[a[3]].value,10);s=Math.floor(o/60),r=o%60}var l=new Date(i[a[2]].value,i[a[1]].value,i[a[0]].value,s,r);if(s=r=0,dhtmlx.defined(a[3])){var o=parseInt(i[a.size+a[3]].value,10);s=Math.floor(o/60),r=o%60}var d=new Date(i[a[2]+a.size].value,i[a[1]+a.size].value,i[a[0]+a.size].value,s,r);
|
||||
|
||||
l>=d&&(d=gantt.date.add(l,gantt._get_timepicker_step(),"minute"));var _=gantt._resolve_default_mapping(n),h={start_date:new Date(l),end_date:new Date(d)};return"string"==typeof _?h.start_date:h},focus:function(t){gantt._focus(t.getElementsByTagName("select")[0])}},duration:{render:function(t){var e=this.form_blocks.getTimePicker.call(this,t);e="<div class='gantt_time_selects'>"+e+"</div>";var n=this.locale.labels[this.config.duration_unit+"s"],i=t.single_date?' style="display:none"':"",a=t.readonly?" disabled='disabled'":"",s="<div class='gantt_duration' "+i+"><input type='button' class='gantt_duration_dec' value='-'"+a+"><input type='text' value='5' class='gantt_duration_value'"+a+"><input type='button' class='gantt_duration_inc' value='+'"+a+"> "+n+" <span></span></div>",r="<div style='height:"+(t.height||30)+"px;padding-top:0px;font-size:inherit;' class='gantt_section_time'>"+e+" "+s+"</div>";
|
||||
|
||||
return r},set_value:function(t,e,n,i){function a(){var e=gantt.form_blocks.duration._get_start_date.call(gantt,t,i),n=gantt.form_blocks.duration._get_duration.call(gantt,t,i),a=gantt.calculateEndDate(e,n);h.innerHTML=gantt.templates.task_date(a)}function s(t){var e=d.value;e=parseInt(e,10),window.isNaN(e)&&(e=0),e+=t,1>e&&(e=1),d.value=e,a()}var r=i,o=t.getElementsByTagName("select"),l=t.getElementsByTagName("input"),d=l[1],_=[l[0],l[2]],h=t.getElementsByTagName("span")[0],c=i._time_format_order;
|
||||
_[0].onclick=dhtmlx.bind(function(){s(-1*this.config.duration_step)},this),_[1].onclick=dhtmlx.bind(function(){s(1*this.config.duration_step)},this),o[0].onchange=a,o[1].onchange=a,o[2].onchange=a,o[3]&&(o[3].onchange=a),d.onkeydown=dhtmlx.bind(function(t){t=t||window.event;var e=t.charCode||t.keyCode||t.which;return 40==e?(s(-1*this.config.duration_step),!1):38==e?(s(1*this.config.duration_step),!1):void window.setTimeout(function(){a()},1)},this),d.onchange=dhtmlx.bind(function(){a()},this);var g=gantt._resolve_default_mapping(i);
|
||||
|
||||
"string"==typeof g&&(g={start_date:g});var u=n[g.start_date]||new Date,f=n[g.end_date]||gantt.calculateEndDate(u,1),p=Math.round(n[g.duration])||gantt.calculateDuration(u,f);gantt.form_blocks._fill_lightbox_select(o,0,u,c,r),d.value=p,a()},_get_start_date:function(t,e){var n=t.getElementsByTagName("select"),i=e._time_format_order,a=0,s=0;if(dhtmlx.defined(i[3])){var r=n[i[3]],o=parseInt(r.value,10);isNaN(o)&&r.hasAttribute("data-value")&&(o=parseInt(r.getAttribute("data-value"),10)),a=Math.floor(o/60),
|
||||
s=o%60}return new Date(n[i[2]].value,n[i[1]].value,n[i[0]].value,a,s)},_get_duration:function(t){var e=t.getElementsByTagName("input")[1];return e=parseInt(e.value,10),(!e||window.isNaN(e))&&(e=1),0>e&&(e*=-1),e},get_value:function(t,e,n){var i=gantt.form_blocks.duration._get_start_date(t,n),a=gantt.form_blocks.duration._get_duration(t,n),s=gantt.calculateEndDate(i,a),r=gantt._resolve_default_mapping(n),o={start_date:new Date(i),end_date:new Date(s),duration:a};return"string"==typeof r?o.start_date:o;
|
||||
|
||||
},focus:function(t){gantt._focus(t.getElementsByTagName("select")[0])}},parent:{_filter:function(t,e,n){var i=e.filter||function(){return!0};t=t.slice(0);for(var a=0;a<t.length;a++){var s=t[a];(s.id==n||gantt.isChildOf(s.id,n)||i(s.id,s)===!1)&&(t.splice(a,1),a--)}return t},_display:function(t,e){var n=[],i=[];e&&(n=gantt.getTaskByTime(),t.allow_root&&n.unshift({id:gantt.config.root_id,text:t.root_label||""}),n=this._filter(n,t,e),t.sort&&n.sort(t.sort));for(var a=t.template||gantt.templates.task_text,s=0;s<n.length;s++){
|
||||
var r=a.apply(gantt,[n[s].start_date,n[s].end_date,n[s]]);void 0===r&&(r=""),i.push({key:n[s].id,label:r})}return t.options=i,t.map_to=t.map_to||"parent",gantt.form_blocks.select.render.apply(this,arguments)},render:function(t){return gantt.form_blocks.parent._display(t,!1)},set_value:function(t,e,n,i){var a=document.createElement("div");a.innerHTML=gantt.form_blocks.parent._display(i,n.id);var s=a.removeChild(a.firstChild);return t.onselect=null,t.parentNode.replaceChild(s,t),gantt.form_blocks.select.set_value.apply(gantt,[s,e,n,i]);
|
||||
|
||||
},get_value:function(){return gantt.form_blocks.select.get_value.apply(gantt,arguments)},focus:function(){return gantt.form_blocks.select.focus.apply(gantt,arguments)}}},gantt._is_lightbox_timepicker=function(){for(var t=this._get_typed_lightbox_config(),e=0;e<t.length;e++)if("time"==t[e].name&&"time"==t[e].type)return!0;return!1},gantt._dhtmlx_confirm=function(t,e,n,i){if(!t)return n();var a={text:t};e&&(a.title=e),i&&(a.ok=i),n&&(a.callback=function(t){t&&n()}),dhtmlx.confirm(a)},gantt._get_typed_lightbox_config=function(t){
|
||||
void 0===t&&(t=this.getLightboxType());var e=this._get_type_name(t);return gantt.config.lightbox[e+"_sections"]?gantt.config.lightbox[e+"_sections"]:gantt.config.lightbox.sections},gantt._silent_redraw_lightbox=function(t){var e=this.getLightboxType();if(this.getState().lightbox){var n=this.getState().lightbox,i=this.getLightboxValues(),a=dhtmlx.copy(this.getTask(n));this.resetLightbox();var s=dhtmlx.mixin(a,i,!0),r=this.getLightbox(t?t:void 0);this._center_lightbox(this.getLightbox()),this._set_lightbox_values(s,r);
|
||||
|
||||
}else this.resetLightbox(),this.getLightbox(t?t:void 0);this.callEvent("onLightboxChange",[e,this.getLightboxType()])},gantt._extend_to_optional=function(t){var e=t,n={render:e.render,focus:e.focus,set_value:function(t,i,a,s){var r=gantt._resolve_default_mapping(s);if(a[r.start_date])return n.enable(t,s),e.set_value.call(gantt,t,i,a,s);n.disable(t,s);var o={};for(var l in r)o[r[l]]=a[l];return e.set_value.call(gantt,t,i,o,s)},get_value:function(t,n,i){return i.disabled?{start_date:null}:e.get_value.call(gantt,t,n,i);
|
||||
|
||||
},update_block:function(t,e){if(gantt.callEvent("onSectionToggle",[gantt._lightbox_id,e]),t.style.display=e.disabled?"none":"block",e.button){var n=t.previousSibling.firstChild.firstChild,i=gantt.locale.labels,a=e.disabled?i[e.name+"_enable_button"]:i[e.name+"_disable_button"];n.nextSibling.innerHTML=a}gantt.resizeLightbox()},disable:function(t,e){e.disabled=!0,n.update_block(t,e)},enable:function(t,e){e.disabled=!1,n.update_block(t,e)},button_click:function(t,e,i,a){if(gantt.callEvent("onSectionButton",[gantt._lightbox_id,i])!==!1){
|
||||
var s=gantt._get_typed_lightbox_config()[t];s.disabled?n.enable(a,s):n.disable(a,s)}}};return n},gantt.form_blocks.duration_optional=gantt._extend_to_optional(gantt.form_blocks.duration),gantt.form_blocks.time_optional=gantt._extend_to_optional(gantt.form_blocks.time),dataProcessor.prototype={setTransactionMode:function(t,e){"object"==typeof t?(this._tMode=t.mode||this._tMode,this._headers=this._headers||t.headers,this._payload=this._payload||t.payload):(this._tMode=t,this._tSend=e),"REST"==this._tMode&&(this._tSend=!1,
|
||||
this._endnm=!0)},escape:function(t){return this._utf?encodeURIComponent(t):escape(t)},enableUTFencoding:function(t){this._utf=dhx4.s2b(t)},setDataColumns:function(t){this._columns="string"==typeof t?t.split(","):t},getSyncState:function(){return!this.updatedRows.length},enableDataNames:function(t){this._endnm=dhx4.s2b(t)},enablePartialDataSend:function(t){this._changed=dhx4.s2b(t)},setUpdateMode:function(t,e){this.autoUpdate="cell"==t,this.updateMode=t,this.dnd=e},ignore:function(t,e){this._silent_mode=!0,
|
||||
t.call(e||window),this._silent_mode=!1},setUpdated:function(t,e,n){if(!this._silent_mode){var i=this.findRow(t);n=n||"updated";var a=this.obj.getUserData(t,this.action_param);a&&"updated"==n&&(n=a),e?(this.set_invalid(t,!1),this.updatedRows[i]=t,this.obj.setUserData(t,this.action_param,n),this._in_progress[t]&&(this._in_progress[t]="wait")):this.is_invalid(t)||(this.updatedRows.splice(i,1),this.obj.setUserData(t,this.action_param,"")),e||this._clearUpdateFlag(t),this.markRow(t,e,n),e&&this.autoUpdate&&this.sendData(t);
|
||||
|
||||
}},_clearUpdateFlag:function(){},markRow:function(t,e,n){var i="",a=this.is_invalid(t);if(a&&(i=this.styles[a],e=!0),this.callEvent("onRowMark",[t,e,n,a])&&(i=this.styles[e?n:"clear"]+i,this.obj[this._methods[0]](t,i),a&&a.details)){i+=this.styles[a+"_cell"];for(var s=0;s<a.details.length;s++)a.details[s]&&this.obj[this._methods[1]](t,s,i)}},getState:function(t){return this.obj.getUserData(t,this.action_param)},is_invalid:function(t){return this._invalid[t]},set_invalid:function(t,e,n){n&&(e={value:e,
|
||||
details:n,toString:function(){return this.value.toString()}}),this._invalid[t]=e},checkBeforeUpdate:function(){return!0},sendData:function(t){return!this._waitMode||"tree"!=this.obj.mytype&&!this.obj._h2?(this.obj.editStop&&this.obj.editStop(),"undefined"==typeof t||this._tSend?this.sendAllData():this._in_progress[t]?!1:(this.messages=[],!this.checkBeforeUpdate(t)&&this.callEvent("onValidationError",[t,this.messages])?!1:void this._beforeSendData(this._getRowData(t),t))):void 0},_beforeSendData:function(t,e){
|
||||
return this.callEvent("onBeforeUpdate",[e,this.getState(e),t])?void this._sendData(t,e):!1},serialize:function(t,e){if("string"==typeof t)return t;if("undefined"!=typeof e)return this.serialize_one(t,"");var n=[],i=[];for(var a in t)t.hasOwnProperty(a)&&(n.push(this.serialize_one(t[a],a+this.post_delim)),i.push(a));return n.push("ids="+this.escape(i.join(","))),dhtmlx.security_key&&n.push("dhx_security="+dhtmlx.security_key),n.join("&")},serialize_one:function(t,e){if("string"==typeof t)return t;
|
||||
var n=[];for(var i in t)if(t.hasOwnProperty(i)){if(("id"==i||i==this.action_param)&&"REST"==this._tMode)continue;n.push(this.escape((e||"")+i)+"="+this.escape(t[i]))}return n.join("&")},_sendData:function(t,e){if(t){if(!this.callEvent("onBeforeDataSending",e?[e,this.getState(e),t]:[null,null,t]))return!1;e&&(this._in_progress[e]=(new Date).valueOf());var n=this,i=function(i){var a=[];if(e)a.push(e);else if(t)for(var s in t)a.push(s);return n.afterUpdate(n,i,a)},a=this.serverProcessor+(this._user?dhtmlx.url(this.serverProcessor)+["dhx_user="+this._user,"dhx_version="+this.obj.getUserData(0,"version")].join("&"):"");
|
||||
|
||||
if("GET"==this._tMode)dhx4.ajax.get(a+(-1!=a.indexOf("?")?"&":"?")+this.serialize(t,e),i);else if("POST"==this._tMode)dhx4.ajax.post(a,this.serialize(t,e),i);else if("REST"==this._tMode){var s=this.getState(e),r=a.replace(/(\&|\?)editing\=true/,""),o="",l="post";if("inserted"==s?o=this.serialize(t,e):"deleted"==s?(l="DELETE",r=r+("/"==r.slice(-1)?"":"/")+e):(l="PUT",o=this.serialize(t,e),r=r+("/"==r.slice(-1)?"":"/")+e),this._payload)for(var d in this._payload)r=r+dhtmlx.url(r)+this.escape(d)+"="+this.escape(this._payload[d]);
|
||||
|
||||
dhx4.ajax.query({url:r,method:l,headers:this._headers,data:o,callback:i})}this._waitMode++}},sendAllData:function(){if(this.updatedRows.length){this.messages=[];for(var t=!0,e=0;e<this.updatedRows.length;e++)t&=this.checkBeforeUpdate(this.updatedRows[e]);if(!t&&!this.callEvent("onValidationError",["",this.messages]))return!1;if(this._tSend)this._sendData(this._getAllData());else for(var e=0;e<this.updatedRows.length;e++)if(!this._in_progress[this.updatedRows[e]]){if(this.is_invalid(this.updatedRows[e]))continue;
|
||||
|
||||
if(this._beforeSendData(this._getRowData(this.updatedRows[e]),this.updatedRows[e]),this._waitMode&&("tree"==this.obj.mytype||this.obj._h2))return}}},_getAllData:function(){for(var t={},e=!1,n=0;n<this.updatedRows.length;n++){var i=this.updatedRows[n];this._in_progress[i]||this.is_invalid(i)||this.callEvent("onBeforeUpdate",[i,this.getState(i),this._getRowData(i)])&&(t[i]=this._getRowData(i,i+this.post_delim),e=!0,this._in_progress[i]=(new Date).valueOf())}return e?t:null},setVerificator:function(t,e){
|
||||
this.mandatoryFields[t]=e||function(t){return""!==t}},clearVerificator:function(t){this.mandatoryFields[t]=!1},findRow:function(t){var e=0;for(e=0;e<this.updatedRows.length&&t!=this.updatedRows[e];e++);return e},defineAction:function(t,e){this._uActions||(this._uActions=[]),this._uActions[t]=e},afterUpdateCallback:function(t,e,n,i){var a=t,s="error"!=n&&"invalid"!=n;if(s||this.set_invalid(t,n),this._uActions&&this._uActions[n]&&!this._uActions[n](i))return delete this._in_progress[a];"wait"!=this._in_progress[a]&&this.setUpdated(t,!1);
|
||||
|
||||
var r=t;switch(n){case"inserted":case"insert":e!=t&&(this.obj[this._methods[2]](t,e),t=e);break;case"delete":case"deleted":return this.obj.setUserData(t,this.action_param,"true_deleted"),this.obj[this._methods[3]](t),delete this._in_progress[a],this.callEvent("onAfterUpdate",[t,n,e,i])}"wait"!=this._in_progress[a]?(s&&this.obj.setUserData(t,this.action_param,""),delete this._in_progress[a]):(delete this._in_progress[a],this.setUpdated(e,!0,this.obj.getUserData(t,this.action_param))),this.callEvent("onAfterUpdate",[r,n,e,i]);
|
||||
|
||||
},afterUpdate:function(t,e,n){if(window.JSON)try{var i=JSON.parse(e.xmlDoc.responseText),a=i.action||this.getState(n)||"updated",s=i.sid||n[0],r=i.tid||n[0];return t.afterUpdateCallback(s,r,a,i),void t.finalizeUpdate()}catch(o){}var l=dhx4.ajax.xmltop("data",e.xmlDoc);if(!l)return this.cleanUpdate(n);var d=dhx4.ajax.xpath("//data/action",l);if(!d.length)return this.cleanUpdate(n);for(var _=0;_<d.length;_++){var h=d[_],a=h.getAttribute("type"),s=h.getAttribute("sid"),r=h.getAttribute("tid");t.afterUpdateCallback(s,r,a,h);
|
||||
|
||||
}t.finalizeUpdate()},cleanUpdate:function(t){if(t)for(var e=0;e<t.length;e++)delete this._in_progress[t[e]]},finalizeUpdate:function(){this._waitMode&&this._waitMode--,("tree"==this.obj.mytype||this.obj._h2)&&this.updatedRows.length&&this.sendData(),this.callEvent("onAfterUpdateFinish",[]),this.updatedRows.length||this.callEvent("onFullSync",[])},init:function(t){this.obj=t,this.obj._dp_init&&this.obj._dp_init(this)},setOnAfterUpdate:function(t){this.attachEvent("onAfterUpdate",t)},enableDebug:function(){},
|
||||
setOnBeforeUpdateHandler:function(t){this.attachEvent("onBeforeDataSending",t)},setAutoUpdate:function(t,e){t=t||2e3,this._user=e||(new Date).valueOf(),this._need_update=!1,this._loader=null,this._update_busy=!1,this.attachEvent("onAfterUpdate",function(t,e,n,i){this.afterAutoUpdate(t,e,n,i)}),this.attachEvent("onFullSync",function(){this.fullSync()});var n=this;window.setInterval(function(){n.loadUpdate()},t)},afterAutoUpdate:function(t,e){return"collision"==e?(this._need_update=!0,!1):!0},fullSync:function(){
|
||||
return 1==this._need_update&&(this._need_update=!1,this.loadUpdate()),!0},getUpdates:function(t,e){return this._update_busy?!1:(this._update_busy=!0,this._loader=this._loader||new dtmlXMLLoaderObject(!0),this._loader.async=!0,this._loader.waitCall=e,void this._loader.loadXML(t))},_v:function(t){return t.firstChild?t.firstChild.nodeValue:""},_a:function(t){for(var e=[],n=0;n<t.length;n++)e[n]=this._v(t[n]);return e},loadUpdate:function(){var t=this,e=this.obj.getUserData(0,"version"),n=this.serverProcessor+dhtmlx.url(this.serverProcessor)+["dhx_user="+this._user,"dhx_version="+e].join("&");
|
||||
|
||||
n=n.replace("editing=true&",""),this.getUpdates(n,function(){var e=t._loader.doXPath("//userdata");t.obj.setUserData(0,"version",t._v(e[0]));var n=t._loader.doXPath("//update");if(n.length){t._silent_mode=!0;for(var i=0;i<n.length;i++){var a=n[i].getAttribute("status"),s=n[i].getAttribute("id"),r=n[i].getAttribute("parent");switch(a){case"inserted":t.callEvent("insertCallback",[n[i],s,r]);break;case"updated":t.callEvent("updateCallback",[n[i],s,r]);break;case"deleted":t.callEvent("deleteCallback",[n[i],s,r]);
|
||||
|
||||
}}t._silent_mode=!1}t._update_busy=!1,t=null})}},dhtmlx.assert=function(t,e){t||dhtmlx.message({type:"error",text:e,expire:-1})},gantt.init=function(t,e,n){this.callEvent("onBeforeGanttReady",[]),e&&n&&(this.config.start_date=this._min_date=new Date(e),this.config.end_date=this._max_date=new Date(n)),this._init_skin(),this.config.scroll_size||(this.config.scroll_size=this._detectScrollSize()),dhtmlxEvent(window,"resize",this._on_resize),this.init=function(t){this.$container&&this.$container.parentNode&&(this.$container.parentNode.removeChild(this.$container),
|
||||
this.$container=null),this._reinit(t)},this._reinit(t)},gantt._reinit=function(t){this._init_html_area(t),this._set_sizes(),this._clear_renderers(),this.resetLightbox(),this._update_flags(),this._init_touch_events(),this._init_templates(),this._init_grid(),this._init_tasks(),this._set_scroll_events(),dhtmlxEvent(this.$container,"click",this._on_click),dhtmlxEvent(this.$container,"dblclick",this._on_dblclick),dhtmlxEvent(this.$container,"mousemove",this._on_mousemove),dhtmlxEvent(this.$container,"contextmenu",this._on_contextmenu),
|
||||
this.callEvent("onGanttReady",[]),this.render()},gantt._init_html_area=function(t){this._obj="string"==typeof t?document.getElementById(t):t,dhtmlx.assert(this._obj,"Invalid html container: "+t);var e="<div class='gantt_container'><div class='gantt_grid'></div><div class='gantt_task'></div>";e+="<div class='gantt_ver_scroll'><div></div></div><div class='gantt_hor_scroll'><div></div></div></div>",this._obj.innerHTML=e,this.$container=this._obj.firstChild;var n=this.$container.childNodes;this.$grid=n[0],
|
||||
this.$task=n[1],this.$scroll_ver=n[2],this.$scroll_hor=n[3],this.$grid.innerHTML="<div class='gantt_grid_scale'></div><div class='gantt_grid_data'></div>",this.$grid_scale=this.$grid.childNodes[0],this.$grid_data=this.$grid.childNodes[1],this.$task.innerHTML="<div class='gantt_task_scale'></div><div class='gantt_data_area'><div class='gantt_task_bg'></div><div class='gantt_links_area'></div><div class='gantt_bars_area'></div></div>",this.$task_scale=this.$task.childNodes[0],this.$task_data=this.$task.childNodes[1],
|
||||
this.$task_bg=this.$task_data.childNodes[0],this.$task_links=this.$task_data.childNodes[1],this.$task_bars=this.$task_data.childNodes[2]},gantt.$click={buttons:{edit:function(t){gantt.showLightbox(t)},"delete":function(t){var e=gantt.locale.labels.confirm_deleting,n=gantt.locale.labels.confirm_deleting_title;gantt._dhtmlx_confirm(e,n,function(){var e=gantt.getTask(t);e.$new?(gantt._deleteTask(t,!0),gantt.refreshData()):gantt.deleteTask(t),gantt.hideLightbox()})}}},gantt._calculate_content_height=function(){
|
||||
var t=this.config.scale_height,e=this._order.length*this.config.row_height,n=this._scroll_hor?this.config.scroll_size+1:0;return this._is_grid_visible()||this._is_chart_visible()?t+e+2+n:0},gantt._calculate_content_width=function(){{var t=this._get_grid_width(),e=this._tasks?this._tasks.full_width:0;this._scroll_ver?this.config.scroll_size+1:0}return this._is_chart_visible()||(e=0),this._is_grid_visible()||(t=0),t+e+1},gantt._get_resize_options=function(){var t={x:!1,y:!1};return"xy"==this.config.autosize?t.x=t.y=!0:"y"==this.config.autosize||this.config.autosize===!0?t.y=!0:"x"==this.config.autosize&&(t.x=!0),
|
||||
t},gantt._clean_el_size=function(t){return 1*(t||"").toString().replace("px","")||0},gantt._get_box_styles=function(){var t=null;t=window.getComputedStyle?window.getComputedStyle(this._obj,null):{width:this._obj.clientWidth,height:this._obj.clientHeight};var e=["width","height","paddingTop","paddingBottom","paddingLeft","paddingRight","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],n={boxSizing:"border-box"==t.boxSizing};t.MozBoxSizing&&(n.boxSizing="border-box"==t.MozBoxSizing);
|
||||
|
||||
for(var i=0;i<e.length;i++)n[e[i]]=t[e[i]]?this._clean_el_size(t[e[i]]):0;var a={horPaddings:n.paddingLeft+n.paddingRight+n.borderLeftWidth+n.borderRightWidth,vertPaddings:n.paddingTop+n.paddingBottom+n.borderTopWidth+n.borderBottomWidth,borderBox:n.boxSizing,innerWidth:n.width,innerHeight:n.height,outerWidth:n.width,outerHeight:n.height};return a.borderBox?(a.innerWidth-=a.horPaddings,a.innerHeight-=a.vertPaddings):(a.outerWidth+=a.horPaddings,a.outerHeight+=a.vertPaddings),a},gantt._do_autosize=function(){
|
||||
var t=this._get_resize_options(),e=this._get_box_styles();if(t.y){var n=this._calculate_content_height();e.borderBox&&(n+=e.vertPaddings),this._obj.style.height=n+"px"}if(t.x){var i=this._calculate_content_width();e.borderBox&&(i+=e.horPaddings),this._obj.style.width=i+"px"}},gantt._set_sizes=function(){this._do_autosize();var t=this._get_box_styles();if(this._y=t.innerHeight,!(this._y<20)){this.$grid.style.height=this.$task.style.height=Math.max(this._y-this.$scroll_hor.offsetHeight-2,0)+"px";var e=Math.max(this._y-(this.config.scale_height||0)-this.$scroll_hor.offsetHeight-2,0);
|
||||
|
||||
this.$grid_data.style.height=this.$task_data.style.height=e+"px";var n=Math.max(this._get_grid_width()-1,0);this.$grid.style.width=n+"px",this.$grid.style.display=0===n?"none":"",t=this._get_box_styles(),this._x=t.innerWidth,this._x<20||(this.$grid_data.style.width=Math.max(this._get_grid_width()-1,0)+"px",this.$task.style.width=Math.max(this._x-this._get_grid_width()-2,0)+"px")}},gantt.getScrollState=function(){return this.$task&&this.$task_data?{x:this.$task.scrollLeft,y:this.$task_data.scrollTop
|
||||
}:null},gantt._save_scroll_state=function(t,e){var n={};this._cached_scroll_pos=this._cached_scroll_pos||{},void 0!==t&&(n.x=t),void 0!==e&&(n.y=e),dhtmlx.mixin(this._cached_scroll_pos,n,!0)},gantt._restore_scroll_state=function(){return this._cached_scroll_pos||null},gantt.scrollTo=function(t,e){1*t==t&&(this.$task.scrollLeft=t,this._save_scroll_state(t,void 0)),1*e==e&&(this.$task_data.scrollTop=e,this.$grid_data.scrollTop=e,this._save_scroll_state(void 0,e))},gantt.showDate=function(t){var e=this.posFromDate(t),n=Math.max(e-this.config.task_scroll_offset,0);
|
||||
|
||||
this.scrollTo(n)},gantt.showTask=function(t){var e=this.getTaskNode(t);if(e){var n=Math.max(e.offsetLeft-this.config.task_scroll_offset,0),i=e.offsetTop-(this.$task_data.offsetHeight-this.config.row_height)/2;this.scrollTo(n,i)}},gantt._on_resize=gantt.setSizes=function(){gantt._set_sizes(),gantt._scroll_resize()},gantt.render=function(){if(this._is_render_active()){this.callEvent("onBeforeGanttRender",[]);var t=dhtmlx.copy(this._restore_scroll_state()),e=null;if(t&&(e=gantt.dateFromPos(t.x+this.config.task_scroll_offset)),
|
||||
this._render_grid(),this._render_tasks_scales(),this._scroll_resize(),this._on_resize(),this._render_data(),this.config.preserve_scroll&&t){var n=gantt._restore_scroll_state(),i=gantt.dateFromPos(n.x);(+e!=+i||n.y!=t.y)&&(e&&this.showDate(e),gantt.scrollTo(void 0,t.y))}this.callEvent("onGanttRender",[])}},gantt._set_scroll_events=function(){function t(t){var n=gantt._get_resize_options();gantt._wheel_time=new Date;var i=e?-20*t.deltaX:2*t.wheelDeltaX,a=e?-40*t.deltaY:t.wheelDelta;if(i&&Math.abs(i)>Math.abs(a)){
|
||||
if(n.x)return!0;var s=i/-40,r=gantt.$task.scrollLeft+30*s;gantt.scrollTo(r,null),gantt.$scroll_hor.scrollTop=o}else{if(n.y)return!0;var s=a/-40;"undefined"==typeof a&&(s=t.detail);var o=gantt.$scroll_ver.scrollTop+30*s;if(!gantt.config.prevent_default_scroll&&gantt._cached_scroll_pos&&gantt._cached_scroll_pos.y==o)return!0;gantt.scrollTo(null,o),gantt.$scroll_ver.scrollTop=o}return t.preventDefault&&t.preventDefault(),t.cancelBubble=!0,!1}dhtmlxEvent(this.$scroll_hor,"scroll",function(){if(new Date-(gantt._wheel_time||0)<100)return!0;
|
||||
|
||||
if(!gantt._touch_scroll_active){var t=gantt.$scroll_hor.scrollLeft;gantt.scrollTo(t)}}),dhtmlxEvent(this.$scroll_ver,"scroll",function(){if(!gantt._touch_scroll_active){var t=gantt.$scroll_ver.scrollTop;gantt.$grid_data.scrollTop=t,gantt.scrollTo(null,t)}}),dhtmlxEvent(this.$task,"scroll",function(){var t=gantt.$task.scrollLeft,e=gantt.$scroll_hor.scrollLeft;e!=t&&(gantt.$scroll_hor.scrollLeft=t)}),dhtmlxEvent(this.$task_data,"scroll",function(){var t=gantt.$task_data.scrollTop,e=gantt.$scroll_ver.scrollTop;
|
||||
|
||||
e!=t&&(gantt.$scroll_ver.scrollTop=t)});var e=_isFF&&!window._KHTMLrv;e?dhtmlxEvent(gantt.$container,"wheel",t):dhtmlxEvent(gantt.$container,"mousewheel",t)},gantt._scroll_resize=function(){if(!(this._x<20||this._y<20)){var t=this._get_grid_width(),e=Math.max(this._x-t,0),n=Math.max(this._y-this.config.scale_height,0),i=this.config.scroll_size+1,a=Math.max(this.$task_data.offsetWidth-i,0),s=this.config.row_height*this._order.length,r=this._get_resize_options(),o=this._scroll_hor=r.x?!1:a>e,l=this._scroll_ver=r.y?!1:s>n;
|
||||
|
||||
this.$scroll_hor.style.display=o?"block":"none",this.$scroll_hor.style.height=(o?i:0)+"px",this.$scroll_hor.style.width=Math.max(this._x-(l?i:2),0)+"px",this.$scroll_hor.firstChild.style.width=a+t+i+2+"px",this.$scroll_ver.style.display=l?"block":"none",this.$scroll_ver.style.width=(l?i:0)+"px",this.$scroll_ver.style.height=Math.max(this._y-(o?i:0)-this.config.scale_height,0)+"px",this.$scroll_ver.style.top=this.config.scale_height+"px",this.$scroll_ver.firstChild.style.height=this.config.scale_height+s+"px";
|
||||
|
||||
}},gantt.locate=function(t){var e=gantt._get_target_node(t);if((e.className||"").indexOf("gantt_task_cell")>=0)return null;for(var n=arguments[1]||this.config.task_attribute;e;){if(e.getAttribute){var i=e.getAttribute(n);if(i)return i}e=e.parentNode}return null},gantt._get_target_node=function(t){var e;return t.tagName?e=t:(t=t||window.event,e=t.target||t.srcElement),e},gantt._trim=function(t){var e=String.prototype.trim||function(){return this.replace(/^\s+|\s+$/g,"")};return e.apply(t)},gantt._locate_css=function(t,e,n){
|
||||
void 0===n&&(n=!0);for(var i=gantt._get_target_node(t),a="";i;){if(a=i.className){var s=a.indexOf(e);if(s>=0){if(!n)return i;var r=0===s||!gantt._trim(a.charAt(s-1)),o=s+e.length>=a.length||!gantt._trim(a.charAt(s+e.length));if(r&&o)return i}}i=i.parentNode}return null},gantt._locateHTML=function(t,e){var n=gantt._get_target_node(t);for(e=e||this.config.task_attribute;n;){if(n.getAttribute){var i=n.getAttribute(e);if(i)return n}n=n.parentNode}return null},gantt.getTaskRowNode=function(t){for(var e=this.$grid_data.childNodes,n=this.config.task_attribute,i=0;i<e.length;i++)if(e[i].getAttribute){
|
||||
var a=e[i].getAttribute(n);if(a==t)return e[i]}return null},gantt.getState=function(){return{drag_id:this._tasks_dnd.drag.id,drag_mode:this._tasks_dnd.drag.mode,drag_from_start:this._tasks_dnd.drag.left,selected_task:this._selected_task,min_date:new Date(this._min_date),max_date:new Date(this._max_date),lightbox:this._lightbox_id,touch_drag:this._touch_drag}},gantt._checkTimeout=function(t,e){if(!e)return!0;var n=1e3/e;return 1>n?!0:t._on_timeout?!1:(setTimeout(function(){delete t._on_timeout},n),
|
||||
t._on_timeout=!0,!0)},gantt.selectTask=function(t){if(!this.config.select_task)return!1;if(t){if(this._selected_task==t)return this._selected_task;if(!this.callEvent("onBeforeTaskSelected",[t]))return!1;this.unselectTask(),this._selected_task=t,this.refreshTask(t),this.callEvent("onTaskSelected",[t])}return this._selected_task},gantt.unselectTask=function(){var t=this._selected_task;t&&(this._selected_task=null,this.refreshTask(t),this.callEvent("onTaskUnselected",[t]))},gantt.getSelectedId=function(){
|
||||
return dhtmlx.defined(this._selected_task)?this._selected_task:null},gantt.changeLightboxType=function(t){return this.getLightboxType()==t?!0:void gantt._silent_redraw_lightbox(t)},gantt._is_render_active=function(){return!this._skip_render},gantt.batchUpdate=function(t){var e,n=this._dp&&"off"!=this._dp.updateMode;n&&(e=this._dp.updateMode,this._dp.setUpdateMode("off")),this._skip_render=!0;try{t()}catch(i){}this._skip_render=!1,this.render(),n&&(this._dp.setUpdateMode(e),this._dp.sendData())},gantt.date={
|
||||
init:function(){for(var t=gantt.locale.date.month_short,e=gantt.locale.date.month_short_hash={},n=0;n<t.length;n++)e[t[n]]=n;for(var t=gantt.locale.date.month_full,e=gantt.locale.date.month_full_hash={},n=0;n<t.length;n++)e[t[n]]=n},date_part:function(t){var e=new Date(t);return t.setHours(0),t.setMinutes(0),t.setSeconds(0),t.setMilliseconds(0),t.getHours()&&(t.getDate()<e.getDate()||t.getMonth()<e.getMonth()||t.getFullYear()<e.getFullYear())&&t.setTime(t.getTime()+36e5*(24-t.getHours())),t},time_part:function(t){
|
||||
return(t.valueOf()/1e3-60*t.getTimezoneOffset())%86400},week_start:function(t){var e=t.getDay();return gantt.config.start_on_monday&&(0===e?e=6:e--),this.date_part(this.add(t,-1*e,"day"))},month_start:function(t){return t.setDate(1),this.date_part(t)},year_start:function(t){return t.setMonth(0),this.month_start(t)},day_start:function(t){return this.date_part(t)},hour_start:function(t){var e=t.getHours();return this.day_start(t),t.setHours(e),t},minute_start:function(t){var e=t.getMinutes();return this.hour_start(t),
|
||||
t.setMinutes(e),t},_add_days:function(t,e){var n=new Date(t.valueOf());return n.setDate(n.getDate()+e),e>=0&&!t.getHours()&&n.getHours()&&(n.getDate()<t.getDate()||n.getMonth()<t.getMonth()||n.getFullYear()<t.getFullYear())&&n.setTime(n.getTime()+36e5*(24-n.getHours())),n},add:function(t,e,n){var i=new Date(t.valueOf());switch(n){case"day":i=gantt.date._add_days(i,e);break;case"week":i=gantt.date._add_days(i,7*e);break;case"month":i.setMonth(i.getMonth()+e);break;case"year":i.setYear(i.getFullYear()+e);
|
||||
|
||||
break;case"hour":i.setTime(i.getTime()+60*e*60*1e3);break;case"minute":i.setTime(i.getTime()+60*e*1e3);break;default:return gantt.date["add_"+n](t,e,n)}return i},to_fixed:function(t){return 10>t?"0"+t:t},copy:function(t){return new Date(t.valueOf())},date_to_str:function(t,e){return t=t.replace(/%[a-zA-Z]/g,function(t){switch(t){case"%d":return'"+gantt.date.to_fixed(date.getDate())+"';case"%m":return'"+gantt.date.to_fixed((date.getMonth()+1))+"';case"%j":return'"+date.getDate()+"';case"%n":return'"+(date.getMonth()+1)+"';
|
||||
|
||||
case"%y":return'"+gantt.date.to_fixed(date.getFullYear()%100)+"';case"%Y":return'"+date.getFullYear()+"';case"%D":return'"+gantt.locale.date.day_short[date.getDay()]+"';case"%l":return'"+gantt.locale.date.day_full[date.getDay()]+"';case"%M":return'"+gantt.locale.date.month_short[date.getMonth()]+"';case"%F":return'"+gantt.locale.date.month_full[date.getMonth()]+"';case"%h":return'"+gantt.date.to_fixed((date.getHours()+11)%12+1)+"';case"%g":return'"+((date.getHours()+11)%12+1)+"';case"%G":return'"+date.getHours()+"';
|
||||
|
||||
case"%H":return'"+gantt.date.to_fixed(date.getHours())+"';case"%i":return'"+gantt.date.to_fixed(date.getMinutes())+"';case"%a":return'"+(date.getHours()>11?"pm":"am")+"';case"%A":return'"+(date.getHours()>11?"PM":"AM")+"';case"%s":return'"+gantt.date.to_fixed(date.getSeconds())+"';case"%W":return'"+gantt.date.to_fixed(gantt.date.getISOWeek(date))+"';default:return t}}),e&&(t=t.replace(/date\.get/g,"date.getUTC")),new Function("date",'return "'+t+'";')},str_to_date:function(t,e){for(var n="var temp=date.match(/[a-zA-Z]+|[0-9]+/g);",i=t.match(/%[a-zA-Z]/g),a=0;a<i.length;a++)switch(i[a]){
|
||||
case"%j":case"%d":n+="set[2]=temp["+a+"]||1;";break;case"%n":case"%m":n+="set[1]=(temp["+a+"]||1)-1;";break;case"%y":n+="set[0]=temp["+a+"]*1+(temp["+a+"]>50?1900:2000);";break;case"%g":case"%G":case"%h":case"%H":n+="set[3]=temp["+a+"]||0;";break;case"%i":n+="set[4]=temp["+a+"]||0;";break;case"%Y":n+="set[0]=temp["+a+"]||0;";break;case"%a":case"%A":n+="set[3]=set[3]%12+((temp["+a+"]||'').toLowerCase()=='am'?0:12);";break;case"%s":n+="set[5]=temp["+a+"]||0;";break;case"%M":n+="set[1]=gantt.locale.date.month_short_hash[temp["+a+"]]||0;";
|
||||
|
||||
break;case"%F":n+="set[1]=gantt.locale.date.month_full_hash[temp["+a+"]]||0;"}var s="set[0],set[1],set[2],set[3],set[4],set[5]";return e&&(s=" Date.UTC("+s+")"),new Function("date","var set=[0,0,1,0,0,0]; "+n+" return new Date("+s+");")},getISOWeek:function(t){if(!t)return!1;var e=t.getDay();0===e&&(e=7);var n=new Date(t.valueOf());n.setDate(t.getDate()+(4-e));var i=n.getFullYear(),a=Math.round((n.getTime()-new Date(i,0,1).getTime())/864e5),s=1+Math.floor(a/7);return s},getUTCISOWeek:function(t){
|
||||
return this.getISOWeek(t)},convert_to_utc:function(t){return new Date(t.getUTCFullYear(),t.getUTCMonth(),t.getUTCDate(),t.getUTCHours(),t.getUTCMinutes(),t.getUTCSeconds())},parseDate:function(t,e){return"string"==typeof t&&(dhtmlx.defined(e)&&(e="string"==typeof e?dhtmlx.defined(gantt.templates[e])?gantt.templates[e]:gantt.date.str_to_date(e):gantt.templates.xml_date),t=t?e(t):null),t}},gantt.date.quarter_start=function(t){gantt.date.month_start(t);var e,n=t.getMonth();return e=n>=9?9:n>=6?6:n>=3?3:0,
|
||||
t.setMonth(e),t},gantt.date.add_quarter=function(t,e){return gantt.date.add(t,3*e,"month")},gantt.config||(gantt.config={}),gantt.config||(gantt.config={}),gantt.templates||(gantt.templates={}),function(){dhtmlx.mixin(gantt.config,{links:{finish_to_start:"0",start_to_start:"1",finish_to_finish:"2",start_to_finish:"3"},types:{task:"task",project:"project",milestone:"milestone"},duration_unit:"day",work_time:!1,correct_work_time:!1,skip_off_time:!1,autosize:!1,autosize_min_width:0,show_links:!0,show_task_cells:!0,
|
||||
static_background:!1,branch_loading:!1,show_loading:!1,show_chart:!0,show_grid:!0,min_duration:36e5,xml_date:"%d-%m-%Y %H:%i",api_date:"%d-%m-%Y %H:%i",start_on_monday:!0,server_utc:!1,show_progress:!0,fit_tasks:!1,select_task:!0,scroll_on_click:!0,preserve_scroll:!0,readonly:!1,date_grid:"%Y-%m-%d",drag_links:!0,drag_progress:!0,drag_resize:!0,drag_move:!0,drag_mode:{resize:"resize",progress:"progress",move:"move",ignore:"ignore"},round_dnd_dates:!0,link_wrapper_width:20,root_id:0,autofit:!1,columns:[{
|
||||
name:"text",tree:!0,width:"*",resize:!0},{name:"start_date",align:"center",resize:!0},{name:"duration",align:"center"},{name:"add",width:"44"}],step:1,scale_unit:"day",scale_offset_minimal:!0,subscales:[],inherit_scale_class:!1,time_step:60,duration_step:1,date_scale:"%d %M",task_date:"%d %F %Y",time_picker:"%H:%i",task_attribute:"task_id",link_attribute:"link_id",layer_attribute:"data-layer",buttons_left:["gantt_save_btn","gantt_cancel_btn"],_migrate_buttons:{dhx_save_btn:"gantt_save_btn",dhx_cancel_btn:"gantt_cancel_btn",
|
||||
dhx_delete_btn:"gantt_delete_btn"},buttons_right:["gantt_delete_btn"],lightbox:{sections:[{name:"description",height:70,map_to:"text",type:"textarea",focus:!0},{name:"time",type:"duration",map_to:"auto"}],project_sections:[{name:"description",height:70,map_to:"text",type:"textarea",focus:!0},{name:"type",type:"typeselect",map_to:"type"},{name:"time",type:"duration",readonly:!0,map_to:"auto"}],milestone_sections:[{name:"description",height:70,map_to:"text",type:"textarea",focus:!0},{name:"type",type:"typeselect",
|
||||
map_to:"type"},{name:"time",type:"duration",single_date:!0,map_to:"auto"}]},drag_lightbox:!0,sort:!1,details_on_create:!0,details_on_dblclick:!0,initial_scroll:!0,task_scroll_offset:100,task_height:"full",min_column_width:70,min_grid_column_width:70,grid_resizer_column_attribute:"column_index",grid_resizer_attribute:"grid_resizer",keep_grid_width:!1,grid_resize:!1,readonly_property:"readonly",editable_property:"editable",type_renderers:{},open_tree_initially:!1,optimize_render:"auto",prevent_default_scroll:!1
|
||||
}),gantt.keys={edit_save:13,edit_cancel:27},gantt._init_template=function(t,e){var n=this._reg_templates||{};this.config[t]&&n[t]!=this.config[t]&&(e&&this.templates[t]||(this.templates[t]=this.date.date_to_str(this.config[t]),n[t]=this.config[t])),this._reg_templates=n},gantt._init_templates=function(){var t=gantt.locale.labels;t.gantt_save_btn=t.icon_save,t.gantt_cancel_btn=t.icon_cancel,t.gantt_delete_btn=t.icon_delete;var e=this.date.date_to_str,n=this.config;gantt._init_template("date_scale",!0),
|
||||
gantt._init_template("date_grid",!0),gantt._init_template("task_date",!0),dhtmlx.mixin(this.templates,{xml_date:this.date.str_to_date(n.xml_date,n.server_utc),xml_format:e(n.xml_date,n.server_utc),api_date:this.date.str_to_date(n.api_date),progress_text:function(){return""},grid_header_class:function(){return""},task_text:function(t,e,n){return n.text},task_class:function(){return""},grid_row_class:function(){return""},task_row_class:function(){return""},task_cell_class:function(){return""},scale_cell_class:function(){
|
||||
return""},scale_row_class:function(){return""},grid_indent:function(){return"<div class='gantt_tree_indent'></div>"},grid_folder:function(t){return"<div class='gantt_tree_icon gantt_folder_"+(t.$open?"open":"closed")+"'></div>"},grid_file:function(){return"<div class='gantt_tree_icon gantt_file'></div>"},grid_open:function(t){return"<div class='gantt_tree_icon gantt_"+(t.$open?"close":"open")+"'></div>"},grid_blank:function(){return"<div class='gantt_tree_icon gantt_blank'></div>"},task_time:function(t,e){
|
||||
return gantt.templates.task_date(t)+" - "+gantt.templates.task_date(e)},time_picker:e(n.time_picker),link_class:function(){return""},link_description:function(t){var e=gantt.getTask(t.source),n=gantt.getTask(t.target);return"<b>"+e.text+"</b> – <b>"+n.text+"</b>"},drag_link:function(t,e,n,i){t=gantt.getTask(t);var a=gantt.locale.labels,s="<b>"+t.text+"</b> "+(e?a.link_start:a.link_end)+"<br/>";return n&&(n=gantt.getTask(n),s+="<b> "+n.text+"</b> "+(i?a.link_start:a.link_end)+"<br/>"),s},drag_link_class:function(t,e,n,i){
|
||||
var a="";if(t&&n){var s=gantt.isLinkAllowed(t,n,e,i);a=" "+(s?"gantt_link_allow":"gantt_link_deny")}return"gantt_link_tooltip"+a}}),this.callEvent("onTemplatesReady",[])}}(),window.jQuery&&!function(t){var e=[];t.fn.dhx_gantt=function(n){if(n=n||{},"string"!=typeof n){var i=[];return this.each(function(){if(this&&this.getAttribute&&!this.getAttribute("dhxgantt")){for(var t in n)"data"!=t&&(gantt.config[t]=n[t]);gantt.init(this),n.data&&gantt.parse(n.data),i.push(gantt)}}),1===i.length?i[0]:i}return e[n]?e[n].apply(this,[]):void t.error("Method "+n+" does not exist on jQuery.dhx_gantt");
|
||||
|
||||
}}(jQuery),window.dhtmlx&&(dhtmlx.attaches||(dhtmlx.attaches={}),dhtmlx.attaches.attachGantt=function(t,e){var n=document.createElement("DIV");n.id="gantt_"+dhtmlx.uid(),n.style.width="100%",n.style.height="100%",n.cmp="grid",document.body.appendChild(n),this.attachObject(n.id);var i=this.vs[this.av];i.grid=gantt,gantt.init(n.id,t,e),n.firstChild.style.border="none",i.gridId=n.id,i.gridObj=n;var a="_viewRestore";return this.vs[this[a]()].grid}),gantt.locale={date:{month_full:["January","February","March","April","May","June","July","August","September","October","November","December"],
|
||||
month_short:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],day_full:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],day_short:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]},labels:{new_task:"New task",icon_save:"Save",icon_cancel:"Cancel",icon_details:"Details",icon_edit:"Edit",icon_delete:"Delete",confirm_closing:"",confirm_deleting:"Task will be deleted permanently, are you sure?",section_description:"Description",section_time:"Time period",section_type:"Type",
|
||||
column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}},gantt.skins.skyblue={config:{grid_width:350,row_height:27,scale_height:27,link_line_width:1,link_arrow_size:8,lightbox_additional_height:75},_second_column_width:95,
|
||||
_third_column_width:80},gantt.skins.meadow={config:{grid_width:350,row_height:27,scale_height:30,link_line_width:2,link_arrow_size:6,lightbox_additional_height:72},_second_column_width:95,_third_column_width:80},gantt.skins.terrace={config:{grid_width:360,row_height:35,scale_height:35,link_line_width:2,link_arrow_size:6,lightbox_additional_height:75},_second_column_width:90,_third_column_width:70},gantt.skins.broadway={config:{grid_width:360,row_height:35,scale_height:35,link_line_width:1,link_arrow_size:7,
|
||||
lightbox_additional_height:86},_second_column_width:90,_third_column_width:80,_lightbox_template:"<div class='gantt_cal_ltitle'><span class='gantt_mark'> </span><span class='gantt_time'></span><span class='gantt_title'></span><div class='gantt_cancel_btn'></div></div><div class='gantt_cal_larea'></div>",_config_buttons_left:{},_config_buttons_right:{gantt_delete_btn:"icon_delete",gantt_save_btn:"icon_save"}},gantt.config.touch_drag=500,gantt.config.touch=!0,gantt.config.touch_feedback=!0,gantt._touch_feedback=function(){
|
||||
gantt.config.touch_feedback&&navigator.vibrate&&navigator.vibrate(1)},gantt._init_touch_events=function(){"force"!=this.config.touch&&(this.config.touch=this.config.touch&&(-1!=navigator.userAgent.indexOf("Mobile")||-1!=navigator.userAgent.indexOf("iPad")||-1!=navigator.userAgent.indexOf("Android")||-1!=navigator.userAgent.indexOf("Touch"))),this.config.touch&&(window.navigator.msPointerEnabled?this._touch_events(["MSPointerMove","MSPointerDown","MSPointerUp"],function(t){return t.pointerType==t.MSPOINTER_TYPE_MOUSE?null:t;
|
||||
|
||||
},function(t){return!t||t.pointerType==t.MSPOINTER_TYPE_MOUSE}):this._touch_events(["touchmove","touchstart","touchend"],function(t){return t.touches&&t.touches.length>1?null:t.touches[0]?{target:t.target,pageX:t.touches[0].pageX,pageY:t.touches[0].pageY,clientX:t.touches[0].clientX,clientY:t.touches[0].clientY}:t},function(){return!1}))},gantt._touch_events=function(t,e,n){function i(t){return t&&t.preventDefault&&t.preventDefault(),(t||event).cancelBubble=!0,!1}function a(t){var e=gantt._task_area_pulls,n=gantt.getTask(t);
|
||||
|
||||
if(n&&gantt.isTaskVisible(t))for(var i in e)if(n=e[i][t],n&&n.getAttribute("task_id")&&n.getAttribute("task_id")==t){var a=n.cloneNode(!0);return h=n,e[i][t]=a,n.style.display="none",a.className+=" gantt_drag_move ",n.parentNode.appendChild(a),a}}var s,r=0,o=!1,l=!1,d=null,_=null,h=null;this._gantt_touch_event_ready||(this._gantt_touch_event_ready=1,dhtmlxEvent(gantt.$container,t[0],function(t){if(!n(t)&&o){_&&clearTimeout(_);var a=e(t);if(gantt._tasks_dnd.drag.id||gantt._tasks_dnd.drag.start_drag)return gantt._tasks_dnd.on_mouse_move(a),
|
||||
t.preventDefault&&t.preventDefault(),t.cancelBubble=!0,!1;if(a&&d){var h=d.pageX-a.pageX,c=d.pageY-a.pageY;!l&&(Math.abs(h)>5||Math.abs(c)>5)&&(gantt._touch_scroll_active=l=!0,r=0,s=gantt.getScrollState()),l&&gantt.scrollTo(s.x+h,s.y+c)}return i(t)}})),dhtmlxEvent(this.$container,"contextmenu",function(t){return o?i(t):void 0}),dhtmlxEvent(this.$container,t[1],function(t){if(!n(t)){if(t.touches&&t.touches.length>1)return void(o=!1);if(o=!0,d=e(t),d&&r){var s=new Date;500>s-r?(gantt._on_dblclick(d),
|
||||
i(t)):r=s}else r=new Date;_=setTimeout(function(){var t=gantt.locate(d);t&&-1==d.target.className.indexOf("gantt_link_point")&&(gantt._tasks_dnd.on_mouse_down(d),gantt._tasks_dnd._start_dnd(d),gantt._touch_drag=!0,a(t),gantt.refreshTask(t),gantt._touch_feedback()),_=null},gantt.config.touch_drag)}}),dhtmlxEvent(this.$container,t[2],function(t){if(!n(t)){_&&clearTimeout(_),gantt._touch_drag=!1,o=!1;var i=e(t);gantt._tasks_dnd.on_mouse_up(i),h&&(gantt.refreshTask(gantt.locate(h)),h.parentNode.removeChild(h),
|
||||
gantt._touch_feedback()),gantt._touch_scroll_active=o=l=!1,h=null}})};
|
||||
//# sourceMappingURL=sources/dhtmlxgantt.js.map
|
||||
15
libraries/dhtmlxgantt/ext/dhtmlxgantt_marker.js
Normal file
15
libraries/dhtmlxgantt/ext/dhtmlxgantt_marker.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt._markers||(gantt._markers={}),gantt.config.show_markers=!0,gantt.attachEvent("onClear",function(){gantt._markers={}}),gantt.attachEvent("onGanttReady",function(){function t(t){if(!gantt.config.show_markers)return!1;if(!t.start_date)return!1;var e=gantt.getState();if(!(+t.start_date>+e.max_date||+t.end_date&&+t.end_date<+e.min_date||+t.start_date<+e.min_date)){var r=document.createElement("div");r.setAttribute("marker_id",t.id);var a="gantt_marker";gantt.templates.marker_class&&(a+=" "+gantt.templates.marker_class(t)),
|
||||
t.css&&(a+=" "+t.css),t.title&&(r.title=t.title),r.className=a;var n=gantt.posFromDate(t.start_date);if(r.style.left=n+"px",r.style.height=Math.max(gantt._y_from_ind(gantt._order.length),0)+"px",t.end_date){var s=gantt.posFromDate(t.end_date);r.style.width=Math.max(s-n,0)+"px"}return t.text&&(r.innerHTML="<div class='gantt_marker_content' >"+t.text+"</div>"),r}}var e=document.createElement("div");e.className="gantt_marker_area",gantt.$task_data.appendChild(e),gantt.$marker_area=e,gantt._markerRenderer=gantt._task_renderer("markers",t,gantt.$marker_area,null);
|
||||
|
||||
}),gantt.attachEvent("onDataRender",function(){gantt.renderMarkers()}),gantt.getMarker=function(t){return this._markers?this._markers[t]:null},gantt.addMarker=function(t){return t.id=t.id||dhtmlx.uid(),this._markers[t.id]=t,t.id},gantt.deleteMarker=function(t){return this._markers&&this._markers[t]?(delete this._markers[t],!0):!1},gantt.updateMarker=function(t){this._markerRenderer&&this._markerRenderer.render_item(t)},gantt.renderMarkers=function(){if(!this._markers)return!1;if(!this._markerRenderer)return!1;
|
||||
|
||||
var t=[];for(var e in this._markers)t.push(this._markers[e]);return this._markerRenderer.render_items(t),!0};
|
||||
//# sourceMappingURL=../sources/ext/dhtmlxgantt_marker.js.map
|
||||
21
libraries/dhtmlxgantt/ext/dhtmlxgantt_multiselect.js
Normal file
21
libraries/dhtmlxgantt/ext/dhtmlxgantt_multiselect.js
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.config.multiselect=!0,gantt.config.multiselect_one_level=!1,gantt._multiselect={selected:{},one_level:!0,active:!0,isActive:function(){return this.update_state(),this.active},update_state:function(){this.one_level=gantt.config.multiselect_one_level;var t=this.active;this.active=gantt.config.multiselect,this.active!=t&&this.reset()},reset:function(){this.selected={}},set_last_selected:function(t){this.last_selected=t},getLastSelected:function(){return this.last_selected?this.last_selected:null;
|
||||
|
||||
},select:function(t,e){gantt.callEvent("onBeforeTaskMultiSelect",[t,!0,e])&&(this.selected[t]=!0,this.set_last_selected(t),gantt.callEvent("onTaskMultiSelect",[t,!0,e]))},toggle:function(t,e){this.selected[t]?this.unselect(t,e):this.select(t,e)},unselect:function(t,e){gantt.callEvent("onBeforeTaskMultiSelect",[t,!1,e])&&(this.selected[t]=!1,this.last_selected==t&&(this.last_selected=null),gantt.callEvent("onTaskMultiSelect",[t,!0,e]))},isSelected:function(t){return!!this.selected[t]},getSelected:function(){
|
||||
var t=[];for(var e in this.selected)this.selected[e]&&t.push(e);return t.sort(function(t,e){return gantt.calculateTaskLevel(gantt.getTask(t))>gantt.calculateTaskLevel(gantt.getTask(e))?1:-1}),t},forSelected:function(t){for(var e=this.getSelected(),n=0;n<e.length;n++)t(e[n])},is_same_level:function(t){if(!this.one_level)return!0;var e=this.getLastSelected();return e&&gantt.isTaskExists(e)&&gantt.isTaskExists(t)?!(gantt.calculateTaskLevel(gantt.getTask(e))!=gantt.calculateTaskLevel(gantt.getTask(t))):!0;
|
||||
|
||||
},_after_select:function(t){gantt.refreshTask(t)},_do_selection:function(t){if(!this.isActive())return!0;var e=gantt.locate(t),n=this.getSelected();if(!e)return!0;if(!gantt.callEvent("onBeforeMultiSelect",[t]))return!0;if(t.ctrlKey)e&&(this.toggle(e,t),this._after_select(e));else if(t.shiftKey&&n.length){var a=this.getLastSelected();if(a||(a=n[n.length-1]),e&&a!=e){for(var s=gantt.getGlobalTaskIndex(a),l=gantt.getGlobalTaskIndex(e),r=e;gantt.getGlobalTaskIndex(r)!=s;)this.select(r),this._after_select(r),
|
||||
r=s>l?gantt.getNext(r):gantt.getPrev(r);this.forSelected(dhtmlx.bind(function(t){var e=gantt.getGlobalTaskIndex(t);(e>s&&e>l||s>e&&l>e)&&(this.unselect(t),gantt.refreshTask(t))},this))}}else this.forSelected(dhtmlx.bind(function(t){t!=e&&(this.unselect(t),gantt.refreshTask(t))},this)),this.isSelected(e)||(this.select(e),this._after_select(e));return this.isSelected(e)?!0:!1}},function(){var t=gantt.selectTask;gantt.selectTask=function(e){var n=t.call(this,e);return this.config.multiselect&&this._multiselect.select(e),
|
||||
n};var e=gantt.unselectTask;gantt.unselectTask=function(t){var n=e.call(this,t);return this.config.multiselect&&this._multiselect.unselect(t),n},gantt.toggleTaskSelection=function(t){this.config.multiselect&&this._multiselect.toggle(t)},gantt.getSelectedTasks=function(){return this._multiselect.getSelected()},gantt.eachSelectedTask=function(t){return this._multiselect.forSelected(t)},gantt.isSelectedTask=function(t){return this._multiselect.isSelected(t)},gantt.getLastSelectedTask=function(){return this._multiselect.getLastSelected();
|
||||
|
||||
}}(),gantt.attachEvent("onTaskIdChange",function(t,e){var n=gantt._multiselect;return n.isActive()?void(gantt.isSelectedTask(t)&&(n.unselect(t,null),n.select(e,null),gantt.refreshTask(e))):!0}),gantt.attachEvent("onAfterTaskDelete",function(t){var e=gantt._multiselect;return e.isActive()?(e.selected[t]&&e.unselect(t,null),void e.forSelected(function(t){gantt.isTaskExists(t)||e.unselect(t,null)})):!0}),gantt.attachEvent("onBeforeTaskMultiSelect",function(t,e){var n=gantt._multiselect;return e&&n.isActive()?n.is_same_level(t):!0;
|
||||
|
||||
}),gantt.attachEvent("onTaskClick",function(t,e){var n=gantt._multiselect._do_selection(e);return gantt.callEvent("onMultiSelect",[e]),n}),gantt.attachEvent("onEmptyClick",function(t){return gantt._multiselect._do_selection(t),gantt.callEvent("onMultiSelect",[t]),!0});
|
||||
//# sourceMappingURL=../sources/ext/dhtmlxgantt_multiselect.js.map
|
||||
22
libraries/dhtmlxgantt/ext/dhtmlxgantt_quick_info.js
Normal file
22
libraries/dhtmlxgantt/ext/dhtmlxgantt_quick_info.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.config.quickinfo_buttons=["icon_delete","icon_edit"],gantt.config.quick_info_detached=!0,gantt.config.show_quick_info=!0,gantt.attachEvent("onTaskClick",function(t){return gantt.showQuickInfo(t),!0}),function(){for(var t=["onEmptyClick","onViewChange","onLightbox","onBeforeTaskDelete","onBeforeDrag"],e=function(){return gantt._hideQuickInfo(),!0},n=0;n<t.length;n++)gantt.attachEvent(t[n],e)}(),gantt.templates.quick_info_title=function(t,e,n){return n.text.substr(0,50)},gantt.templates.quick_info_content=function(t,e,n){
|
||||
return n.details||n.text},gantt.templates.quick_info_date=function(t,e,n){return gantt.templates.task_time(t,e,n)},gantt.templates.quick_info_class=function(){return""},gantt.showQuickInfo=function(t){if(t!=this._quick_info_box_id&&this.config.show_quick_info){this.hideQuickInfo(!0);var e=this._get_event_counter_part(t);e&&(this._quick_info_box=this._init_quick_info(e,t),this._quick_info_box.className=gantt._prepare_quick_info_classname(t),this._fill_quick_data(t),this._show_quick_info(e))}},gantt._hideQuickInfo=function(){
|
||||
gantt.hideQuickInfo()},gantt.hideQuickInfo=function(t){var e=this._quick_info_box;if(this._quick_info_box_id=0,e&&e.parentNode){if(gantt.config.quick_info_detached)return e.parentNode.removeChild(e);e.className+=" gantt_qi_hidden","auto"==e.style.right?e.style.left="-350px":e.style.right="-350px",t&&e.parentNode.removeChild(e)}},dhtmlxEvent(window,"keydown",function(t){27==t.keyCode&&gantt.hideQuickInfo()}),gantt._show_quick_info=function(t){var e=gantt._quick_info_box;if(gantt.config.quick_info_detached){
|
||||
e.parentNode&&"#document-fragment"!=e.parentNode.nodeName.toLowerCase()||gantt.$task_data.appendChild(e);var n=e.offsetWidth,i=e.offsetHeight,a=this.getScrollState(),s=this.$task.offsetWidth+a.x-n;e.style.left=Math.min(Math.max(a.x,t.left-t.dx*(n-t.width)),s)+"px",e.style.top=t.top-(t.dy?i:-t.height)-25+"px"}else e.style.top="20px",1==t.dx?(e.style.right="auto",e.style.left="-300px",setTimeout(function(){e.style.left="-10px"},1)):(e.style.left="auto",e.style.right="-300px",setTimeout(function(){e.style.right="-10px";
|
||||
|
||||
},1)),e.className+=" gantt_qi_"+(1==t.dx?"left":"right"),gantt._obj.appendChild(e)},gantt._prepare_quick_info_classname=function(t){var e=gantt.getTask(t),n="gantt_cal_quick_info",i=this.templates.quick_info_class(e.start_date,e.end_date,e);return i&&(n+=" "+i),n},gantt._init_quick_info=function(t,e){var n=gantt.getTask(e);if("boolean"==typeof this._quick_info_readonly&&this._is_readonly(n)!==this._quick_info_readonly&&(gantt.hideQuickInfo(!0),this._quick_info_box=null),this._quick_info_readonly=this._is_readonly(n),
|
||||
!this._quick_info_box){var i=this._quick_info_box=document.createElement("div"),a='<div class="gantt_cal_qi_title"><div class="gantt_cal_qi_tcontent"></div><div class="gantt_cal_qi_tdate"></div></div><div class="gantt_cal_qi_content"></div>';a+='<div class="gantt_cal_qi_controls">';for(var s=gantt.config.quickinfo_buttons,r={icon_delete:!0,icon_edit:!0},o=0;o<s.length;o++)this._quick_info_readonly&&r[s[o]]||(a+='<div class="gantt_qi_big_icon '+s[o]+'" title="'+gantt.locale.labels[s[o]]+"\"><div class='gantt_menu_icon "+s[o]+"'></div><div>"+gantt.locale.labels[s[o]]+"</div></div>");
|
||||
|
||||
a+="</div>",i.innerHTML=a,dhtmlxEvent(i,"click",function(t){t=t||event,gantt._qi_button_click(t.target||t.srcElement)}),gantt.config.quick_info_detached&&dhtmlxEvent(gantt.$task_data,"scroll",function(){gantt.hideQuickInfo()})}return this._quick_info_box},gantt._qi_button_click=function(t){var e=gantt._quick_info_box;if(t&&t!=e){var n=t.className;if(-1!=n.indexOf("_icon")){var i=gantt._quick_info_box_id;gantt.$click.buttons[n.split(" ")[1].replace("icon_","")](i)}else gantt._qi_button_click(t.parentNode);
|
||||
|
||||
}},gantt._get_event_counter_part=function(t){for(var e=gantt.getTaskNode(t),n=0,i=0,a=e;a&&"gantt_task"!=a.className;)n+=a.offsetLeft,i+=a.offsetTop,a=a.offsetParent;var s=this.getScrollState();if(a){var r=n+e.offsetWidth/2-s.x>gantt._x/2?1:0,o=i+e.offsetHeight/2-s.y>gantt._y/2?1:0;return{left:n,top:i,dx:r,dy:o,width:e.offsetWidth,height:e.offsetHeight}}return 0},gantt._fill_quick_data=function(t){var e=gantt.getTask(t),n=gantt._quick_info_box;gantt._quick_info_box_id=t;var i=n.firstChild.firstChild;
|
||||
|
||||
i.innerHTML=gantt.templates.quick_info_title(e.start_date,e.end_date,e);var a=i.nextSibling;a.innerHTML=gantt.templates.quick_info_date(e.start_date,e.end_date,e);var s=n.firstChild.nextSibling;s.innerHTML=gantt.templates.quick_info_content(e.start_date,e.end_date,e)};
|
||||
//# sourceMappingURL=../sources/ext/dhtmlxgantt_quick_info.js.map
|
||||
17
libraries/dhtmlxgantt/ext/dhtmlxgantt_tooltip.js
Normal file
17
libraries/dhtmlxgantt/ext/dhtmlxgantt_tooltip.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt._tooltip={},gantt._tooltip_class="gantt_tooltip",gantt.config.tooltip_timeout=30,gantt.config.tooltip_offset_y=20,gantt.config.tooltip_offset_x=10,gantt._create_tooltip=function(){return this._tooltip_html||(this._tooltip_html=document.createElement("div"),this._tooltip_html.className=gantt._tooltip_class),this._tooltip_html},gantt._is_cursor_under_tooltip=function(t,e){return t.x>=e.pos.x&&t.x<=e.pos.x+e.width?!0:t.y>=e.pos.y&&t.y<=e.pos.y+e.height?!0:!1},gantt._show_tooltip=function(t,e){
|
||||
if(!gantt.config.touch||gantt.config.touch_tooltip){var n=this._create_tooltip();n.innerHTML=t,gantt.$task_data.appendChild(n);var i=n.offsetWidth+20,a=n.offsetHeight+40,s=this.$task.offsetHeight,r=this.$task.offsetWidth,o=this.getScrollState();e.y+=o.y;var l={x:e.x,y:e.y};e.x+=1*gantt.config.tooltip_offset_x||0,e.y+=1*gantt.config.tooltip_offset_y||0,e.y=Math.min(Math.max(o.y,e.y),o.y+s-a),e.x=Math.min(Math.max(o.x,e.x),o.x+r-i),gantt._is_cursor_under_tooltip(l,{pos:e,width:i,height:a})&&(l.x+i>r+o.x&&(e.x=l.x-(i-20)-(1*gantt.config.tooltip_offset_x||0)),
|
||||
l.y+a>s+o.y&&(e.y=l.y-(a-40)-(1*gantt.config.tooltip_offset_y||0))),n.style.left=e.x+"px",n.style.top=e.y+"px"}},gantt._hide_tooltip=function(){this._tooltip_html&&this._tooltip_html.parentNode&&this._tooltip_html.parentNode.removeChild(this._tooltip_html),this._tooltip_id=0},gantt._is_tooltip=function(t){var e=t.target||t.srcElement;return gantt._is_node_child(e,function(t){return t.className==this._tooltip_class})},gantt._is_task_line=function(t){var e=t.target||t.srcElement;return gantt._is_node_child(e,function(t){
|
||||
return t==this.$task_data})},gantt._is_node_child=function(t,e){for(var n=!1;t&&!n;)n=e.call(gantt,t),t=t.parentNode;return n},gantt._tooltip_pos=function(t){if(t.pageX||t.pageY)var e={x:t.pageX,y:t.pageY};var n=_isIE?document.documentElement:document.body,e={x:t.clientX+n.scrollLeft-n.clientLeft,y:t.clientY+n.scrollTop-n.clientTop},i=gantt._get_position(gantt.$task_data);return e.x=e.x-i.x,e.y=e.y-i.y,e},gantt.attachEvent("onMouseMove",function(t,e){if(this.config.tooltip_timeout){document.createEventObject&&!document.createEvent&&(e=document.createEventObject(e));
|
||||
|
||||
var n=this.config.tooltip_timeout;this._tooltip_id&&!t&&(isNaN(this.config.tooltip_hide_timeout)||(n=this.config.tooltip_hide_timeout)),clearTimeout(gantt._tooltip_ev_timer),gantt._tooltip_ev_timer=setTimeout(function(){gantt._init_tooltip(t,e)},n)}else gantt._init_tooltip(t,e)}),gantt._init_tooltip=function(t,e){if(!this._is_tooltip(e)&&(t!=this._tooltip_id||this._is_task_line(e))){if(!t)return this._hide_tooltip();this._tooltip_id=t;var n=this.getTask(t),i=this.templates.tooltip_text(n.start_date,n.end_date,n);
|
||||
|
||||
return i?void this._show_tooltip(i,this._tooltip_pos(e)):void this._hide_tooltip()}},gantt.attachEvent("onMouseLeave",function(t){gantt._is_tooltip(t)||this._hide_tooltip()}),gantt.templates.tooltip_date_format=gantt.date.date_to_str("%Y-%m-%d"),gantt.templates.tooltip_text=function(t,e,n){return"<b>Task:</b> "+n.text+"<br/><b>Start date:</b> "+gantt.templates.tooltip_date_format(t)+"<br/><b>End date:</b> "+gantt.templates.tooltip_date_format(e)};
|
||||
//# sourceMappingURL=../sources/ext/dhtmlxgantt_tooltip.js.map
|
||||
11
libraries/dhtmlxgantt/locale/locale.js
Normal file
11
libraries/dhtmlxgantt/locale/locale.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["January","February","March","April","May","June","July","August","September","October","November","December"],month_short:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],day_full:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],day_short:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]},labels:{new_task:"New task",icon_save:"Save",icon_cancel:"Cancel",icon_details:"Details",icon_edit:"Edit",icon_delete:"Delete",confirm_closing:"",
|
||||
confirm_deleting:"Task will be deleted permanently, are you sure?",section_description:"Description",section_time:"Time period",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_ar.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_ar.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["كانون الثاني","شباط","آذار","نيسان","أيار","حزيران","تموز","آب","أيلول","تشرين الأول","تشرين الثاني","كانون الأول"],month_short:["يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر"],day_full:["الأحد","الأثنين","ألثلاثاء","الأربعاء","ألحميس","ألجمعة","السبت"],day_short:["احد","اثنين","ثلاثاء","اربعاء","خميس","جمعة","سبت"]},labels:{dhx_cal_today_button:"اليوم",day_tab:"يوم",week_tab:"أسبوع",month_tab:"شهر",new_event:"حدث جديد",
|
||||
icon_save:"اخزن",icon_cancel:"الغاء",icon_details:"تفاصيل",icon_edit:"تحرير",icon_delete:"حذف",confirm_closing:"التغييرات سوف تضيع, هل انت متأكد؟",confirm_deleting:"الحدث سيتم حذفها نهائيا ، هل أنت متأكد؟",section_description:"الوصف",section_time:"الفترة الزمنية",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",
|
||||
type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_ar.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_be.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_be.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Студзень","Люты","Сакавік","Красавік","Maй","Чэрвень","Ліпень","Жнівень","Верасень","Кастрычнік","Лістапад","Снежань"],month_short:["Студз","Лют","Сак","Крас","Maй","Чэр","Ліп","Жнів","Вер","Каст","Ліст","Снеж"],day_full:["Нядзеля","Панядзелак","Аўторак","Серада","Чацвер","Пятніца","Субота"],day_short:["Нд","Пн","Аўт","Ср","Чцв","Пт","Сб"]},labels:{dhx_cal_today_button:"Сёння",day_tab:"Дзень",week_tab:"Тыдзень",month_tab:"Месяц",new_event:"Новая падзея",icon_save:"Захаваць",
|
||||
icon_cancel:"Адмяніць",icon_details:"Дэталі",icon_edit:"Змяніць",icon_delete:"Выдаліць",confirm_closing:"",confirm_deleting:"Падзея будзе выдалена незваротна, працягнуць?",section_description:"Апісанне",section_time:"Перыяд часу",section_type:"Тып",column_text:"Задача",column_start_date:"Пачатак",column_duration:"Працяг",column_add:"",link:"Сувязь",confirm_link_deleting:"будзе выдалена",link_start:"(пачатак)",link_end:"(канец)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Хвiлiна",
|
||||
hours:"Гадзiна",days:"Дзень",weeks:"Тыдзень",months:"Месяц",years:"Год"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_be.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_ca.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_ca.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Gener","Febrer","Març","Abril","Maig","Juny","Juliol","Agost","Setembre","Octubre","Novembre","Desembre"],month_short:["Gen","Feb","Mar","Abr","Mai","Jun","Jul","Ago","Set","Oct","Nov","Des"],day_full:["Diumenge","Dilluns","Dimarts","Dimecres","Dijous","Divendres","Dissabte"],day_short:["Dg","Dl","Dm","Dc","Dj","Dv","Ds"]},labels:{dhx_cal_today_button:"Hui",day_tab:"Dia",week_tab:"Setmana",month_tab:"Mes",new_event:"Nou esdeveniment",icon_save:"Guardar",icon_cancel:"Cancel·lar",
|
||||
icon_details:"Detalls",icon_edit:"Editar",icon_delete:"Esborrar",confirm_closing:"",confirm_deleting:"L'esdeveniment s'esborrarà definitivament, continuar ?",section_description:"Descripció",section_time:"Periode de temps",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",
|
||||
hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_ca.js.map
|
||||
11
libraries/dhtmlxgantt/locale/locale_cn.js
Normal file
11
libraries/dhtmlxgantt/locale/locale_cn.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.config.day_date="%M %d日 %D",gantt.config.default_date="%Y年 %M %d日",gantt.config.month_date="%Y年 %M",gantt.locale={date:{month_full:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],month_short:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],day_full:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],day_short:["日","一","二","三","四","五","六"]},labels:{dhx_cal_today_button:"今天",day_tab:"日",week_tab:"周",month_tab:"月",new_event:"新建日程",icon_save:"保存",icon_cancel:"关闭",icon_details:"详细",
|
||||
icon_edit:"编辑",icon_delete:"删除",confirm_closing:"请确认是否撤销修改!",confirm_deleting:"是否删除日程?",section_description:"描述",section_time:"时间范围",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_cn.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_cs.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_cs.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Leden","Únor","Březen","Duben","Květen","Červen","Červenec","Srpen","Září","Říjen","Listopad","Prosinec"],month_short:["Led","Ún","Bře","Dub","Kvě","Čer","Čec","Srp","Září","Říj","List","Pro"],day_full:["Neděle","Pondělí","Úterý","Středa","Čtvrtek","Pátek","Sobota"],day_short:["Ne","Po","Út","St","Čt","Pá","So"]},labels:{dhx_cal_today_button:"Dnes",day_tab:"Den",week_tab:"Týden",month_tab:"Měsíc",new_event:"Nová událost",icon_save:"Uložit",icon_cancel:"Zpět",icon_details:"Detail",
|
||||
icon_edit:"Edituj",icon_delete:"Smazat",confirm_closing:"",confirm_deleting:"Událost bude trvale smazána, opravdu?",section_description:"Poznámky",section_time:"Doba platnosti",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",
|
||||
months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_cs.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_da.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_da.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Januar","Februar","Marts","April","Maj","Juni","Juli","August","September","Oktober","November","December"],month_short:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],day_full:["Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag"],day_short:["Søn","Man","Tir","Ons","Tor","Fre","Lør"]},labels:{dhx_cal_today_button:"Idag",day_tab:"Dag",week_tab:"Uge",month_tab:"Måned",new_event:"Ny begivenhed",icon_save:"Gem",icon_cancel:"Fortryd",
|
||||
icon_details:"Detaljer",icon_edit:"Tilret",icon_delete:"Slet",confirm_closing:"Dine rettelser vil gå tabt.. Er dy sikker?",confirm_deleting:"Bigivenheden vil blive slettet permanent. Er du sikker?",section_description:"Beskrivelse",section_time:"Tidsperiode",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",
|
||||
type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_da.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_de.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_de.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:[" Januar"," Februar"," März "," April"," Mai"," Juni"," Juli"," August"," September "," Oktober"," November "," Dezember"],month_short:["Jan","Feb","Mär","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],day_full:["Sonntag","Montag","Dienstag"," Mittwoch"," Donnerstag","Freitag","Samstag"],day_short:["So","Mo","Di","Mi","Do","Fr","Sa"]},labels:{dhx_cal_today_button:"Heute",day_tab:"Tag",week_tab:"Woche",month_tab:"Monat",new_event:"neuer Eintrag",icon_save:"Speichern",
|
||||
icon_cancel:"Abbrechen",icon_details:"Details",icon_edit:"Ändern",icon_delete:"Löschen",confirm_closing:"",confirm_deleting:"Der Eintrag wird gelöscht",section_description:"Beschreibung",section_time:"Zeitspanne",section_type:"Type",column_text:"Task-Namen",column_start_date:"Startzeit",column_duration:"Dauer",column_add:"",link:"Link",confirm_link_deleting:"werden gelöscht",link_start:"(starten)",link_end:"(ende)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minuten",
|
||||
hours:"Stunden",days:"Tage",weeks:"Wochen",months:"Monate",years:"Jahre"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_de.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_el.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_el.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Ιανουάριος","Φεβρουάριος","Μάρτιος","Απρίλιος","Μάϊος","Ιούνιος","Ιούλιος","Αύγουστος","Σεπτέμβριος","Οκτώβριος","Νοέμβριος","Δεκέμβριος"],month_short:["ΙΑΝ","ΦΕΒ","ΜΑΡ","ΑΠΡ","ΜΑΙ","ΙΟΥΝ","ΙΟΥΛ","ΑΥΓ","ΣΕΠ","ΟΚΤ","ΝΟΕ","ΔΕΚ"],day_full:["Κυριακή","Δευτέρα","Τρίτη","Τετάρτη","Πέμπτη","Παρασκευή","Κυριακή"],day_short:["ΚΥ","ΔΕ","ΤΡ","ΤΕ","ΠΕ","ΠΑ","ΣΑ"]},labels:{dhx_cal_today_button:"Σήμερα",day_tab:"Ημέρα",week_tab:"Εβδομάδα",month_tab:"Μήνας",new_event:"Νέο έργο",
|
||||
icon_save:"Αποθήκευση",icon_cancel:"Άκυρο",icon_details:"Λεπτομέρειες",icon_edit:"Επεξεργασία",icon_delete:"Διαγραφή",confirm_closing:"",confirm_deleting:"Το έργο θα διαγραφεί οριστικά. Θέλετε να συνεχίσετε;",section_description:"Περιγραφή",section_time:"Χρονική περίοδος",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",
|
||||
type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_el.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_es.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_es.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre"],month_short:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],day_full:["Domingo","Lunes","Martes","Miércoles","Jueves","Viernes","Sábado"],day_short:["Dom","Lun","Mar","Mié","Jue","Vie","Sáb"]},labels:{dhx_cal_today_button:"Hoy",day_tab:"Día",week_tab:"Semana",month_tab:"Mes",new_event:"Nuevo evento",icon_save:"Guardar",icon_cancel:"Cancelar",
|
||||
icon_details:"Detalles",icon_edit:"Editar",icon_delete:"Eliminar",confirm_closing:"",confirm_deleting:"El evento se borrará definitivamente, ¿continuar?",section_description:"Descripción",section_time:"Período",section_type:"Type",column_text:"Tarea",column_start_date:"Inicio",column_duration:"Dur.",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",
|
||||
hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_es.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_fi.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_fi.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Tammikuu","Helmikuu","Maaliskuu","Huhtikuu","Toukokuu","Kesäkuu","Heinäkuu","Elokuu","Syyskuu","Lokakuu","Marraskuu","Joulukuu"],month_short:["Tam","Hel","Maa","Huh","Tou","Kes","Hei","Elo","Syy","Lok","Mar","Jou"],day_full:["Sunnuntai","Maanantai","Tiistai","Keskiviikko","Torstai","Perjantai","Lauantai"],day_short:["Su","Ma","Ti","Ke","To","Pe","La"]},labels:{dhx_cal_today_button:"Tänään",day_tab:"Päivä",week_tab:"Viikko",month_tab:"Kuukausi",new_event:"Uusi tapahtuma",
|
||||
icon_save:"Tallenna",icon_cancel:"Peru",icon_details:"Tiedot",icon_edit:"Muokkaa",icon_delete:"Poista",confirm_closing:"",confirm_deleting:"Haluatko varmasti poistaa tapahtuman?",section_description:"Kuvaus",section_time:"Aikajakso",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",
|
||||
minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_fi.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_fr.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_fr.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"],month_short:["Jan","Fév","Mar","Avr","Mai","Juin","Juil","Aoû","Sep","Oct","Nov","Déc"],day_full:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],day_short:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"]},labels:{new_task:"Nouvelle tâche",icon_save:"Enregistrer",icon_cancel:"Annuler",icon_details:"Détails",icon_edit:"Modifier",icon_delete:"Effacer",
|
||||
confirm_closing:"",confirm_deleting:"L'événement sera effacé sans appel, êtes-vous sûr ?",section_description:"Description",section_time:"Période",section_type:"Type",column_text:"Nom de la tâche",column_start_date:"Date initiale",column_duration:"Durée",column_add:"",link:"Le lien",confirm_link_deleting:"sera supprimé",link_start:"(début)",link_end:"(fin)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",hours:"Heures",days:"Jours",weeks:"Semaines",months:"Mois",
|
||||
years:"Années"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_fr.js.map
|
||||
11
libraries/dhtmlxgantt/locale/locale_he.js
Normal file
11
libraries/dhtmlxgantt/locale/locale_he.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["ינואר","פברואר","מרץ","אפריל","מאי","יוני","יולי","אוגוסט","ספטמבר","אוקטובר","נובמבר","דצמבר"],month_short:["ינו","פבר","מרץ","אפר","מאי","יונ","יול","אוג","ספט","אוק","נוב","דצמ"],day_full:["ראשון","שני","שלישי","רביעי","חמישי","שישי","שבת"],day_short:["א","ב","ג","ד","ה","ו","ש"]},labels:{dhx_cal_today_button:"היום",day_tab:"יום",week_tab:"שבוע",month_tab:"חודש",new_event:"ארוע חדש",icon_save:"שמור",icon_cancel:"בטל",icon_details:"פרטים",icon_edit:"ערוך",icon_delete:"מחק",
|
||||
confirm_closing:"",confirm_deleting:"ארוע ימחק סופית.להמשיך?",section_description:"הסבר",section_time:"תקופה",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_he.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_hu.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_hu.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Január","Február","Március","Április","Május","Június","Július","Augusztus","Szeptember","Október","November","December"],month_short:["Jan","Feb","Már","Ápr","Máj","Jún","Júl","Aug","Sep","Okt","Nov","Dec"],day_full:["Vasárnap","Hétfõ","Kedd","Szerda","Csütörtök","Péntek","szombat"],day_short:["Va","Hé","Ke","Sze","Csü","Pé","Szo"]},labels:{dhx_cal_today_button:"Ma",day_tab:"Nap",week_tab:"Hét",month_tab:"Hónap",new_event:"Új esemény",icon_save:"Mentés",icon_cancel:"Mégse",
|
||||
icon_details:"Részletek",icon_edit:"Szerkesztés",icon_delete:"Törlés",confirm_closing:"",confirm_deleting:"Az esemény törölve lesz, biztosan folytatja?",section_description:"Leírás",section_time:"Idõszak",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",
|
||||
days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_hu.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_id.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_id.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Januari","Februari","Maret","April","Mei","Juni","Juli","Agustus","September","Oktober","November","Desember"],month_short:["Jan","Feb","Mar","Apr","Mei","Jun","Jul","Ags","Sep","Okt","Nov","Des"],day_full:["Minggu","Senin","Selasa","Rabu","Kamis","Jumat","Sabtu"],day_short:["Ming","Sen","Sel","Rab","Kam","Jum","Sab"]},labels:{dhx_cal_today_button:"Hari Ini",day_tab:"Hari",week_tab:"Minggu",month_tab:"Bulan",new_event:"Acara Baru",icon_save:"Simpan",icon_cancel:"Batal",
|
||||
icon_details:"Detail",icon_edit:"Edit",icon_delete:"Hapus",confirm_closing:"",confirm_deleting:"Acara akan dihapus",section_description:"Keterangan",section_time:"Periode",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",
|
||||
months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_id.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_it.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_it.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Gennaio","Febbraio","Marzo","Aprile","Maggio","Giugno","Luglio","Agosto","Settembre","Ottobre","Novembre","Dicembre"],month_short:["Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"],day_full:["Domenica","Lunedì","Martedì","Mercoledì","Giovedì","Venerdì","Sabato"],day_short:["Dom","Lun","Mar","Mer","Gio","Ven","Sab"]},labels:{dhx_cal_today_button:"Oggi",day_tab:"Giorno",week_tab:"Settimana",month_tab:"Mese",new_event:"Nuovo evento",icon_save:"Salva",
|
||||
icon_cancel:"Chiudi",icon_details:"Dettagli",icon_edit:"Modifica",icon_delete:"Elimina",confirm_closing:"",confirm_deleting:"L'evento sarà eliminato, siete sicuri?",section_description:"Descrizione",section_time:"Periodo di tempo",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",
|
||||
minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_it.js.map
|
||||
11
libraries/dhtmlxgantt/locale/locale_jp.js
Normal file
11
libraries/dhtmlxgantt/locale/locale_jp.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],month_short:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],day_full:["日曜日","月曜日","火曜日","水曜日","木曜日","金曜日","土曜日"],day_short:["日","月","火","水","木","金","土"]},labels:{dhx_cal_today_button:"今日",day_tab:"日",week_tab:"週",month_tab:"月",new_event:"新イベント",icon_save:"保存",icon_cancel:"キャンセル",icon_details:"詳細",icon_edit:"編集",icon_delete:"削除",confirm_closing:"",confirm_deleting:"イベント完全に削除されます、宜しいですか?",
|
||||
section_description:"デスクリプション",section_time:"期間",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_jp.js.map
|
||||
11
libraries/dhtmlxgantt/locale/locale_kr.js
Normal file
11
libraries/dhtmlxgantt/locale/locale_kr.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],month_short:["1월","2월","3월","4월","5월","6월","7월","8월","9월","10월","11월","12월"],day_full:["일요일","월요일","화요일","수요일","목요일","금요일","토요일"],day_short:["일","월","화","수","목","금","토"]},labels:{new_task:"이름없는 작업",icon_save:"저장",icon_cancel:"취소",icon_details:"세부 사항",icon_edit:"수정",icon_delete:"삭제",confirm_closing:"",confirm_deleting:"작업을 삭제하시겠습니까?",section_description:"설명",section_time:"기간",section_type:"Type",column_text:"작업명",
|
||||
column_start_date:"시작일",column_duration:"기간",column_add:"",link:"전제",confirm_link_deleting:"삭제 하시겠습니까?",link_start:" (start)",link_end:" (end)",type_task:"작업",type_project:"프로젝트",type_milestone:"마일스톤",minutes:"분",hours:"시간",days:"일",weeks:"주",months:"달",years:"년"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_kr.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_nb.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_nb.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Januar","Februar","Mars","April","Mai","Juni","Juli","August","September","Oktober","November","Desember"],month_short:["Jan","Feb","Mar","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Des"],day_full:["Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag"],day_short:["Søn","Mon","Tir","Ons","Tor","Fre","Lør"]},labels:{dhx_cal_today_button:"I dag",day_tab:"Dag",week_tab:"Uke",month_tab:"Måned",new_event:"Ny hendelse",icon_save:"Lagre",icon_cancel:"Avbryt",
|
||||
icon_details:"Detaljer",icon_edit:"Rediger",icon_delete:"Slett",confirm_closing:"",confirm_deleting:"Hendelsen vil bli slettet permanent. Er du sikker?",section_description:"Beskrivelse",section_time:"Tidsperiode",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",
|
||||
hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_nb.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_nl.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_nl.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Januari","Februari","Maart","April","Mei","Juni","Juli","Augustus","September","Oktober","November","December"],month_short:["Jan","Feb","mrt","Apr","Mei","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],day_full:["Zondag","Maandag","Dinsdag","Woensdag","Donderdag","Vrijdag","Zaterdag"],day_short:["Zo","Ma","Di","Wo","Do","Vr","Za"]},labels:{dhx_cal_today_button:"Vandaag",day_tab:"Dag",week_tab:"Week",month_tab:"Maand",new_event:"Nieuw item",icon_save:"Opslaan",icon_cancel:"Annuleren",
|
||||
icon_details:"Details",icon_edit:"Bewerken",icon_delete:"Verwijderen",confirm_closing:"",confirm_deleting:"Item zal permanent worden verwijderd, doorgaan?",section_description:"Beschrijving",section_time:"Tijd periode",section_type:"Type",column_text:"Taak omschrijving",column_start_date:"Startdatum",column_duration:"Duur",column_add:"",link:"Koppeling",confirm_link_deleting:"zal worden verwijderd",link_start:" (start)",link_end:" (eind)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",
|
||||
minutes:"minuten",hours:"uren",days:"dagen",weeks:"weken",months:"maanden",years:"jaren"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_nl.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_no.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_no.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Januar","Februar","Mars","April","Mai","Juni","Juli","August","September","Oktober","November","Desember"],month_short:["Jan","Feb","Mar","Apr","Mai","Jun","Jul","Aug","Sep","Okt","Nov","Des"],day_full:["Søndag","Mandag","Tirsdag","Onsdag","Torsdag","Fredag","Lørdag"],day_short:["Søn","Man","Tir","Ons","Tor","Fre","Lør"]},labels:{dhx_cal_today_button:"Idag",day_tab:"Dag",week_tab:"Uke",month_tab:"Måned",new_event:"Ny",icon_save:"Lagre",icon_cancel:"Avbryt",icon_details:"Detaljer",
|
||||
icon_edit:"Endre",icon_delete:"Slett",confirm_closing:"Endringer blir ikke lagret, er du sikker?",confirm_deleting:"Oppføringen vil bli slettet, er du sikker?",section_description:"Beskrivelse",section_time:"Tidsperiode",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",
|
||||
hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_no.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_pl.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_pl.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Styczeń","Luty","Marzec","Kwiecień","Maj","Czerwiec","Lipiec","Sierpień","Wrzesień","Październik","Listopad","Grudzień"],month_short:["Sty","Lut","Mar","Kwi","Maj","Cze","Lip","Sie","Wrz","Paź","Lis","Gru"],day_full:["Niedziela","Poniedziałek","Wtorek","Środa","Czwartek","Piątek","Sobota"],day_short:["Nie","Pon","Wto","Śro","Czw","Pią","Sob"]},labels:{dhx_cal_today_button:"Dziś",day_tab:"Dzień",week_tab:"Tydzień",month_tab:"Miesiąc",new_event:"Nowe zdarzenie",icon_save:"Zapisz",
|
||||
icon_cancel:"Anuluj",icon_details:"Szczegóły",icon_edit:"Edytuj",icon_delete:"Usuń",confirm_closing:"",confirm_deleting:"Zdarzenie zostanie usunięte na zawsze, kontynuować?",section_description:"Opis",section_time:"Okres czasu",section_type:"Typ",column_text:"Nazwa zadania",column_start_date:"Początek",column_duration:"Czas trwania",column_add:"",link:"Link",confirm_link_deleting:"zostanie usunięty",link_start:" (początek)",link_end:" (koniec)",type_task:"Zadanie",type_project:"Projekt",type_milestone:"Milestone",
|
||||
minutes:"Minuty",hours:"Godziny",days:"Dni",weeks:"Tydzień",months:"Miesiące",years:"Lata"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_pl.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_pt.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_pt.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro"],month_short:["Jan","Fev","Mar","Abr","Mai","Jun","Jul","Ago","Set","Out","Nov","Dez"],day_full:["Domingo","Segunda","Terça","Quarta","Quinta","Sexta","Sábado"],day_short:["Dom","Seg","Ter","Qua","Qui","Sex","Sab"]},labels:{dhx_cal_today_button:"Hoje",day_tab:"Dia",week_tab:"Semana",month_tab:"Mês",new_event:"Novo evento",icon_save:"Salvar",icon_cancel:"Cancelar",
|
||||
icon_details:"Detalhes",icon_edit:"Editar",icon_delete:"Deletar",confirm_closing:"Suas alterações serão perdidas. Você tem certeza?",confirm_deleting:"Tem certeza que deseja excluir?",section_description:"Descrição",section_time:"Período de tempo",section_type:"Type",column_text:"Nome tarefa",column_start_date:"Data início",column_duration:"Duração",column_add:"",link:"Link",confirm_link_deleting:"será apagado",link_start:" (início)",link_end:" (fim)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",
|
||||
minutes:"Minutos",hours:"Horas",days:"Dias",weeks:"Semanas",months:"Meses",years:"Anos"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_pt.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_ro.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_ro.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Ianuarie","Februarie","Martie","Aprilie","Mai","Iunie","Iulie","August","Septembrie","Octombrie","November","December"],month_short:["Ian","Feb","Mar","Apr","Mai","Iun","Iul","Aug","Sep","Oct","Nov","Dec"],day_full:["Duminica","Luni","Marti","Miercuri","Joi","Vineri","Sambata"],day_short:["Du","Lu","Ma","Mi","Jo","Vi","Sa"]},labels:{dhx_cal_today_button:"Astazi",day_tab:"Zi",week_tab:"Saptamana",month_tab:"Luna",new_event:"Eveniment nou",icon_save:"Salveaza",icon_cancel:"Anuleaza",
|
||||
icon_details:"Detalii",icon_edit:"Editeaza",icon_delete:"Sterge",confirm_closing:"Schimbarile nu vor fi salvate, esti sigur?",confirm_deleting:"Evenimentul va fi sters permanent, esti sigur?",section_description:"Descriere",section_time:"Interval",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",
|
||||
minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_ro.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_ru.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_ru.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Январь","Февраль","Март","Апрель","Maй","Июнь","Июль","Август","Сентябрь","Oктябрь","Ноябрь","Декабрь"],month_short:["Янв","Фев","Maр","Aпр","Maй","Июн","Июл","Aвг","Сен","Окт","Ноя","Дек"],day_full:["Воскресенье","Понедельник","Вторник","Среда","Четверг","Пятница","Суббота"],day_short:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"]},labels:{dhx_cal_today_button:"Сегодня",day_tab:"День",week_tab:"Неделя",month_tab:"Месяц",new_event:"Новое событие",icon_save:"Сохранить",icon_cancel:"Отменить",
|
||||
icon_details:"Детали",icon_edit:"Изменить",icon_delete:"Удалить",confirm_closing:"",confirm_deleting:"Событие будет удалено безвозвратно, продолжить?",section_description:"Описание",section_time:"Период времени",section_type:"Тип",column_text:"Задача",column_start_date:"Начало",column_duration:"Длительность",column_add:"",link:"Связь",confirm_link_deleting:"будет удалена",link_start:" (начало)",link_end:" (конец)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Минута",
|
||||
hours:"Час",days:"День",weeks:"Неделя",months:"Месяц",years:"Год"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_ru.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_si.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_si.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Januar","Februar","Marec","April","Maj","Junij","Julij","Avgust","September","Oktober","November","December"],month_short:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],day_full:["Nedelja","Ponedeljek","Torek","Sreda","Četrtek","Petek","Sobota"],day_short:["Ned","Pon","Tor","Sre","Čet","Pet","Sob"]},labels:{dhx_cal_today_button:"Danes",day_tab:"Dan",week_tab:"Teden",month_tab:"Mesec",new_event:"Nov dogodek",icon_save:"Shrani",icon_cancel:"Prekliči",
|
||||
icon_details:"Podrobnosti",icon_edit:"Uredi",icon_delete:"Izbriši",confirm_closing:"",confirm_deleting:"Dogodek bo izbrisan. Želite nadaljevati?",section_description:"Opis",section_time:"Časovni okvir",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",
|
||||
days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_si.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_sk.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_sk.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Január","Február","Marec","Apríl","Máj","Jún","Júl","August","September","Október","November","December"],month_short:["Jan","Feb","Mar","Apr","Máj","Jún","Júl","Aug","Sept","Okt","Nov","Dec"],day_full:["Nedeľa","Pondelok","Utorok","Streda","Štvrtok","Piatok","Sobota"],day_short:["Ne","Po","Ut","St","Št","Pi","So"]},labels:{dhx_cal_today_button:"Dnes",day_tab:"Deň",week_tab:"Týždeň",month_tab:"Mesiac",new_event:"Nová udalosť",icon_save:"Uložiť",icon_cancel:"Späť",
|
||||
icon_details:"Detail",icon_edit:"Edituj",icon_delete:"Zmazať",confirm_closing:"Vaše zmeny nebudú uložené. Skutočne?",confirm_deleting:"Udalosť bude natrvalo vymazaná. Skutočne?",section_description:"Poznámky",section_time:"Doba platnosti",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",
|
||||
minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_sk.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_sv.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_sv.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Januari","Februari","Mars","April","Maj","Juni","Juli","Augusti","September","Oktober","November","December"],month_short:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec"],day_full:["Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag"],day_short:["Sön","Mån","Tis","Ons","Tor","Fre","Lör"]},labels:{dhx_cal_today_button:"Idag",day_tab:"Dag",week_tab:"Vecka",month_tab:"Månad",new_event:"Ny händelse",icon_save:"Spara",icon_cancel:"Avbryt",
|
||||
icon_details:"Detajer",icon_edit:"Ändra",icon_delete:"Ta bort",confirm_closing:"",confirm_deleting:"Är du säker på att du vill ta bort händelsen permanent?",section_description:"Beskrivning",section_time:"Tid",section_type:"Typ",column_text:"Uppgiftsnamn",column_start_date:"Starttid",column_duration:"Varaktighet",column_add:"",link:"Länk",confirm_link_deleting:"kommer tas bort",link_start:" (start)",link_end:" (slut)",type_task:"Uppgift",type_project:"Projekt",type_milestone:"Milstolpe",minutes:"Minuter",
|
||||
hours:"Timmar",days:"Dagar",weeks:"Veckor",months:"Månader",years:"År"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_sv.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_tr.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_tr.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Ocak","Þubat","Mart","Nisan","Mayýs","Haziran","Temmuz","Aðustos","Eylül","Ekim","Kasým","Aralýk"],month_short:["Oca","Þub","Mar","Nis","May","Haz","Tem","Aðu","Eyl","Eki","Kas","Ara"],day_full:["Pazar","Pazartes,","Salý","Çarþamba","Perþembe","Cuma","Cumartesi"],day_short:["Paz","Pts","Sal","Çar","Per","Cum","Cts"]},labels:{dhx_cal_today_button:"Bugün",day_tab:"Gün",week_tab:"Hafta",month_tab:"Ay",new_event:"Uygun",icon_save:"Kaydet",icon_cancel:"Ýptal",icon_details:"Detaylar",
|
||||
icon_edit:"Düzenle",icon_delete:"Sil",confirm_closing:"",confirm_deleting:"Etkinlik silinecek, devam?",section_description:"Açýklama",section_time:"Zaman aralýðý",section_type:"Type",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",
|
||||
years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_tr.js.map
|
||||
12
libraries/dhtmlxgantt/locale/locale_ua.js
Normal file
12
libraries/dhtmlxgantt/locale/locale_ua.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale={date:{month_full:["Січень","Лютий","Березень","Квітень","Травень","Червень","Липень","Серпень","Вересень","Жовтень","Листопад","Грудень"],month_short:["Січ","Лют","Бер","Кві","Тра","Чер","Лип","Сер","Вер","Жов","Лис","Гру"],day_full:["Неділя","Понеділок","Вівторок","Середа","Четвер","П'ятниця","Субота"],day_short:["Нед","Пон","Вів","Сер","Чет","Птн","Суб"]},labels:{dhx_cal_today_button:"Сьогодні",day_tab:"День",week_tab:"Тиждень",month_tab:"Місяць",new_event:"Нова подія",icon_save:"Зберегти",
|
||||
icon_cancel:"Відміна",icon_details:"Деталі",icon_edit:"Редагувати",icon_delete:"Вилучити",confirm_closing:"",confirm_deleting:"Подія вилучиться назавжди. Ви впевнені?",section_description:"Опис",section_time:"Часовий проміжок",section_type:"Тип",column_text:"Task name",column_start_date:"Start time",column_duration:"Duration",column_add:"",link:"Link",confirm_link_deleting:"will be deleted",link_start:" (start)",link_end:" (end)",type_task:"Task",type_project:"Project",type_milestone:"Milestone",
|
||||
minutes:"Minutes",hours:"Hours",days:"Days",weeks:"Week",months:"Months",years:"Years"}};
|
||||
//# sourceMappingURL=../sources/locale/locale_ua.js.map
|
||||
9
libraries/dhtmlxgantt/skins/dhtmlxgantt_broadway.css
Normal file
9
libraries/dhtmlxgantt/skins/dhtmlxgantt_broadway.css
Normal file
File diff suppressed because one or more lines are too long
9
libraries/dhtmlxgantt/skins/dhtmlxgantt_meadow.css
Normal file
9
libraries/dhtmlxgantt/skins/dhtmlxgantt_meadow.css
Normal file
File diff suppressed because one or more lines are too long
9
libraries/dhtmlxgantt/skins/dhtmlxgantt_skyblue.css
Normal file
9
libraries/dhtmlxgantt/skins/dhtmlxgantt_skyblue.css
Normal file
File diff suppressed because one or more lines are too long
9
libraries/dhtmlxgantt/skins/dhtmlxgantt_terrace.css
Normal file
9
libraries/dhtmlxgantt/skins/dhtmlxgantt_terrace.css
Normal file
File diff suppressed because one or more lines are too long
9424
libraries/dhtmlxgantt/sources/dhtmlxgantt.js
Normal file
9424
libraries/dhtmlxgantt/sources/dhtmlxgantt.js
Normal file
File diff suppressed because it is too large
Load diff
1
libraries/dhtmlxgantt/sources/dhtmlxgantt.js.map
Normal file
1
libraries/dhtmlxgantt/sources/dhtmlxgantt.js.map
Normal file
File diff suppressed because one or more lines are too long
119
libraries/dhtmlxgantt/sources/ext/dhtmlxgantt_marker.js
Normal file
119
libraries/dhtmlxgantt/sources/ext/dhtmlxgantt_marker.js
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
|
||||
if(!gantt._markers)
|
||||
gantt._markers = {};
|
||||
|
||||
gantt.config.show_markers = true;
|
||||
|
||||
gantt.attachEvent("onClear", function(){
|
||||
gantt._markers = {};
|
||||
});
|
||||
|
||||
gantt.attachEvent("onGanttReady", function(){
|
||||
var markerArea = document.createElement("div");
|
||||
markerArea.className = "gantt_marker_area";
|
||||
gantt.$task_data.appendChild(markerArea);
|
||||
gantt.$marker_area = markerArea;
|
||||
|
||||
gantt._markerRenderer = gantt._task_renderer("markers", render_marker, gantt.$marker_area, null);
|
||||
|
||||
function render_marker(marker){
|
||||
if(!gantt.config.show_markers)
|
||||
return false;
|
||||
|
||||
if(!marker.start_date)
|
||||
return false;
|
||||
|
||||
var state = gantt.getState();
|
||||
if(+marker.start_date > +state.max_date)
|
||||
return;
|
||||
if(+marker.end_date && +marker.end_date < +state.min_date || +marker.start_date < +state.min_date)
|
||||
return;
|
||||
|
||||
var div = document.createElement("div");
|
||||
|
||||
div.setAttribute("marker_id", marker.id);
|
||||
|
||||
var css = "gantt_marker";
|
||||
if(gantt.templates.marker_class)
|
||||
css += " " + gantt.templates.marker_class(marker);
|
||||
|
||||
if(marker.css){
|
||||
css += " " + marker.css;
|
||||
}
|
||||
|
||||
if(marker.title){
|
||||
div.title = marker.title;
|
||||
}
|
||||
div.className = css;
|
||||
|
||||
var start = gantt.posFromDate(marker.start_date);
|
||||
div.style.left = start + "px";
|
||||
div.style.height = Math.max(gantt._y_from_ind(gantt._order.length), 0) + "px";
|
||||
if(marker.end_date){
|
||||
var end = gantt.posFromDate(marker.end_date);
|
||||
div.style.width = Math.max((end - start), 0) + "px";
|
||||
|
||||
}
|
||||
|
||||
if(marker.text){
|
||||
div.innerHTML = "<div class='gantt_marker_content' >" + marker.text + "</div>";
|
||||
}
|
||||
|
||||
return div;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
gantt.attachEvent("onDataRender", function(){
|
||||
gantt.renderMarkers();
|
||||
});
|
||||
|
||||
gantt.getMarker = function(id){
|
||||
if(!this._markers) return null;
|
||||
|
||||
return this._markers[id];
|
||||
};
|
||||
|
||||
gantt.addMarker = function(marker){
|
||||
marker.id = marker.id || dhtmlx.uid();
|
||||
|
||||
this._markers[marker.id] = marker;
|
||||
|
||||
return marker.id;
|
||||
};
|
||||
|
||||
gantt.deleteMarker = function(id){
|
||||
if(!this._markers || !this._markers[id])
|
||||
return false;
|
||||
|
||||
delete this._markers[id];
|
||||
return true;
|
||||
};
|
||||
gantt.updateMarker = function(id){
|
||||
if(this._markerRenderer)
|
||||
this._markerRenderer.render_item(id);
|
||||
};
|
||||
gantt.renderMarkers = function(){
|
||||
if(!this._markers)
|
||||
return false;
|
||||
|
||||
if(!this._markerRenderer)
|
||||
return false;
|
||||
|
||||
var to_render = [];
|
||||
|
||||
for(var id in this._markers)
|
||||
to_render.push(this._markers[id]);
|
||||
|
||||
this._markerRenderer.render_items(to_render);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"dhtmlxgantt_marker.js","sources":["dhtmlxgantt_marker.js"],"names":["gantt","_markers","config","show_markers","attachEvent","render_marker","marker","start_date","state","getState","max_date","end_date","min_date","div","document","createElement","setAttribute","id","css","templates","marker_class","title","className","start","posFromDate","style","left","height","Math","max","_y_from_ind","_order","length","end","width","text","innerHTML","markerArea","$task_data","appendChild","$marker_area","_markerRenderer","_task_renderer","renderMarkers","getMarker","this","addMarker","dhtmlx","uid","deleteMarker","updateMarker","render_item","to_render","push","render_items"],"mappings":";;;;;;;;AASIA,MAAMC,WACTD,MAAMC,aAEPD,MAAME,OAAOC,cAAe,EAE5BH,MAAMI,YAAY,UAAW,WAC5BJ,MAAMC,cAGPD,MAAMI,YAAY,eAAgB,WAQjC,QAASC,GAAcC,GACtB,IAAIN,MAAME,OAAOC,aAChB,OAAO,CAER,KAAIG,EAAOC,WACV,OAAO,CAER,IAAIC,GAAQR,MAAMS,UAClB,OAAIH,EAAOC,YAAcC,EAAME,WAE3BJ,EAAOK,WAAaL,EAAOK,UAAYH,EAAMI,WAAaN,EAAOC,YAAcC,EAAMI,UAAzF,CAGA,GAAIC,GAAMC,SAASC,cAAc,MAEjCF,GAAIG,aAAa,YAAaV,EAAOW,GAErC,IAAIC,GAAM,cACPlB,OAAMmB,UAAUC,eAClBF,GAAO,IAAMlB,MAAMmB,UAAUC,aAAad;AAExCA,EAAOY,MACTA,GAAO,IAAMZ,EAAOY,KAGlBZ,EAAOe,QACTR,EAAIQ,MAAQf,EAAOe,OAEpBR,EAAIS,UAAYJ,CAEhB,IAAIK,GAAQvB,MAAMwB,YAAYlB,EAAOC,WAGrC,IAFAM,EAAIY,MAAMC,KAAOH,EAAQ,KACzBV,EAAIY,MAAME,OAASC,KAAKC,IAAI7B,MAAM8B,YAAY9B,MAAM+B,OAAOC,QAAS,GAAK,KACtE1B,EAAOK,SAAS,CAClB,GAAIsB,GAAMjC,MAAMwB,YAAYlB,EAAOK,SACnCE,GAAIY,MAAMS,MAAQN,KAAKC,IAAKI,EAAMV,EAAQ,GAAK,KAQhD,MAJGjB,GAAO6B,OACTtB,EAAIuB,UAAY,sCAAwC9B,EAAO6B,KAAO,UAGhEtB,GAlDR,GAAIwB,GAAavB,SAASC,cAAc,MACxCsB,GAAWf,UAAY,oBACvBtB,MAAMsC,WAAWC,YAAYF,GAC7BrC,MAAMwC,aAAeH,EAErBrC,MAAMyC,gBAAkBzC,MAAM0C,eAAe,UAAWrC,EAAeL,MAAMwC,aAAc;;GAkD5FxC,MAAMI,YAAY,eAAgB,WACjCJ,MAAM2C,kBAGP3C,MAAM4C,UAAY,SAAS3B,GAC1B,MAAI4B,MAAK5C,SAEF4C,KAAK5C,SAASgB,GAFK,MAK3BjB,MAAM8C,UAAY,SAASxC,GAK1B,MAJAA,GAAOW,GAAKX,EAAOW,IAAM8B,OAAOC,MAEhCH,KAAK5C,SAASK,EAAOW,IAAMX,EAEpBA,EAAOW,IAGfjB,MAAMiD,aAAe,SAAShC,GAC7B,MAAI4B,MAAK5C,UAAa4C,KAAK5C,SAASgB,UAG7B4B,MAAK5C,SAASgB,IACd,IAHC,GAKTjB,MAAMkD,aAAe,SAASjC,GAC1B4B,KAAKJ,iBACPI,KAAKJ,gBAAgBU,YAAYlC,IAEnCjB,MAAM2C,cAAgB,WACrB,IAAIE,KAAK5C,SACR,OAAO,CAER,KAAI4C,KAAKJ,gBACR,OAAO;;AAER,GAAIW,KAEJ,KAAI,GAAInC,KAAM4B,MAAK5C,SAClBmD,EAAUC,KAAKR,KAAK5C,SAASgB,GAI9B,OAFA4B,MAAKJ,gBAAgBa,aAAaF,IAE3B"}
|
||||
241
libraries/dhtmlxgantt/sources/ext/dhtmlxgantt_multiselect.js
Normal file
241
libraries/dhtmlxgantt/sources/ext/dhtmlxgantt_multiselect.js
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.config.multiselect = true;
|
||||
gantt.config.multiselect_one_level = false;
|
||||
|
||||
gantt._multiselect = {
|
||||
selected: {},
|
||||
one_level: true,
|
||||
active: true,
|
||||
isActive: function(){
|
||||
this.update_state();
|
||||
return this.active;
|
||||
},
|
||||
update_state: function(){
|
||||
this.one_level = gantt.config.multiselect_one_level;
|
||||
var active = this.active;
|
||||
this.active = gantt.config.multiselect;
|
||||
if(this.active != active){
|
||||
this.reset();
|
||||
}
|
||||
},
|
||||
reset: function () {
|
||||
this.selected = {};
|
||||
},
|
||||
set_last_selected: function (id) {
|
||||
this.last_selected = id;
|
||||
},
|
||||
getLastSelected: function () {
|
||||
return this.last_selected ? this.last_selected : null;
|
||||
},
|
||||
select: function (id, e) {
|
||||
if(gantt.callEvent("onBeforeTaskMultiSelect", [id, true, e])){
|
||||
this.selected[id] = true;
|
||||
this.set_last_selected(id);
|
||||
gantt.callEvent("onTaskMultiSelect", [id, true, e]);
|
||||
}
|
||||
},
|
||||
toggle: function (id, e) {
|
||||
if(this.selected[id]){
|
||||
this.unselect(id, e);
|
||||
}else{
|
||||
this.select(id, e);
|
||||
}
|
||||
},
|
||||
unselect: function (id, e) {
|
||||
if(gantt.callEvent("onBeforeTaskMultiSelect", [id, false, e])){
|
||||
this.selected[id] = false;
|
||||
if(this.last_selected == id)
|
||||
this.last_selected = null;
|
||||
|
||||
gantt.callEvent("onTaskMultiSelect", [id, true, e]);
|
||||
}
|
||||
},
|
||||
isSelected: function (id) {
|
||||
return !!this.selected[id];
|
||||
},
|
||||
getSelected: function () {
|
||||
var res = [];
|
||||
for (var i in this.selected) {
|
||||
if (this.selected[i]) {
|
||||
res.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
res.sort(function(a, b){
|
||||
return gantt.calculateTaskLevel(gantt.getTask(a)) > gantt.calculateTaskLevel(gantt.getTask(b)) ? 1 : -1;
|
||||
});
|
||||
|
||||
return res;
|
||||
},
|
||||
forSelected: function (callback) {
|
||||
var selected = this.getSelected();
|
||||
for (var i = 0; i < selected.length; i++) {
|
||||
callback(selected[i]);
|
||||
}
|
||||
},
|
||||
is_same_level: function(id){
|
||||
if(!this.one_level)
|
||||
return true;
|
||||
var last = this.getLastSelected();
|
||||
if(!last)
|
||||
return true;
|
||||
|
||||
if(!(gantt.isTaskExists(last) && gantt.isTaskExists(id)))
|
||||
return true;
|
||||
|
||||
return !!(gantt.calculateTaskLevel(gantt.getTask(last)) == gantt.calculateTaskLevel(gantt.getTask(id)));
|
||||
},
|
||||
_after_select: function(target){
|
||||
gantt.refreshTask(target);
|
||||
},
|
||||
_do_selection: function(e) {
|
||||
/* add onclick handler to gantt container, hook up multiselection */
|
||||
if(!this.isActive())
|
||||
return true;
|
||||
var target_ev = gantt.locate(e);
|
||||
var selected = this.getSelected();
|
||||
if (!target_ev)
|
||||
return true;
|
||||
|
||||
if(!gantt.callEvent("onBeforeMultiSelect", [e])){
|
||||
return true;
|
||||
}
|
||||
|
||||
if (e.ctrlKey) {
|
||||
if (target_ev) {
|
||||
this.toggle(target_ev, e);
|
||||
this._after_select(target_ev);
|
||||
}
|
||||
} else if (e.shiftKey && selected.length) {
|
||||
var last = this.getLastSelected();
|
||||
if (!last)
|
||||
last = selected[selected.length - 1];
|
||||
if (target_ev && last != target_ev) {
|
||||
var last_si = gantt.getGlobalTaskIndex(last);
|
||||
var cur_si = gantt.getGlobalTaskIndex(target_ev);
|
||||
var tmp = target_ev;
|
||||
while (gantt.getGlobalTaskIndex(tmp) != last_si) {
|
||||
this.select(tmp);
|
||||
this._after_select(tmp);
|
||||
tmp = (last_si > cur_si) ? gantt.getNext(tmp) : gantt.getPrev(tmp);
|
||||
}
|
||||
this.forSelected(dhtmlx.bind(function (task_id) {
|
||||
var index = gantt.getGlobalTaskIndex(task_id);
|
||||
if ((index > last_si && index > cur_si) || (index < last_si && index < cur_si)) {
|
||||
this.unselect(task_id);
|
||||
gantt.refreshTask(task_id);
|
||||
}
|
||||
}, this));
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
this.forSelected(dhtmlx.bind(function (task_id) {
|
||||
if (task_id != target_ev) {
|
||||
this.unselect(task_id);
|
||||
gantt.refreshTask(task_id);
|
||||
}
|
||||
}, this));
|
||||
if (!this.isSelected(target_ev)) {
|
||||
|
||||
this.select(target_ev);
|
||||
this._after_select(target_ev);
|
||||
}
|
||||
}
|
||||
|
||||
if(!this.isSelected(target_ev)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
(function(){
|
||||
var old_selectTask = gantt.selectTask;
|
||||
gantt.selectTask = function(id){
|
||||
var res = old_selectTask.call(this, id);
|
||||
if(this.config.multiselect)
|
||||
this._multiselect.select(id);
|
||||
|
||||
return res;
|
||||
};
|
||||
var old_unselectTask = gantt.unselectTask;
|
||||
gantt.unselectTask = function(id){
|
||||
var res = old_unselectTask.call(this, id);
|
||||
if(this.config.multiselect)
|
||||
this._multiselect.unselect(id);
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
gantt.toggleTaskSelection = function(id){
|
||||
if(this.config.multiselect)
|
||||
this._multiselect.toggle(id);
|
||||
};
|
||||
gantt.getSelectedTasks = function(){
|
||||
return this._multiselect.getSelected();
|
||||
};
|
||||
gantt.eachSelectedTask = function(callback){
|
||||
return this._multiselect.forSelected(callback);
|
||||
};
|
||||
gantt.isSelectedTask = function(id){
|
||||
return this._multiselect.isSelected(id);
|
||||
};
|
||||
gantt.getLastSelectedTask = function(){
|
||||
return this._multiselect.getLastSelected();
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
gantt.attachEvent("onTaskIdChange", function (id, new_id) {
|
||||
var multiselect = gantt._multiselect;
|
||||
if(!multiselect.isActive())
|
||||
return true;
|
||||
|
||||
if (gantt.isSelectedTask(id)) {
|
||||
multiselect.unselect(id, null);
|
||||
multiselect.select(new_id, null);
|
||||
gantt.refreshTask(new_id);
|
||||
}
|
||||
});
|
||||
|
||||
gantt.attachEvent("onAfterTaskDelete", function (id, item) {
|
||||
var multiselect = gantt._multiselect;
|
||||
if(!multiselect.isActive())
|
||||
return true;
|
||||
|
||||
if (multiselect.selected[id])
|
||||
multiselect.unselect(id, null);
|
||||
|
||||
multiselect.forSelected(function (task_id) {
|
||||
if (!gantt.isTaskExists(task_id))
|
||||
multiselect.unselect(task_id, null);
|
||||
});
|
||||
});
|
||||
|
||||
gantt.attachEvent("onBeforeTaskMultiSelect", function(id, select, e){
|
||||
var multiselect = gantt._multiselect;
|
||||
if(select && multiselect.isActive()){
|
||||
return multiselect.is_same_level(id);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
gantt.attachEvent("onTaskClick", function(id, e){
|
||||
var res = gantt._multiselect._do_selection(e);
|
||||
gantt.callEvent("onMultiSelect", [e]);
|
||||
return res;
|
||||
});
|
||||
gantt.attachEvent("onEmptyClick", function (e){
|
||||
gantt._multiselect._do_selection(e);
|
||||
gantt.callEvent("onMultiSelect", [e]);
|
||||
return true;
|
||||
});
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"dhtmlxgantt_multiselect.js","sources":["dhtmlxgantt_multiselect.js"],"names":["gantt","config","multiselect","multiselect_one_level","_multiselect","selected","one_level","active","isActive","this","update_state","reset","set_last_selected","id","last_selected","getLastSelected","select","e","callEvent","toggle","unselect","isSelected","getSelected","res","i","push","sort","a","b","calculateTaskLevel","getTask","forSelected","callback","length","is_same_level","last","isTaskExists","_after_select","target","refreshTask","_do_selection","target_ev","locate","ctrlKey","shiftKey","last_si","getGlobalTaskIndex","cur_si","tmp","getNext","getPrev","dhtmlx","bind","task_id","index","old_selectTask","selectTask","call","old_unselectTask","unselectTask","toggleTaskSelection","getSelectedTasks","eachSelectedTask","isSelectedTask","getLastSelectedTask","attachEvent","new_id"],"mappings":";;;;;;;;AAQAA,MAAMC,OAAOC,aAAc,EAC3BF,MAAMC,OAAOE,uBAAwB,EAErCH,MAAMI,cACLC,YACAC,WAAW,EACXC,QAAQ,EACRC,SAAU,WAET,MADAC,MAAKC,eACED,KAAKF,QAEbG,aAAc,WACbD,KAAKH,UAAYN,MAAMC,OAAOE,qBAC9B,IAAII,GAASE,KAAKF,MAClBE,MAAKF,OAASP,MAAMC,OAAOC,YACxBO,KAAKF,QAAUA,GACjBE,KAAKE,SAGPA,MAAO,WACNF,KAAKJ,aAENO,kBAAmB,SAAUC,GAC5BJ,KAAKK,cAAgBD,GAEtBE,gBAAiB,WAChB,MAAON,MAAKK,cAAgBL,KAAKK,cAAgB;;EAElDE,OAAQ,SAAUH,EAAII,GAClBjB,MAAMkB,UAAU,2BAA4BL,GAAI,EAAMI,MACxDR,KAAKJ,SAASQ,IAAM,EACpBJ,KAAKG,kBAAkBC,GACvBb,MAAMkB,UAAU,qBAAsBL,GAAI,EAAMI,MAGlDE,OAAQ,SAAUN,EAAII,GAClBR,KAAKJ,SAASQ,GAChBJ,KAAKW,SAASP,EAAII,GAElBR,KAAKO,OAAOH,EAAII,IAGlBG,SAAU,SAAUP,EAAII,GACpBjB,MAAMkB,UAAU,2BAA4BL,GAAI,EAAOI,MACzDR,KAAKJ,SAASQ,IAAM,EACjBJ,KAAKK,eAAiBD,IACxBJ,KAAKK,cAAgB,MAEtBd,MAAMkB,UAAU,qBAAsBL,GAAI,EAAMI,MAGlDI,WAAY,SAAUR,GACrB,QAASJ,KAAKJ,SAASQ,IAExBS,YAAa;AACZ,GAAIC,KACJ,KAAK,GAAIC,KAAKf,MAAKJ,SACdI,KAAKJ,SAASmB,IACjBD,EAAIE,KAAKD,EAQX,OAJAD,GAAIG,KAAK,SAASC,EAAGC,GACpB,MAAO5B,OAAM6B,mBAAmB7B,MAAM8B,QAAQH,IAAM3B,MAAM6B,mBAAmB7B,MAAM8B,QAAQF,IAAM,EAAI,KAG/FL,GAERQ,YAAa,SAAUC,GAEtB,IAAK,GADD3B,GAAWI,KAAKa,cACXE,EAAI,EAAGA,EAAInB,EAAS4B,OAAQT,IACpCQ,EAAS3B,EAASmB,KAGpBU,cAAe,SAASrB,GACvB,IAAIJ,KAAKH,UACR,OAAO,CACR,IAAI6B,GAAO1B,KAAKM,iBAChB,OAAIoB,IAGCnC,MAAMoC,aAAaD,IAASnC,MAAMoC,aAAavB,KAG1Cb,MAAM6B,mBAAmB7B,MAAM8B,QAAQK,KAAUnC,MAAM6B,mBAAmB7B,MAAM8B,QAAQjB,MAL1F;;EAOTwB,cAAe,SAASC,GACvBtC,MAAMuC,YAAYD,IAEnBE,cAAe,SAASvB,GAEvB,IAAIR,KAAKD,WACR,OAAO,CACR,IAAIiC,GAAYzC,MAAM0C,OAAOzB,GACzBZ,EAAWI,KAAKa,aACpB,KAAKmB,EACJ,OAAO,CAER,KAAIzC,MAAMkB,UAAU,uBAAwBD,IAC3C,OAAO,CAGR,IAAIA,EAAE0B,QACDF,IACHhC,KAAKU,OAAOsB,EAAWxB,GACvBR,KAAK4B,cAAcI,QAEd,IAAIxB,EAAE2B,UAAYvC,EAAS4B,OAAQ,CACzC,GAAIE,GAAO1B,KAAKM,iBAGhB,IAFKoB,IACJA,EAAO9B,EAASA,EAAS4B,OAAS,IAC/BQ,GAAaN,GAAQM,EAAW,CAInC,IAHA,GAAII,GAAU7C,MAAM8C,mBAAmBX,GACnCY,EAAS/C,MAAM8C,mBAAmBL,GAClCO,EAAMP,EACHzC,MAAM8C,mBAAmBE,IAAQH,GACvCpC,KAAKO,OAAOgC,GACZvC,KAAK4B,cAAcW;AACnBA,EAAOH,EAAUE,EAAU/C,MAAMiD,QAAQD,GAAOhD,MAAMkD,QAAQF,EAE/DvC,MAAKsB,YAAYoB,OAAOC,KAAK,SAAUC,GACtC,GAAIC,GAAQtD,MAAM8C,mBAAmBO,IAChCC,EAAQT,GAAWS,EAAQP,GAAoBF,EAARS,GAA2BP,EAARO,KAC9D7C,KAAKW,SAASiC,GACdrD,MAAMuC,YAAYc,KAEjB5C,YAKJA,MAAKsB,YAAYoB,OAAOC,KAAK,SAAUC,GAClCA,GAAWZ,IACdhC,KAAKW,SAASiC,GACdrD,MAAMuC,YAAYc,KAEjB5C,OACEA,KAAKY,WAAWoB,KAEpBhC,KAAKO,OAAOyB,GACZhC,KAAK4B,cAAcI,GAIrB,OAAIhC,MAAKY,WAAWoB,IAGb,GAFC,IAOV,WACC,GAAIc,GAAiBvD,MAAMwD,UAC3BxD,OAAMwD,WAAa,SAAS3C,GAC3B,GAAIU,GAAMgC,EAAeE,KAAKhD,KAAMI,EAIpC,OAHGJ,MAAKR,OAAOC,aACdO,KAAKL,aAAaY,OAAOH;AAEnBU,EAER,IAAImC,GAAmB1D,MAAM2D,YAC7B3D,OAAM2D,aAAe,SAAS9C,GAC7B,GAAIU,GAAMmC,EAAiBD,KAAKhD,KAAMI,EAItC,OAHGJ,MAAKR,OAAOC,aACdO,KAAKL,aAAagB,SAASP,GAErBU,GAGRvB,MAAM4D,oBAAsB,SAAS/C,GACjCJ,KAAKR,OAAOC,aACdO,KAAKL,aAAae,OAAON,IAE3Bb,MAAM6D,iBAAmB,WACxB,MAAOpD,MAAKL,aAAakB,eAE1BtB,MAAM8D,iBAAmB,SAAS9B,GACjC,MAAOvB,MAAKL,aAAa2B,YAAYC,IAEtChC,MAAM+D,eAAiB,SAASlD,GAC/B,MAAOJ,MAAKL,aAAaiB,WAAWR,IAErCb,MAAMgE,oBAAsB,WAC3B,MAAOvD,MAAKL,aAAaW;;KAK3Bf,MAAMiE,YAAY,iBAAkB,SAAUpD,EAAIqD,GACjD,GAAIhE,GAAcF,MAAMI,YACxB,OAAIF,GAAYM,gBAGZR,MAAM+D,eAAelD,KACxBX,EAAYkB,SAASP,EAAI,MACzBX,EAAYc,OAAOkD,EAAQ,MAC3BlE,MAAMuC,YAAY2B,MALX,IASTlE,MAAMiE,YAAY,oBAAqB,SAAUpD,GAChD,GAAIX,GAAcF,MAAMI,YACxB,OAAIF,GAAYM,YAGZN,EAAYG,SAASQ,IACxBX,EAAYkB,SAASP,EAAI,UAE1BX,GAAY6B,YAAY,SAAUsB,GAC5BrD,MAAMoC,aAAaiB,IACvBnD,EAAYkB,SAASiC,EAAS,UAPxB,IAWTrD,MAAMiE,YAAY,0BAA2B,SAASpD,EAAIG,GACzD,GAAId,GAAcF,MAAMI,YACxB,OAAGY,IAAUd,EAAYM,WACjBN,EAAYgC,cAAcrB,IAE3B;;GAGRb,MAAMiE,YAAY,cAAe,SAASpD,EAAII,GAC7C,GAAIM,GAAMvB,MAAMI,aAAaoC,cAAcvB,EAE3C,OADAjB,OAAMkB,UAAU,iBAAkBD,IAC3BM,IAERvB,MAAMiE,YAAY,eAAgB,SAAUhD,GAG3C,MAFAjB,OAAMI,aAAaoC,cAAcvB,GACjCjB,MAAMkB,UAAU,iBAAkBD,KAC3B"}
|
||||
218
libraries/dhtmlxgantt/sources/ext/dhtmlxgantt_quick_info.js
Normal file
218
libraries/dhtmlxgantt/sources/ext/dhtmlxgantt_quick_info.js
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.config.quickinfo_buttons = ["icon_delete","icon_edit"];
|
||||
gantt.config.quick_info_detached = true;
|
||||
gantt.config.show_quick_info = true;
|
||||
|
||||
gantt.attachEvent("onTaskClick", function(id){
|
||||
gantt.showQuickInfo(id);
|
||||
return true;
|
||||
});
|
||||
|
||||
(function(){
|
||||
var events = ["onEmptyClick", "onViewChange", "onLightbox", "onBeforeTaskDelete", "onBeforeDrag"];
|
||||
var hiding_function = function(){
|
||||
gantt._hideQuickInfo();
|
||||
return true;
|
||||
};
|
||||
for (var i=0; i<events.length; i++)
|
||||
gantt.attachEvent(events[i], hiding_function);
|
||||
})();
|
||||
|
||||
gantt.templates.quick_info_title = function(start, end, ev){ return ev.text.substr(0,50); };
|
||||
gantt.templates.quick_info_content = function(start, end, ev){ return ev.details || ev.text; };
|
||||
gantt.templates.quick_info_date = function(start, end, ev){
|
||||
return gantt.templates.task_time(start, end, ev);
|
||||
};
|
||||
gantt.templates.quick_info_class = function(start, end, task){ return ""; };
|
||||
|
||||
gantt.showQuickInfo = function(id){
|
||||
if (id == this._quick_info_box_id || !this.config.show_quick_info) return;
|
||||
this.hideQuickInfo(true);
|
||||
|
||||
var pos = this._get_event_counter_part(id);
|
||||
|
||||
if (pos){
|
||||
this._quick_info_box = this._init_quick_info(pos, id);
|
||||
|
||||
this._quick_info_box.className = gantt._prepare_quick_info_classname(id);
|
||||
|
||||
this._fill_quick_data(id);
|
||||
this._show_quick_info(pos);
|
||||
}
|
||||
};
|
||||
gantt._hideQuickInfo = function(){
|
||||
gantt.hideQuickInfo();
|
||||
};
|
||||
gantt.hideQuickInfo = function(forced){
|
||||
var qi = this._quick_info_box;
|
||||
this._quick_info_box_id = 0;
|
||||
|
||||
if (qi && qi.parentNode){
|
||||
if (gantt.config.quick_info_detached)
|
||||
return qi.parentNode.removeChild(qi);
|
||||
|
||||
|
||||
qi.className += " gantt_qi_hidden";
|
||||
if (qi.style.right == "auto")
|
||||
qi.style.left = "-350px";
|
||||
else
|
||||
qi.style.right = "-350px";
|
||||
|
||||
if (forced)
|
||||
qi.parentNode.removeChild(qi);
|
||||
}
|
||||
};
|
||||
dhtmlxEvent(window, "keydown", function(e){
|
||||
if (e.keyCode == 27)
|
||||
gantt.hideQuickInfo();
|
||||
});
|
||||
|
||||
gantt._show_quick_info = function(pos){
|
||||
var qi = gantt._quick_info_box;
|
||||
|
||||
if (gantt.config.quick_info_detached){
|
||||
if (!qi.parentNode ||
|
||||
qi.parentNode.nodeName.toLowerCase() == "#document-fragment")//IE8
|
||||
gantt.$task_data.appendChild(qi);
|
||||
var width = qi.offsetWidth;
|
||||
var height = qi.offsetHeight;
|
||||
|
||||
var scrolls = this.getScrollState();
|
||||
var screen_width = this.$task.offsetWidth + scrolls.x - width;
|
||||
|
||||
qi.style.left = Math.min(Math.max(scrolls.x, pos.left - pos.dx*(width - pos.width)), screen_width) + "px";
|
||||
qi.style.top = pos.top - (pos.dy?height:-pos.height) - 25 + "px";
|
||||
} else {
|
||||
qi.style.top = 20 + "px";
|
||||
if (pos.dx == 1){
|
||||
qi.style.right = "auto";
|
||||
qi.style.left = "-300px";
|
||||
|
||||
setTimeout(function(){
|
||||
qi.style.left = "-10px";
|
||||
},1);
|
||||
} else {
|
||||
qi.style.left = "auto";
|
||||
qi.style.right = "-300px";
|
||||
|
||||
setTimeout(function(){
|
||||
qi.style.right = "-10px";
|
||||
},1);
|
||||
}
|
||||
qi.className += " gantt_qi_"+(pos.dx == 1 ? "left" : "right");
|
||||
gantt._obj.appendChild(qi);
|
||||
}
|
||||
};
|
||||
gantt._prepare_quick_info_classname = function(id){
|
||||
var task = gantt.getTask(id);
|
||||
|
||||
var css = "gantt_cal_quick_info",
|
||||
template = this.templates.quick_info_class(task.start_date, task.end_date, task);
|
||||
|
||||
if(template){
|
||||
css += " " + template;
|
||||
}
|
||||
return css;
|
||||
};
|
||||
|
||||
gantt._init_quick_info = function(pos, id){
|
||||
var task = gantt.getTask(id);
|
||||
if(typeof this._quick_info_readonly == "boolean"){
|
||||
if(this._is_readonly(task) !== this._quick_info_readonly){
|
||||
gantt.hideQuickInfo(true);
|
||||
this._quick_info_box = null;
|
||||
}
|
||||
}
|
||||
|
||||
this._quick_info_readonly = this._is_readonly(task);
|
||||
|
||||
if (!this._quick_info_box){
|
||||
var qi = this._quick_info_box = document.createElement("div");
|
||||
//title
|
||||
var html = "<div class=\"gantt_cal_qi_title\">" +
|
||||
"<div class=\"gantt_cal_qi_tcontent\"></div><div class=\"gantt_cal_qi_tdate\"></div>" +
|
||||
"</div>" +
|
||||
"<div class=\"gantt_cal_qi_content\"></div>";
|
||||
|
||||
//buttons
|
||||
html += "<div class=\"gantt_cal_qi_controls\">";
|
||||
var buttons = gantt.config.quickinfo_buttons;
|
||||
|
||||
var is_editor = {"icon_delete":true,"icon_edit":true};
|
||||
|
||||
for (var i = 0; i < buttons.length; i++){
|
||||
if(this._quick_info_readonly && is_editor[buttons[i]])
|
||||
continue;
|
||||
|
||||
html += "<div class=\"gantt_qi_big_icon "+buttons[i]+"\" title=\""+gantt.locale.labels[buttons[i]]+"\"><div class='gantt_menu_icon " + buttons[i] + "'></div><div>"+gantt.locale.labels[buttons[i]]+"</div></div>";
|
||||
}
|
||||
html += "</div>";
|
||||
|
||||
qi.innerHTML = html;
|
||||
dhtmlxEvent(qi, "click", function(ev){
|
||||
ev = ev || event;
|
||||
gantt._qi_button_click(ev.target || ev.srcElement);
|
||||
});
|
||||
if (gantt.config.quick_info_detached)
|
||||
dhtmlxEvent(gantt.$task_data, "scroll", function(){ gantt.hideQuickInfo(); });
|
||||
}
|
||||
|
||||
return this._quick_info_box;
|
||||
};
|
||||
|
||||
gantt._qi_button_click = function(node){
|
||||
var box = gantt._quick_info_box;
|
||||
if (!node || node == box) return;
|
||||
|
||||
var mask = node.className;
|
||||
if (mask.indexOf("_icon")!=-1){
|
||||
var id = gantt._quick_info_box_id;
|
||||
gantt.$click.buttons[mask.split(" ")[1].replace("icon_","")](id);
|
||||
} else
|
||||
gantt._qi_button_click(node.parentNode);
|
||||
};
|
||||
gantt._get_event_counter_part = function(id){
|
||||
var domEv = gantt.getTaskNode(id);
|
||||
var left = 0;
|
||||
var top = 0;
|
||||
|
||||
var node = domEv;
|
||||
while (node && node.className != "gantt_task"){
|
||||
left += node.offsetLeft;
|
||||
top += node.offsetTop;
|
||||
node = node.offsetParent;
|
||||
}
|
||||
var scroll = this.getScrollState();
|
||||
if(node){
|
||||
var dx = (left + domEv.offsetWidth/2) - scroll.x > (gantt._x/2) ? 1 : 0;
|
||||
var dy = (top + domEv.offsetHeight/2) - scroll.y > (gantt._y/2) ? 1 : 0;
|
||||
|
||||
return { left:left, top:top, dx:dx, dy:dy,
|
||||
width:domEv.offsetWidth, height:domEv.offsetHeight };
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
gantt._fill_quick_data = function(id){
|
||||
var ev = gantt.getTask(id);
|
||||
var qi = gantt._quick_info_box;
|
||||
|
||||
gantt._quick_info_box_id = id;
|
||||
|
||||
//title content
|
||||
var titleContent = qi.firstChild.firstChild;
|
||||
titleContent.innerHTML = gantt.templates.quick_info_title(ev.start_date, ev.end_date, ev);
|
||||
var titleDate = titleContent.nextSibling;
|
||||
titleDate.innerHTML = gantt.templates.quick_info_date(ev.start_date, ev.end_date, ev);
|
||||
|
||||
//main content
|
||||
var main = qi.firstChild.nextSibling;
|
||||
main.innerHTML = gantt.templates.quick_info_content(ev.start_date, ev.end_date, ev);
|
||||
};
|
||||
File diff suppressed because one or more lines are too long
172
libraries/dhtmlxgantt/sources/ext/dhtmlxgantt_tooltip.js
Normal file
172
libraries/dhtmlxgantt/sources/ext/dhtmlxgantt_tooltip.js
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt._tooltip = {};
|
||||
gantt._tooltip_class = "gantt_tooltip";
|
||||
gantt.config.tooltip_timeout = 30;//,
|
||||
gantt.config.tooltip_offset_y = 20;
|
||||
gantt.config.tooltip_offset_x = 10;//,
|
||||
// timeout_to_hide: 50,
|
||||
// delta_x: 15,
|
||||
// delta_y: -20
|
||||
|
||||
gantt._create_tooltip = function(){
|
||||
if (!this._tooltip_html){
|
||||
this._tooltip_html = document.createElement('div');
|
||||
this._tooltip_html.className = gantt._tooltip_class;
|
||||
}
|
||||
return this._tooltip_html;
|
||||
};
|
||||
|
||||
gantt._is_cursor_under_tooltip = function(mouse_pos, tooltip) {
|
||||
if(mouse_pos.x >= tooltip.pos.x && mouse_pos.x <= (tooltip.pos.x + tooltip.width)) return true;
|
||||
if(mouse_pos.y >= tooltip.pos.y && mouse_pos.y <= (tooltip.pos.y + tooltip.height)) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
gantt._show_tooltip = function(text, pos) {
|
||||
if (gantt.config.touch && !gantt.config.touch_tooltip) return;
|
||||
|
||||
var tip = this._create_tooltip();
|
||||
|
||||
tip.innerHTML = text;
|
||||
gantt.$task_data.appendChild(tip);
|
||||
|
||||
var width = tip.offsetWidth + 20;
|
||||
var height = tip.offsetHeight + 40;
|
||||
var max_height = this.$task.offsetHeight;
|
||||
var max_width = this.$task.offsetWidth;
|
||||
var scroll = this.getScrollState();
|
||||
|
||||
//pos.x += scroll.x;
|
||||
pos.y += scroll.y;
|
||||
|
||||
var mouse_pos = {
|
||||
x: pos.x,
|
||||
y: pos.y
|
||||
};
|
||||
|
||||
pos.x += (gantt.config.tooltip_offset_x*1 || 0);
|
||||
pos.y += (gantt.config.tooltip_offset_y*1 || 0);
|
||||
|
||||
pos.y = Math.min(Math.max(scroll.y, pos.y), scroll.y+max_height - height);
|
||||
pos.x = Math.min(Math.max(scroll.x, pos.x), scroll.x+max_width - width);
|
||||
|
||||
if (gantt._is_cursor_under_tooltip(mouse_pos, {pos: pos, width: width, height: height})) {
|
||||
if((mouse_pos.x+width) > (max_width + scroll.x)) pos.x = mouse_pos.x - (width - 20) - (gantt.config.tooltip_offset_x*1 || 0);
|
||||
if((mouse_pos.y+height) > (max_height + scroll.y)) pos.y = mouse_pos.y - (height - 40) - (gantt.config.tooltip_offset_y*1 || 0);
|
||||
}
|
||||
|
||||
tip.style.left = pos.x + "px";
|
||||
tip.style.top = pos.y + "px";
|
||||
};
|
||||
|
||||
gantt._hide_tooltip = function(){
|
||||
if (this._tooltip_html && this._tooltip_html.parentNode)
|
||||
this._tooltip_html.parentNode.removeChild(this._tooltip_html);
|
||||
this._tooltip_id = 0;
|
||||
};
|
||||
|
||||
gantt._is_tooltip = function(ev) {
|
||||
var node = ev.target || ev.srcElement;
|
||||
return gantt._is_node_child(node, function(node){
|
||||
return (node.className == this._tooltip_class);
|
||||
});
|
||||
};
|
||||
|
||||
gantt._is_task_line = function(ev){
|
||||
var node = ev.target || ev.srcElement;
|
||||
return gantt._is_node_child(node, function(node){
|
||||
return (node == this.$task_data);
|
||||
});
|
||||
};
|
||||
|
||||
gantt._is_node_child = function(node, condition){
|
||||
var res = false;
|
||||
while (node && !res) {
|
||||
res = condition.call(gantt, node);
|
||||
node = node.parentNode;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
gantt._tooltip_pos = function(ev) {
|
||||
if (ev.pageX || ev.pageY)
|
||||
var pos = {x:ev.pageX, y:ev.pageY};
|
||||
|
||||
var d = _isIE ? document.documentElement : document.body;
|
||||
var pos = {
|
||||
x:ev.clientX + d.scrollLeft - d.clientLeft,
|
||||
y:ev.clientY + d.scrollTop - d.clientTop
|
||||
};
|
||||
|
||||
var box = gantt._get_position(gantt.$task_data);
|
||||
pos.x = pos.x - box.x;
|
||||
pos.y = pos.y - box.y;
|
||||
return pos;
|
||||
};
|
||||
|
||||
gantt.attachEvent("onMouseMove", function(event_id, ev) { // (gantt event_id, browser event)
|
||||
if(this.config.tooltip_timeout){
|
||||
//making events survive timeout in ie
|
||||
if(document.createEventObject && !document.createEvent)
|
||||
ev = document.createEventObject(ev);
|
||||
|
||||
var delay = this.config.tooltip_timeout;
|
||||
|
||||
if(this._tooltip_id && !event_id){
|
||||
if(!isNaN(this.config.tooltip_hide_timeout)){
|
||||
delay = this.config.tooltip_hide_timeout;
|
||||
}
|
||||
}
|
||||
|
||||
clearTimeout(gantt._tooltip_ev_timer);
|
||||
gantt._tooltip_ev_timer = setTimeout(function(){
|
||||
gantt._init_tooltip(event_id, ev);
|
||||
}, delay);
|
||||
|
||||
}else{
|
||||
gantt._init_tooltip(event_id, ev);
|
||||
}
|
||||
});
|
||||
gantt._init_tooltip = function(event_id, ev){
|
||||
if (this._is_tooltip(ev)) return;
|
||||
if (event_id == this._tooltip_id && !this._is_task_line(ev)) return;
|
||||
if (!event_id)
|
||||
return this._hide_tooltip();
|
||||
|
||||
this._tooltip_id = event_id;
|
||||
|
||||
var task = this.getTask(event_id);
|
||||
var text = this.templates.tooltip_text(task.start_date, task.end_date, task);
|
||||
if (!text){
|
||||
this._hide_tooltip();
|
||||
return;
|
||||
}
|
||||
this._show_tooltip(text, this._tooltip_pos(ev));
|
||||
};
|
||||
gantt.attachEvent("onMouseLeave", function(ev){
|
||||
if (gantt._is_tooltip(ev)) return;
|
||||
this._hide_tooltip();
|
||||
});
|
||||
|
||||
// gantt.attachEvent("onBeforeDrag", function() {
|
||||
// gantt._tooltip.hide();
|
||||
// return true;
|
||||
// });
|
||||
// gantt.attachEvent("onEventDeleted", function() {
|
||||
// gantt._tooltip.hide();
|
||||
// return true;
|
||||
// });
|
||||
|
||||
|
||||
/* Could be redifined */
|
||||
gantt.templates.tooltip_date_format = gantt.date.date_to_str("%Y-%m-%d");
|
||||
gantt.templates.tooltip_text = function(start, end, event) {
|
||||
return "<b>Task:</b> " + event.text + "<br/><b>Start date:</b> " + gantt.templates.tooltip_date_format(start) + "<br/><b>End date:</b> " + gantt.templates.tooltip_date_format(end);
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"dhtmlxgantt_tooltip.js","sources":["dhtmlxgantt_tooltip.js"],"names":["gantt","_tooltip","_tooltip_class","config","tooltip_timeout","tooltip_offset_y","tooltip_offset_x","_create_tooltip","this","_tooltip_html","document","createElement","className","_is_cursor_under_tooltip","mouse_pos","tooltip","x","pos","width","y","height","_show_tooltip","text","touch","touch_tooltip","tip","innerHTML","$task_data","appendChild","offsetWidth","offsetHeight","max_height","$task","max_width","scroll","getScrollState","Math","min","max","style","left","top","_hide_tooltip","parentNode","removeChild","_tooltip_id","_is_tooltip","ev","node","target","srcElement","_is_node_child","_is_task_line","condition","res","call","_tooltip_pos","pageX","pageY","d","_isIE","documentElement","body","clientX","scrollLeft","clientLeft","clientY","scrollTop","clientTop","box","_get_position","attachEvent","event_id","createEventObject","createEvent","delay","isNaN","tooltip_hide_timeout","clearTimeout","_tooltip_ev_timer","setTimeout","_init_tooltip","task","getTask","templates","tooltip_text","start_date","end_date","tooltip_date_format","date","date_to_str","start","end","event"],"mappings":";;;;;;;;AAQAA,MAAMC,YACND,MAAME,eAAiB,gBACvBF,MAAMG,OAAOC,gBAAkB,GAC/BJ,MAAMG,OAAOE,iBAAmB,GAChCL,MAAMG,OAAOG,iBAAmB,GAKhCN,MAAMO,gBAAkB,WAKvB,MAJKC,MAAKC,gBACTD,KAAKC,cAAgBC,SAASC,cAAc,OAC5CH,KAAKC,cAAcG,UAAYZ,MAAME,gBAE/BM,KAAKC,eAGbT,MAAMa,yBAA2B,SAASC,EAAWC,GACpD,MAAGD,GAAUE,GAAKD,EAAQE,IAAID,GAAKF,EAAUE,GAAMD,EAAQE,IAAID,EAAID,EAAQG,OAAe,EACvFJ,EAAUK,GAAKJ,EAAQE,IAAIE,GAAKL,EAAUK,GAAMJ,EAAQE,IAAIE,EAAIJ,EAAQK,QAAgB,GACpF,GAGRpB,MAAMqB,cAAgB,SAASC,EAAML;AACpC,IAAIjB,MAAMG,OAAOoB,OAAUvB,MAAMG,OAAOqB,cAAxC,CAEA,GAAIC,GAAMjB,KAAKD,iBAEfkB,GAAIC,UAAYJ,EAChBtB,MAAM2B,WAAWC,YAAYH,EAE7B,IAAIP,GAAQO,EAAII,YAAc,GAC1BT,EAASK,EAAIK,aAAe,GAC5BC,EAAavB,KAAKwB,MAAMF,aACxBG,EAAYzB,KAAKwB,MAAMH,YACvBK,EAAS1B,KAAK2B,gBAGlBlB,GAAIE,GAAKe,EAAOf,CAEhB,IAAIL,IACHE,EAAGC,EAAID,EACPG,EAAGF,EAAIE,EAGRF,GAAID,GAAoC,EAA9BhB,MAAMG,OAAOG,kBAAsB,EAC7CW,EAAIE,GAAoC,EAA9BnB,MAAMG,OAAOE,kBAAsB,EAE7CY,EAAIE,EAAIiB,KAAKC,IAAID,KAAKE,IAAIJ,EAAOf,EAAGF,EAAIE,GAAIe,EAAOf,EAAEY,EAAaX,GAClEH,EAAID,EAAIoB,KAAKC,IAAID,KAAKE,IAAIJ,EAAOlB,EAAGC,EAAID,GAAIkB,EAAOlB,EAAEiB,EAAYf,GAE7DlB,MAAMa,yBAAyBC,GAAYG,IAAKA,EAAKC,MAAOA,EAAOE,OAAQA,MAC1EN,EAAUE,EAAEE,EAAUe,EAAYC,EAAOlB,IAAIC,EAAID,EAAIF,EAAUE,GAAKE,EAAQ,KAAqC,EAA9BlB,MAAMG,OAAOG,kBAAsB;AACtHQ,EAAUK,EAAEC,EAAWW,EAAaG,EAAOf,IAAIF,EAAIE,EAAIL,EAAUK,GAAKC,EAAS,KAAqC,EAA9BpB,MAAMG,OAAOE,kBAAsB,KAG9HoB,EAAIc,MAAMC,KAAOvB,EAAID,EAAI,KACzBS,EAAIc,MAAME,IAAOxB,EAAIE,EAAI,OAG1BnB,MAAM0C,cAAgB,WACjBlC,KAAKC,eAAiBD,KAAKC,cAAckC,YAC5CnC,KAAKC,cAAckC,WAAWC,YAAYpC,KAAKC,eAChDD,KAAKqC,YAAc,GAGpB7C,MAAM8C,YAAc,SAASC,GAC5B,GAAIC,GAAOD,EAAGE,QAAUF,EAAGG,UAC3B,OAAOlD,OAAMmD,eAAeH,EAAM,SAASA,GAC1C,MAAQA,GAAKpC,WAAaJ,KAAKN,kBAIjCF,MAAMoD,cAAgB,SAASL,GAC9B,GAAIC,GAAOD,EAAGE,QAAUF,EAAGG,UAC3B,OAAOlD,OAAMmD,eAAeH,EAAM,SAASA;AAC1C,MAAQA,IAAQxC,KAAKmB,cAIvB3B,MAAMmD,eAAiB,SAASH,EAAMK,GAErC,IADA,GAAIC,IAAM,EACHN,IAASM,GACfA,EAAMD,EAAUE,KAAKvD,MAAOgD,GAC5BA,EAAOA,EAAKL,UAEb,OAAOW,IAGRtD,MAAMwD,aAAe,SAAST,GAC7B,GAAIA,EAAGU,OAASV,EAAGW,MAClB,GAAIzC,IAAOD,EAAE+B,EAAGU,MAAOtC,EAAE4B,EAAGW,MAE7B,IAAIC,GAAIC,MAAQlD,SAASmD,gBAAkBnD,SAASoD,KAChD7C,GACHD,EAAE+B,EAAGgB,QAAUJ,EAAEK,WAAaL,EAAEM,WAChC9C,EAAE4B,EAAGmB,QAAUP,EAAEQ,UAAYR,EAAES,WAG5BC,EAAMrE,MAAMsE,cAActE,MAAM2B,WAGpC,OAFAV,GAAID,EAAIC,EAAID,EAAIqD,EAAIrD,EACpBC,EAAIE,EAAIF,EAAIE,EAAIkD,EAAIlD,EACbF,GAGRjB,MAAMuE,YAAY,cAAe,SAASC,EAAUzB,GACnD,GAAGvC,KAAKL,OAAOC,gBAAgB,CAE3BM,SAAS+D,oBAAsB/D,SAASgE,cAC1C3B,EAAKrC,SAAS+D,kBAAkB1B;;AAEjC,GAAI4B,GAAQnE,KAAKL,OAAOC,eAErBI,MAAKqC,cAAgB2B,IACnBI,MAAMpE,KAAKL,OAAO0E,wBACrBF,EAAQnE,KAAKL,OAAO0E,uBAItBC,aAAa9E,MAAM+E,mBACnB/E,MAAM+E,kBAAoBC,WAAW,WACpChF,MAAMiF,cAAcT,EAAUzB,IAC5B4B,OAGH3E,OAAMiF,cAAcT,EAAUzB,KAGhC/C,MAAMiF,cAAgB,SAAST,EAAUzB,GACxC,IAAIvC,KAAKsC,YAAYC,KACjByB,GAAYhE,KAAKqC,aAAgBrC,KAAK4C,cAAcL,IAAxD,CACA,IAAKyB,EACJ,MAAOhE,MAAKkC,eAEblC,MAAKqC,YAAc2B,CAEnB,IAAIU,GAAO1E,KAAK2E,QAAQX,GACpBlD,EAAOd,KAAK4E,UAAUC,aAAaH,EAAKI,WAAYJ,EAAKK,SAAUL;;AACvE,MAAK5D,OAILd,MAAKa,cAAcC,EAAMd,KAAKgD,aAAaT,QAH1CvC,MAAKkC,kBAKP1C,MAAMuE,YAAY,eAAgB,SAASxB,GACtC/C,MAAM8C,YAAYC,IACtBvC,KAAKkC,kBAcN1C,MAAMoF,UAAUI,oBAAsBxF,MAAMyF,KAAKC,YAAY,YAC7D1F,MAAMoF,UAAUC,aAAe,SAASM,EAAOC,EAAKC,GACnD,MAAO,gBAAkBA,EAAMvE,KAAO,2BAA6BtB,MAAMoF,UAAUI,oBAAoBG,GAAS,yBAA2B3F,MAAMoF,UAAUI,oBAAoBI"}
|
||||
54
libraries/dhtmlxgantt/sources/locale/locale.js
Normal file
54
libraries/dhtmlxgantt/sources/locale/locale.js
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale = {
|
||||
date:{
|
||||
month_full:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
|
||||
month_short:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
|
||||
day_full:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
|
||||
day_short:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
|
||||
},
|
||||
labels:{
|
||||
new_task:"New task",
|
||||
icon_save:"Save",
|
||||
icon_cancel:"Cancel",
|
||||
icon_details:"Details",
|
||||
icon_edit:"Edit",
|
||||
icon_delete:"Delete",
|
||||
confirm_closing:"",//Your changes will be lost, are your sure ?
|
||||
confirm_deleting:"Task will be deleted permanently, are you sure?",
|
||||
section_description:"Description",
|
||||
section_time:"Time period",
|
||||
section_type:"Type",
|
||||
|
||||
/* grid columns */
|
||||
|
||||
column_text : "Task name",
|
||||
column_start_date : "Start time",
|
||||
column_duration : "Duration",
|
||||
column_add : "",
|
||||
|
||||
/* link confirmation */
|
||||
link: "Link",
|
||||
confirm_link_deleting:"will be deleted",
|
||||
link_start: " (start)",
|
||||
link_end: " (end)",
|
||||
|
||||
type_task: "Task",
|
||||
type_project: "Project",
|
||||
type_milestone: "Milestone",
|
||||
|
||||
minutes: "Minutes",
|
||||
hours: "Hours",
|
||||
days: "Days",
|
||||
weeks: "Week",
|
||||
months: "Months",
|
||||
years: "Years"
|
||||
}
|
||||
};
|
||||
|
||||
1
libraries/dhtmlxgantt/sources/locale/locale.js.map
Normal file
1
libraries/dhtmlxgantt/sources/locale/locale.js.map
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"locale.js","sources":["locale.js"],"names":["gantt","locale","date","month_full","month_short","day_full","day_short","labels","new_task","icon_save","icon_cancel","icon_details","icon_edit","icon_delete","confirm_closing","confirm_deleting","section_description","section_time","section_type","column_text","column_start_date","column_duration","column_add","link","confirm_link_deleting","link_start","link_end","type_task","type_project","type_milestone","minutes","hours","days","weeks","months","years"],"mappings":";;;;;;;;AAQAA,MAAMC,QACLC,MACCC,YAAY,UAAW,WAAY,QAAS,QAAS,MAAO,OAAQ,OAAQ,SAAU,YAAa,UAAW,WAAY,YAC1HC,aAAa,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,OAC1FC,UAAU,SAAU,SAAU,UAAW,YAAa,WAAY,SAAU,YAC5EC,WAAW,MAAO,MAAO,MAAO,MAAO,MAAO,MAAO,QAEtDC,QACCC,SAAS,WACTC,UAAU,OACVC,YAAY,SACZC,aAAa,UACbC,UAAU,OACVC,YAAY,SACZC,gBAAgB;AAChBC,iBAAiB,kDACXC,oBAAoB,cACpBC,aAAa,cACnBC,aAAa,OAIPC,YAAc,YACdC,kBAAoB,aACpBC,gBAAkB,WAClBC,WAAa,GAGnBC,KAAM,OACNC,sBAAsB,kBACtBC,WAAY,WACZC,SAAU,SAEVC,UAAW,OACXC,aAAc,UACdC,eAAgB,YAEVC,QAAS,UACTC,MAAO,QACPC,KAAM,OACNC,MAAO,OACPC,OAAQ,SACRC,MAAO"}
|
||||
57
libraries/dhtmlxgantt/sources/locale/locale_ar.js
Normal file
57
libraries/dhtmlxgantt/sources/locale/locale_ar.js
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale = {
|
||||
date: {
|
||||
month_full: ["كانون الثاني", "شباط", "آذار", "نيسان", "أيار", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول"],
|
||||
month_short: ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"],
|
||||
day_full: ["الأحد", "الأثنين", "ألثلاثاء", "الأربعاء", "ألحميس", "ألجمعة", "السبت"],
|
||||
day_short: ["احد", "اثنين", "ثلاثاء", "اربعاء", "خميس", "جمعة", "سبت"]
|
||||
},
|
||||
labels: {
|
||||
dhx_cal_today_button: "اليوم",
|
||||
day_tab: "يوم",
|
||||
week_tab: "أسبوع",
|
||||
month_tab: "شهر",
|
||||
new_event: "حدث جديد",
|
||||
icon_save: "اخزن",
|
||||
icon_cancel: "الغاء",
|
||||
icon_details: "تفاصيل",
|
||||
icon_edit: "تحرير",
|
||||
icon_delete: "حذف",
|
||||
confirm_closing: "التغييرات سوف تضيع, هل انت متأكد؟", //Your changes will be lost, are your sure ?
|
||||
confirm_deleting: "الحدث سيتم حذفها نهائيا ، هل أنت متأكد؟",
|
||||
section_description: "الوصف",
|
||||
section_time: "الفترة الزمنية",
|
||||
section_type:"Type",
|
||||
/* grid columns */
|
||||
|
||||
column_text : "Task name",
|
||||
column_start_date : "Start time",
|
||||
column_duration : "Duration",
|
||||
column_add : "",
|
||||
|
||||
/* link confirmation */
|
||||
link: "Link",
|
||||
confirm_link_deleting:"will be deleted",
|
||||
link_start: " (start)",
|
||||
link_end: " (end)",
|
||||
|
||||
type_task: "Task",
|
||||
type_project: "Project",
|
||||
type_milestone: "Milestone",
|
||||
|
||||
minutes: "Minutes",
|
||||
hours: "Hours",
|
||||
days: "Days",
|
||||
weeks: "Week",
|
||||
months: "Months",
|
||||
years: "Years"
|
||||
}
|
||||
};
|
||||
|
||||
1
libraries/dhtmlxgantt/sources/locale/locale_ar.js.map
Normal file
1
libraries/dhtmlxgantt/sources/locale/locale_ar.js.map
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"locale_ar.js","sources":["locale_ar.js"],"names":["gantt","locale","date","month_full","month_short","day_full","day_short","labels","dhx_cal_today_button","day_tab","week_tab","month_tab","new_event","icon_save","icon_cancel","icon_details","icon_edit","icon_delete","confirm_closing","confirm_deleting","section_description","section_time","section_type","column_text","column_start_date","column_duration","column_add","link","confirm_link_deleting","link_start","link_end","type_task","type_project","type_milestone","minutes","hours","days","weeks","months","years"],"mappings":";;;;;;;;AAQAA,MAAMC,QACLC,MACCC,YAAa,eAAgB,OAAQ,OAAQ,QAAS,OAAQ,SAAU,OAAQ,KAAM,QAAS,cAAe,eAAgB,eAC9HC,aAAc,QAAS,SAAU,OAAQ,QAAS,OAAQ,QAAS,QAAS,QAAS,SAAU,SAAU,SAAU,UACnHC,UAAW,QAAS,UAAW,WAAY,WAAY,SAAU,SAAU,SAC3EC,WAAY,MAAO,QAAS,SAAU,SAAU,OAAQ,OAAQ,QAEjEC,QACCC,qBAAsB,QACtBC,QAAS,MACTC,SAAU,QACVC,UAAW,MACXC,UAAW;AACXC,UAAW,OACXC,YAAa,QACbC,aAAc,SACdC,UAAW,QACXC,YAAa,MACbC,gBAAiB,oCACjBC,iBAAkB,0CAClBC,oBAAqB,QACrBC,aAAc,iBACdC,aAAa,OAGPC,YAAc,YACdC,kBAAoB,aACpBC,gBAAkB,WAClBC,WAAa,GAGnBC,KAAM,OACNC,sBAAsB,kBACtBC,WAAY,WACZC,SAAU,SAEVC,UAAW,OACXC,aAAc;AACdC,eAAgB,YAEVC,QAAS,UACTC,MAAO,QACPC,KAAM,OACNC,MAAO,OACPC,OAAQ,SACRC,MAAO"}
|
||||
58
libraries/dhtmlxgantt/sources/locale/locale_be.js
Normal file
58
libraries/dhtmlxgantt/sources/locale/locale_be.js
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
@license
|
||||
|
||||
dhtmlxGantt v.3.2.0 Stardard
|
||||
This software is covered by GPL license. You also can obtain Commercial or Enterprise license to use it in non-GPL project - please contact sales@dhtmlx.com. Usage without proper license is prohibited.
|
||||
|
||||
(c) Dinamenta, UAB.
|
||||
*/
|
||||
gantt.locale = {
|
||||
date: {
|
||||
month_full: ["Студзень", "Люты", "Сакавік", "Красавік", "Maй", "Чэрвень", "Ліпень", "Жнівень", "Верасень", "Кастрычнік", "Лістапад", "Снежань"],
|
||||
month_short: ["Студз", "Лют", "Сак", "Крас", "Maй", "Чэр", "Ліп", "Жнів", "Вер", "Каст", "Ліст", "Снеж"],
|
||||
day_full: [ "Нядзеля", "Панядзелак", "Аўторак", "Серада", "Чацвер", "Пятніца", "Субота"],
|
||||
day_short: ["Нд", "Пн", "Аўт", "Ср", "Чцв", "Пт", "Сб"]
|
||||
},
|
||||
labels: {
|
||||
dhx_cal_today_button: "Сёння",
|
||||
day_tab: "Дзень",
|
||||
week_tab: "Тыдзень",
|
||||
month_tab: "Месяц",
|
||||
new_event: "Новая падзея",
|
||||
icon_save: "Захаваць",
|
||||
icon_cancel: "Адмяніць",
|
||||
icon_details: "Дэталі",
|
||||
icon_edit: "Змяніць",
|
||||
icon_delete: "Выдаліць",
|
||||
confirm_closing: "", //Унесеныя змены будуць страчаны, працягнуць?
|
||||
confirm_deleting: "Падзея будзе выдалена незваротна, працягнуць?",
|
||||
section_description: "Апісанне",
|
||||
section_time: "Перыяд часу",
|
||||
section_type:"Тып",
|
||||
/* grid columns */
|
||||
|
||||
column_text : "Задача",
|
||||
column_start_date : "Пачатак",
|
||||
column_duration : "Працяг",
|
||||
column_add : "",
|
||||
|
||||
/* link confirmation */
|
||||
link: "Сувязь",
|
||||
confirm_link_deleting:"будзе выдалена",
|
||||
link_start: "(пачатак)",
|
||||
link_end: "(канец)",
|
||||
|
||||
type_task: "Task",
|
||||
type_project: "Project",
|
||||
type_milestone: "Milestone",
|
||||
|
||||
|
||||
minutes: "Хвiлiна",
|
||||
hours: "Гадзiна",
|
||||
days: "Дзень",
|
||||
weeks: "Тыдзень",
|
||||
months: "Месяц",
|
||||
years: "Год"
|
||||
}
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue