/** * save state for grid view of the browser * @return Ext.Direct responce */ public function saveGridViewState($p) { $rez = array('success' => true); $guid = false; /* incomming params example p: {params:{id:251, view:grid, path:1/114/101/251, query:null, start:0},…} params: {id:251, view:grid, path:1/114/101/251, query:null, start:0} id: 251 path: "1/114/101/251" query: null start: 0 view: "grid" state: {columns:{nid:{id:0, width:80, hidden:true, sortable:true}, name:{id:1, width:160, sortable:true},…}} columns: {nid:{id:0, width:80, hidden:true, sortable:true}, name:{id:1, width:160, sortable:true},…} case: {id:3, width:150, sortable:true} cdate: {id:8, width:120, hidden:true, sortable:true} cid: {id:6, width:200, hidden:true, sortable:true} date: {id:4, width:120, sortable:true} name: {id:1, width:160, sortable:true} nid: {id:0, width:80, hidden:true, sortable:true} oid: {id:7, width:200, sortable:true} path: {id:2, width:150, hidden:true, sortable:true} size: {id:5, width:80, sortable:true} udate: {id:9, width:120, hidden:true, sortable:true} */ if (!empty($p['params']['search']['template_id'])) { $guid = 'template_' . $p['params']['search']['template_id']; } else { $path = empty($p['params']['path']) ? $p['params']['id'] : $p['params']['path']; if (!empty($path)) { $treeNodeConfigs = Config::get('treeNodes', array('Dbnode' => array())); $treeNodeClasses = Path::getNodeClasses($treeNodeConfigs); $treeNodeGUIDConfigs = array(); foreach ($treeNodeClasses as $nodeClass) { $cfg = $nodeClass->getConfig(); $treeNodeGUIDConfigs[$cfg['guid']] = $cfg; } $nodesPath = Path::createNodesPath($path, $treeNodeGUIDConfigs); if (!empty($nodesPath)) { $lastNode = array_pop($nodesPath); $DCConfig = $lastNode->getNodeParam('DC'); $guid = empty($DCConfig['from']) ? 'default' : $DCConfig['from']; } } } if ($guid) { DB\dbQuery('INSERT INTO tree_user_config (guid, user_id, cfg) VALUES($1, $2, $3) ON DUPLICATE KEY UPDATE cfg = $3', array($guid, $_SESSION['user']['id'], Util\jsonEncode($p['state']))) or die(DB\dbQueryError()); } return $rez; }
/** * create an object * @param array $p params * @return json responce */ public function create($p) { $pid = empty($p['pid']) ? @$p['path'] : $p['pid']; if (empty($pid)) { throw new \Exception(L\get('Access_denied')); } if (empty($p['pid']) || !is_numeric($p['pid'])) { $p['pid'] = Path::detectRealTargetId($pid); } //security check moved inside objects class $template = \CB\Templates\SingletonCollection::getInstance()->getTemplate($p['template_id']); $templateData = $template->getData(); $object = $this->getCustomClassByType($templateData['type']); //prepare params if (empty($p['name'])) { $p['name'] = $template->getName(); } $p['name'] = $this->getAvailableName($p['pid'], $p['name']); $id = $object->create($p); Solr\Client::runCron(); $rez = $this->load(array('id' => $id)); $rez['data']['isNew'] = true; return $rez; }
/** * get the menu config for a given path or id * @param varchar | int $path path string or node id * @return [type] [description] */ public static function getMenuForPath($path) { $rez = ''; //get item path if id specified if (is_numeric($path)) { $tmp = \CB\Path::getPath($path); $path = '/' . $tmp['path']; } if (is_string($path)) { $path = explode('/', $path); } $path = array_reverse(array_filter($path, 'is_numeric')); $path = Util\toNumericArray($path); // get templates for each path elements $nodeTemplate = array(); $recs = DM\Tree::readByIds($path); foreach ($recs as $r) { $nodeTemplate[$r['id']] = $r['template_id']; } //get db menu into variable $menu = static::getMenuRules(); $ugids = isset($_SESSION['user']['groups']) ? $_SESSION['user']['groups'] : array(); $ugids[] = $_SESSION['user']['id']; // we have 3 main criterias for detecting needed menu: // - user_group_ids - records for specific users or groups // - node_ids // - template_ids // // we'll iterate the path from the end and detect the menu $lastWeight = 0; for ($i = 0; $i < sizeof($path); $i++) { //firstly we'll check if we find a menu row with id or template of the node foreach ($menu as $m) { $weight = 0; if (in_array($path[$i], $m['nids'])) { $weight += 50; } elseif (empty($m['nids'])) { $weight += 1; } else { //skip this record because it contain nids and not contain this node id continue; } if (in_array($nodeTemplate[$path[$i]], $m['ntids'])) { $weight += 50; } elseif (empty($m['ntids'])) { $weight += 1; } else { //skip this record because it has ntids specified and not contain this node template id continue; } if (empty($m['ugids'])) { $weight += 1; } else { $int = array_intersect($ugids, $m['ugids']); if (empty($int)) { continue; } else { $weight += 10; } } if ($weight > $lastWeight) { $lastWeight = $weight; $rez = $m['menu']; } } //if nid matched or template matched then dont iterate further if ($lastWeight > 50) { return $rez; } } return $rez; }
public function load($p) { $rez = array('success' => true, 'data' => array('html' => '<div class="msg">Please select a case ...</div>')); if (empty($p['path'])) { return $rez; } $this->params = $p; $this->pathProperties = Path::getPathProperties($p['path']); $pp =& $this->pathProperties; if (empty($pp['case_id'])) { return $rez; } /* define graph title */ $graphTitle = empty($pp['name']) ? 'Graph' : $pp['name']; $graphTitle = str_replace(array(' ', '.', '\'', '"', '-', '/', '\\', '~'), '_', $graphTitle); /* end of define graph title */ $solrNodes = $this->getGraphNodes($pp['case_id']); if (empty($solrNodes)) { return array('success' => true, 'data' => array('html' => '<div class="msg">Nothing to display.</div>')); } $graphNodes = $solrNodes; $this->prepareGraphNodes($graphNodes); $this->setGraphTimeline($graphNodes); $rez = ''; /* print graph timeline nodes */ $rez .= "{\n node [shape=plaintext, fontsize=7, fontcolor=\"gray\", tooltip=\"timeline\"];\n /* the time-line graph */ \n"; $rez .= 't' . implode(' -> t', array_keys($this->timeline)) . " [dir=none, color=\"gray\"];\n}\n"; for ($i = 0; $i < sizeof($this->timeline); $i++) { $rez .= 't' . $i . '[label="' . $this->timeline[$i] . '"];' . "\n"; } /* end of print graph timeline nodes */ /* align graph nodes to corresponding timeline node */ foreach ($graphNodes as $node) { $rez .= "\n{rank=same; " . $node['t'] . "; n" . $node['id'] . "; }"; } /* end of align graph nodes to corresponding timeline node */ /* defining nodes */ foreach ($graphNodes as $node) { /* check if its a composite node with left and/or right sides and replace it's label with corresponding nodes table */ $leftSide = ''; if (!empty($node['leftSideNodes'])) { foreach ($node['leftSideNodes'] as $subnode) { $leftSide .= '<td href="#' . $subnode['id'] . '"' . ' bgcolor="' . $subnode['bgcolor'] . '"' . ' PORT="n' . $subnode['id'] . '_' . $node['id'] . '"' . (empty($subnode[$this->hintField]) ? '' : ' tooltip="' . $subnode[$this->hintField] . '"') . ' valign="middle">' . $subnode[$this->labelField] . '</td>'; } } $rightSide = ''; if (!empty($node['rightSideNodes'])) { foreach ($node['rightSideNodes'] as $subnode) { $rightSide .= '<td href="#' . $subnode['id'] . '"' . ' bgcolor="' . $subnode['bgcolor'] . '"' . ' PORT="n' . $subnode['id'] . '_' . $node['id'] . '"' . (empty($subnode[$this->hintField]) ? '' : ' tooltip="' . $subnode[$this->hintField] . '"') . ' valign="middle">' . $subnode[$this->labelField] . '</td>'; } } if (!empty($leftSide) || !empty($rightSide)) { $node[$this->labelField] = '< <table border="0" cellborder="1" cellspacing="0" cellpadding="4" ' . 'style="border: 0 !important; border-collapse: collapse !important"><tr>' . $leftSide . '<td bgcolor="' . $this->colors['yellow'] . '"' . ' PORT="n' . $node['id'] . '"' . ' valign="middle"' . (empty($node[$this->hintField]) ?: ' tooltip="' . addslashes($node[$this->hintField]) . '"') . '>' . $node[$this->labelField] . '</td>' . $rightSide . '</tr></table> >'; } else { $node[$this->labelField] = '"' . addslashes($node[$this->labelField]) . '"'; } /* end of check if its a composite node with left and/or right sides and replace it's label with corresponding nodes table */ $rez .= "\n n" . $node['id'] . ' [shape="' . ($node['shape'] ? $node['shape'] : 'ellipse') . '"' . (empty($node['style']) ? '' : ', style="' . $node['style'] . '"') . (empty($node['fillcolor']) ? '' : ', fillcolor="' . $node['fillcolor'] . '"') . (isset($node['margin']) ? ', margin="' . $node['margin'] . '"' : '') . (isset($node['penwidth']) ? ', penwidth="' . $node['penwidth'] . '"' : '') . (empty($node[$this->hintField]) ? '' : ', tooltip="' . addslashes($node[$this->hintField]) . '"') . ', label=' . $node[$this->labelField] . ', URL="#' . $node['id'] . '"];'; $linkedNodeIds = $this->getNodeLinks($node['id']); foreach ($linkedNodeIds as $ln) { $rez .= "\n" . 'n' . $ln . ' -> n' . $node['id'] . ';'; } } // enclosing all nodes data in header and footer $rez = 'digraph "' . $graphTitle . '" { spline=false; node [margin="0.05,0.05", shape=plaintext, fontname="tahoma", fontsize=8, height=0.2, width=0.2]; edge [arrowsize=0.5, fontsize=7]; ranksep=0.25; nodesep=0.25; ' . $rez . "\n}"; /* save result to a temporary file for passing it to graphviz */ $t = tempnam(sys_get_temp_dir(), 'gv'); file_put_contents($t, $rez); //also store gv file in core files path for any case /* if parametter "d" is passed in GET, then save graph is requested. Generate png file and write it directly to output */ if (@$_GET['d'] == 1) { $cmd = "dot -Tpng -o" . $t . ".png " . $t; exec($cmd); header('Content-Type: image/png'); header('Content-Disposition: attachment; filename="' . date('Y-m-d') . ' - Граф дела ' . addslashes($graphTitle) . '.png"'); echo file_get_contents($t . '.png'); } else { //generate and return svg $cmd = "dot -Tsvg -o" . $t . ".svg " . $t; exec($cmd); $rez = file_get_contents($t . '.svg'); } /* delete temporary files */ unlink($t); unlink($t . '.svg'); /* end of delete temporary files */ return array('success' => true, 'data' => array('html' => $rez, 'nodes' => $solrNodes)); }
public function saveFile($p) { $incommingFilesDir = Config::get('incomming_files_dir'); $files = new Files(); /* clean previous unhandled uploads if any */ $a = $files->getUploadParams(); if ($a !== false && !empty($a['files'])) { @unlink($incommingFilesDir . $_SESSION['key']); $files->removeIncomingFiles($a['files']); } /* end of clean previous unhandled uploads if any */ $F =& $_FILES; if (empty($p['pid'])) { return array('success' => false, 'msg' => L\get('Error_uploading_file')); } $p['pid'] = Path::detectRealTargetId($p['pid']); if (empty($F)) { //update only file properties (no files were uploaded) return $files->updateFileProperties($p); } else { foreach ($F as $k => $v) { $F[$k]['name'] = Purify::filename(@$F[$k]['name']); } } if (!Objects::idExists($p['pid'])) { return array('success' => false, 'msg' => L\get('TargetFolderDoesNotExist')); } /*checking if there is no upload error (for any type of upload: single, multiple, archive) */ foreach ($F as $fn => $f) { if (!in_array($f['error'], array(UPLOAD_ERR_OK, UPLOAD_ERR_NO_FILE))) { return array('success' => false, 'msg' => L\get('Error_uploading_file') . ': ' . $f['error']); } } /* retreiving files list */ switch (@$p['uploadType']) { case 'archive': $archiveFiles = array(); foreach ($F as $fk => $f) { $files->extractUploadedArchive($F[$fk]); $archiveFiles = array_merge($archiveFiles, $F[$fk]); } $F = $archiveFiles; break; default: $files->moveUploadedFilesToIncomming($F) or die('cannot move file to incomming dir'); break; } $p['existentFilenames'] = $files->getExistentFilenames($F, $p['pid']); $p['files'] =& $F; if (!empty($p['existentFilenames'])) { //check if can write target file if (!Security::canWrite($p['existentFilenames'][0]['existentFileId'])) { return array('success' => false, 'msg' => L\get('Access_denied')); } // store current state serialized in a local file in incomming folder $files->saveUploadParams($p); if (!empty($p['response'])) { //it is supposed to work only for single files upload return $this->confirmUploadRequest($p); } $allow_new_version = false; foreach ($p['existentFilenames'] as $f) { $mfvc = Files::getMFVC($f['name']); if ($mfvc > 0) { $allow_new_version = true; } } $rez = array('success' => false, 'type' => 'filesexist', 'allow_new_version' => $allow_new_version, 'count' => sizeof($p['existentFilenames'])); if ($rez['count'] == 1) { $rez['msg'] = empty($p['existentFilenames'][0]['msg']) ? str_replace('{filename}', '"' . $p['existentFilenames'][0]['name'] . '"', L\get('FilenameExistsInTarget')) : $p['existentFilenames'][0]['msg']; //$rez['filename'] = $p['existentFilenames'][0]['name']; $rez['suggestedFilename'] = $p['existentFilenames'][0]['suggestedFilename']; } else { $rez['msg'] = L\get('SomeFilenamesExistsInTarget'); } return $rez; } else { //check if can write in target folder if (!Security::canWrite($p['pid'])) { return array('success' => false, 'msg' => L\get('Access_denied')); } } $files->storeFiles($p); //if everithing is ok then store files Solr\Client::runCron(); $rez = array('success' => true, 'data' => array('pid' => $p['pid'])); $files->attachPostUploadInfo($F, $rez); return $rez; }
/** * get the menu config for a given path or id * @param varchar | int $path path string or node id * @return [type] [description] */ public static function getMenuForPath($path) { $rez = ''; //get item path if id specified if (is_numeric($path)) { $tmp = \CB\Path::getPath($path); $path = '/' . $tmp['path']; } if (is_string($path)) { $path = explode('/', $path); } $path = array_reverse(array_filter($path, 'is_numeric')); $path = Util\toNumericArray($path); // get templates for each path elements $nodeTemplate = array(); $res = DB\dbQuery('SELECT id, template_id FROM tree WHERE id in (0' . implode(',', $path) . ')') or die(DB\dbQueryError()); while ($r = $res->fetch_assoc()) { $nodeTemplate[$r['id']] = $r['template_id']; } $res->close(); //get db menu into variable $menu = array(); $res = DB\dbQuery('SELECT node_ids `nids` ,node_template_ids `ntids` ,user_group_ids `ugids` ,menu FROM menu') or die(DB\dbQueryError()); while ($r = $res->fetch_assoc()) { $r['nids'] = Util\toNumericArray($r['nids']); $r['ntids'] = Util\toNumericArray($r['ntids']); $r['ugids'] = Util\toNumericArray($r['ugids']); $menu[] = $r; } $res->close(); $ugids = $_SESSION['user']['groups']; $ugids[] = $_SESSION['user']['id']; // we have 3 main criterias for detecting needed menu: // - user_group_ids - records for specific users or groups // - node_ids // - template_ids // // we'll iterate the path from the end and detect the menu $lastWeight = 0; for ($i = 0; $i < sizeof($path); $i++) { //firstly we'll check if we find a menu row with id or template of the node foreach ($menu as $m) { $weight = 0; if (in_array($path[$i], $m['nids'])) { $weight += 50; } elseif (empty($m['nids'])) { $weight += 1; } else { //skip this record because it contain nids and not contain this node id continue; } if (in_array($nodeTemplate[$path[$i]], $m['ntids'])) { $weight += 50; } elseif (empty($m['ntids'])) { $weight += 1; } else { //skip this record because it has ntids specified and not contain this node template id continue; } if (empty($m['ugids'])) { $weight += 1; } else { $int = array_intersect($ugids, $m['ugids']); if (empty($int)) { continue; } else { $weight += 10; } } if ($weight > $lastWeight) { $lastWeight = $weight; $rez = $m['menu']; } } //if nid matched or template matched then dont iterate further if ($lastWeight > 50) { return $rez; } } return $rez; }
/** * analize and adjust view config if needed * @param array $viewConfig * @param array $rp * @return array */ public function adjustViewConfig($viewConfig, &$rp) { if (empty($viewConfig)) { return array(); } $rez = $viewConfig; $cfg =& $this->config; if (!empty($cfg['views'][$rez['type']])) { $rez = array_merge($rez, $cfg['views'][$rez['type']]); } elseif ($rez['type'] == 'activityStream' && !empty($cfg['views']['stream'])) { $rez = array_merge($rez, $cfg['views']['stream']); } //dashboards extention check if (!empty($rez['extends'])) { $rez = Config::extend('dashboards', $rez); } switch ($rez['type']) { //backward compatibility check case 'pivot': case 'charts': if (!empty($cfg['stats'])) { $stats = array(); foreach ($cfg['stats'] as $item) { $stats[] = array('title' => Util\detectTitle($item), 'field' => $item['field']); } $rez['stats'] = $stats; } $rez['sort'] = null; //check renamed options if (isset($rez['chart_type']) && empty($rez['chartType'])) { $rez['chartType'] = $rez['chart_type']; unset($rez['chart_type']); } if (isset($rez['pivot_type']) && empty($rez['pivotType'])) { $rez['pivotType'] = $rez['pivot_type']; unset($rez['pivot_type']); } break; case 'dashboard': //analize dashboard items and merge referenced config if any if (empty($rez['items'])) { $rez['items'] = array(); } $this->subClasses = array(); $copyConfigProperties = ['title', 'cellCls', 'rowspan', 'colspan', 'width', 'height', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight']; foreach ($rez['items'] as $k => $v) { if (!empty($v['extends'])) { $rez['items'][$k] = Config::extend('treeNodes', $v); } $clsArr = Path::getNodeClasses($rez['items']); if (!empty($clsArr)) { $class = current($clsArr); if (isset($v['pid'])) { $class->id = $v['pid']; } $this->subClasses[$k] = $class; $path = array($class); $customRp = $rp; unset($customRp['userViewChange']); $vc = $class->getViewConfig($path, $customRp); $rez['items'][$k] = array_merge($vc, array_intersect_key($v, array_flip($copyConfigProperties))); } } break; default: // grid // if (!empty($cfg['view']['group'])) { // $rez['group'] = $cfg['view']['group']; // } } return $rez; }
/** * get objects acl list * @param $p client side request params with field config * @param boolean $inherited flag to include inherited rules also * @return array json responce */ public function getObjectAcl($p, $inherited = true) { $rez = array('success' => true, 'data' => array(), 'name' => ''); if (!is_numeric($p['id'])) { return $rez; } if (empty($this->internalAccessing) && !Security::canRead($p['id'])) { throw new \Exception(L\get('Access_denied')); } /* set object title, path and inheriting access ids path*/ $obj_ids = array(); $res = DB\dbQuery('SELECT ti.`path` ,t.name ,t.inherit_acl ,ts.`set` `obj_ids` FROM tree t JOIN tree_info ti ON t.id = ti.id LEFT JOIN tree_acl_security_sets ts ON ti.security_set_id = ts.id WHERE t.id = $1', $p['id']) or die(DB\dbQueryError()); if ($r = $res->fetch_assoc()) { $rez['path'] = Path::replaceCustomNames($r['path']); $rez['name'] = Path::replaceCustomNames($r['name']); $rez['inherit_acl'] = $r['inherit_acl']; $obj_ids = explode(',', $r['obj_ids']); } $res->close(); /* end of set object title and path*/ /* get the full set of access credentials(users and/or groups) including inherited from parents */ $lid = Config::get('user_language_index', 1); $res = DB\dbQuery('SELECT DISTINCT u.id ,u.`name` ,u.`first_name` ,u.`last_name` ,u.`system` ,u.`enabled` ,u.`type` ,u.`sex` FROM tree_acl a JOIN users_groups u ON a.user_group_id = u.id WHERE a.node_id ' . ($inherited ? ' in (0' . implode(',', $obj_ids) . ')' : ' = $1 ') . ' ORDER BY u.`type`, 2', $p['id']) or die(DB\dbQueryError()); while ($r = $res->fetch_assoc()) { $r['user_group_id'] = $r['id']; $r['name'] = User::getDisplayName($r); $r['iconCls'] = $r['type'] == 1 ? 'icon-users' : 'icon-user-' . $r['sex']; unset($r['sex']); $access = $this->getUserGroupAccessForObject($p['id'], $r['id']); $r['allow'] = implode(',', $access[0]); $r['deny'] = implode(',', $access[1]); $rez['data'][] = $r; } $res->close(); /* end of get the full set of access credentials(users and/or groups) including inherited from parents */ return $rez; }