public function getContentItems() { $p =& $this->requestParams; $folderTemplates = \CB\Config::get('folder_templates'); $p['fl'] = 'id,system,path,name,case,date,date_end,size,cid,oid,cdate,uid,udate,template_id,acl_count,cls,status,task_status,dstatus'; if (@$p['from'] == 'tree') { $p['templates'] = $folderTemplates; } if (is_numeric($this->lastNode->id)) { $p['pid'] = $pid; } $p['dstatus'] = 1; $p['fq'] = $this->fq; $s = new \CB\Search(); $rez = $s->query($p); if (!empty($rez['data'])) { for ($i = 0; $i < sizeof($rez['data']); $i++) { $d =& $rez['data'][$i]; $res = DB\dbQuery('SELECT cfg , (SELECT 1 FROM tree WHERE pid = $1' . (@$p['from'] == 'tree' ? ' AND `template_id` IN (0' . implode(',', $folderTemplates) . ')' : '') . ' LIMIT 1) has_childs FROM tree WHERE id = $1', $d['id']) or die(DB\dbQueryError()); if ($r = $res->fetch_assoc()) { $d['cfg'] = Util\toJSONArray($r['cfg']); $d['has_childs'] = !empty($r['has_childs']); } $res->close(); } } return $rez; }
/** * load all templates from database * @param boolean $reload reload even if already all loaded * @return void */ public function loadAll($reload = false) { //skip loading if already loaded and reload not true if ($this->loadedAll && !$reload) { return; } $this->reset(); /* collecting template_fields */ $template_fields = array(); $res = DB\dbQuery('SELECT ts.id ,ts.pid ,ts.template_id ,ts.name ,ts.l' . \CB\Config::get('user_language_index') . ' `title` ,ts.`type` ,ts.cfg ,ts.order ,ts.solr_column_name FROM templates_structure ts JOIN tree t on ts.id = t.id AND t.dstatus = 0') or die(DB\dbQueryError()); while ($r = $res->fetch_assoc()) { $template_id = $r['template_id']; unset($r['template_id']); $r['cfg'] = Util\toJSONArray($r['cfg']); $template_fields[$template_id][$r['id']] = $r; } $res->close(); /* loading templates */ $res = DB\dbQuery('SELECT t.id ,t.pid ,t.is_folder ,t.`type` ,t.name ,t.`order` ,t.`visible` ,t.iconCls ,t.default_field ,t.cfg ,t.title_template ,t.info_template ,o.data FROM templates t LEFT JOIN objects o ON t.id = o.id WHERE t.is_folder = 0') or die(DB\dbQueryError()); while ($r = $res->fetch_assoc()) { $r['cfg'] = Util\toJSONArray($r['cfg']); $r['data'] = Util\toJSONArray($r['data']); $r['fields'] = empty($template_fields[$r['id']]) ? array() : $template_fields[$r['id']]; /* store template in collection */ $this->templates[$r['id']] = new \CB\Objects\Template($r['id'], false); $this->templates[$r['id']]->setData($r); } $res->close(); $this->loadedAll = true; }
/** * function used by create method for creating custom data * @return void */ protected function createCustomData() { $p =& $this->data; $p['sys_data'] = Util\toJSONArray(@$p['sys_data']); $sd =& $p['sys_data']; //add assigned users as followers by default if (empty($sd['fu'])) { $sd['fu'] = Util\toNumericArray(@$this->getFieldValue('assigned', 0)['value']); } parent::createCustomData(); }
public function getContentItems() { $rez = array('data' => array()); $fa = DM\Favorites::readAll(); foreach ($fa as $f) { $d = Util\toJSONArray($f['data']); $d['nid'] = $f['node_id']; $d['targetPath'] = $d['path']; $d['path'] = $d['pathText']; unset($d['pathText']); $d['isFavorite'] = true; $rez['data'][] = $d; } return $rez; }
/** * load template custom data */ protected function loadCustomData() { parent::loadCustomData(); $res = DB\dbQuery('SELECT l' . \CB\Config::get('user_language_index') . ' `title` ,`' . implode('`,`', $this->tableFields) . '` FROM templates_structure WHERE id = $1', $this->id) or die(DB\dbQueryError()); if ($r = $res->fetch_assoc()) { $r['cfg'] = Util\toJSONArray($r['cfg']); $this->data = array_merge($this->data, $r); } else { \CB\debug("Template field load error: no field found with id = " . $this->id); // throw new \Exception("Template field load error: no field found with id = ".$this->id); } $res->close(); }
/** * read all templates with data form objects table * @param int $id * @return boolean */ public static function readAllWithData() { $rez = array(); $res = DB\dbQuery('SELECT t.* ,o.data FROM ' . static::getTableName() . ' t LEFT JOIN objects o ON t.id = o.id WHERE t.is_folder = 0'); while ($r = $res->fetch_assoc()) { $r['cfg'] = Util\toJSONArray($r['cfg']); $r['data'] = Util\toJSONArray($r['data']); $rez[] = $r; } $res->close(); return $rez; }
/** * load all plugins from database * * @return void */ public function loadAll() { if (!empty($this->loaded)) { return $this->items; } $this->items = array(); $res = DB\dbQuery('SELECT id ,name ,cfg ,`active` ,`order` FROM ' . \CB\PREFIX . '_casebox.plugins ORDER BY `order`') or die(DB\dbQueryError()); while ($r = $res->fetch_assoc()) { $r['cfg'] = Util\toJSONArray($r['cfg']); $this->items[$r['name']] = $r; } $res->close(); $this->loaded = true; }
/** * load template custom data */ protected function loadCustomData() { parent::loadCustomData(); $r = DM\Objects::read($this->id); if (!empty($r)) { $r = $r['data']; } else { //read from templates_structure if object not present in tree // for backward compatibility $r = DM\TemplatesStructure::read($this->id); } if (!empty($r)) { if (isset($r['cfg'])) { $r['cfg'] = Util\toJSONArray($r['cfg']); } $r['title'] = Util\detectTitle($r); $this->data = array_merge($this->data, $r); } else { \CB\debug("Template field load error: no field found with id = " . $this->id); // throw new \Exception("Template field load error: no field found with id = ".$this->id); } }
/** * create an array of node classes for given path and nodeConfigs * @param varchar $path * @param array $treeNodeGUIDConfigs * @return array */ public static function createNodesPath($path, $treeNodeGUIDConfigs) { $rez = array(); $path = explode('/', $path); $rootNodeCfg = Util\toJSONArray(Config::get('rootNode')); while (!empty($path)) { $npid = null; $nodeId = null; $el = array_shift($path); if (strlen($el) < 1) { continue; } //analize virtual root node if (!empty($rootNodeCfg) && $el == $rootNodeCfg['id'] && intval($el) == 0) { $rootNodeCfg['class'] = 'CB\\TreeNode\\Base'; $rootNodeCfg['guid'] = 0; $class = new \CB\TreeNode\Base($rootNodeCfg, $el); array_push($rez, $class); continue; } $el = explode('-', $el); if (sizeof($el) > 1) { $npid = array_shift($el); $nodeId = implode('-', $el); } else { $npid = static::getGUID('Dbnode'); $nodeId = $el[0]; } $cfg = empty($treeNodeGUIDConfigs[$npid]) ? array('class' => 'CB\\TreeNode\\Dbnode', 'guid' => $npid) : $treeNodeGUIDConfigs[$npid]; $class = new $cfg['class']($cfg, $nodeId); //set parent node if (!empty($rez)) { $class->parent = $rez[sizeof($rez) - 1]; } array_push($rez, $class); } return $rez; }
/** * get only active (not deleted fields) for given template * @param int $templateId optional, filter by a template * @param bool $onlyActive to return only active (nit deleted fields) * @return array */ public static function getFields($templateId = false, $onlyActive = true) { $rez = array(); $sql = 'SELECT ts.id ,ts.pid ,ts.template_id ,ts.name ,ts.`level` ,ts.`type` ,ts.cfg ,ts.order ,ts.solr_column_name ,o.data FROM templates_structure ts LEFT JOIN objects o ON ts.id = o.id '; if ($onlyActive) { $sql .= 'JOIN tree t on ts.id = t.id AND t.dstatus = 0 '; } if (is_numeric($templateId)) { $sql .= 'WHERE ts.template_id = $1 '; } $sql .= 'ORDER BY ts.template_id, ts.`order` '; $res = DB\dbQuery($sql, $templateId); while ($r = $res->fetch_assoc()) { $data = Util\toJSONArray($r['data']); unset($r['data']); //overwrite fields from templates table with values from objects.data $r = array_merge($r, $data); $r['cfg'] = Util\toJSONArray($r['cfg']); $r['title'] = Util\detectTitle($r); $rez[] = $r; } $res->close(); return $rez; }
/** * get param for this node * * @param varchar $param for now using to get 'facets' or 'DC' * @return array */ public function getNodeParam($param = 'facets') { $rez = false; $from = $this->getId(); //check if cached $cacheParam = 'nodeParam_' . $param . '_' . $from; if (Cache::exist($cacheParam)) { return Cache::get($cacheParam); } //select configs from tree and template of the current node $sql = 'SELECT t.cfg, t.template_id, tt.cfg `templateCfg` FROM tree t LEFT JOIN templates tt ON (t.template_id = tt.id) OR ((tt.id = $2) AND (t.template_id IS NULL)) WHERE t.id = $1'; //if template_id specified in config then select directly from templates table if (empty($from) && !empty($this->config['template_id'])) { $from = 'template_' . $this->config['template_id']; $sql = 'SELECT null `cfg`, t.id template_id, t.cfg `templateCfg` FROM templates t WHERE t.id = $2'; } //check node configuration and/or its template for facets definitions $res = DB\dbQuery($sql, array($this->id, @$this->config['template_id'])) or die(DB\dbQueryError()); if ($r = $res->fetch_assoc()) { $cfg = Util\toJSONArray($r['cfg']); if (isset($cfg[$param])) { $rez = $cfg[$param]; } else { $cfg = Util\toJSONArray($r['templateCfg']); if (isset($cfg[$param])) { $rez = $cfg[$param]; $from = 'template_' . $r['template_id']; } } //add grouping param for DC if ($param == 'DC' && $rez !== false) { if (!empty($cfg['view']['group'])) { $rez['group'] = $cfg['view']['group']; } elseif (!empty($cfg['group'])) { $rez['group'] = $cfg['group']; } } } $res->close(); if ($rez === false) { $rez = parent::getNodeParam($param); } else { $rez = array('from' => $from, 'data' => $rez); } Cache::set($cacheParam, $rez); return $rez; }
/** * update objects system data (sysData field) * this method updates data directly and desnt fire update events * @param variant $sysData array or json encoded string * if not specified then sysTada from current class will be used for update * @return boolean */ public function updateSysData($sysData = false) { $d =& $this->data; if ($sysData !== false) { $d['sys_data'] = Util\toJSONArray($sysData); } $this->collectSolrData(); @DB\dbQuery('INSERT INTO objects (id, sys_data) VALUES ($1, $2) ON DUPLICATE KEY UPDATE sys_data = $2', array($d['id'], Util\jsonEncode($d['sys_data']))) or die(DB\dbQueryError()); //mark the item as updated so that it'll be reindexed into solr DB\dbQuery('UPDATE tree SET updated = (updated | 1) WHERE id = $1', $d['id']) or die(DB\dbQueryError()); return true; }
/** * add notification records for a given log action * @param array $p * ('object_id', 'object_pid', 'user_id', 'action_type', 'data', 'activity_data_db') * * @return void */ private static function addNotificationRecords($p) { $activityData = Util\toJSONArray($p['activity_data_db']); $users = array(); if (!empty($activityData['fu'])) { foreach ($activityData['fu'] as $uid) { $users[intval($uid)] = 0; // email unsent meaning } } if (!empty($activityData['wu'])) { foreach ($activityData['wu'] as $uid) { $users[intval($uid)] = -1; // email doesnt need to be sent } } //exclude current user from notified users unset($users[User::getId()]); $params = array('object_id' => $p['object_id'], 'action_id' => $p['id'], 'action_type' => $p['action_type'], 'from_user_id' => $p['user_id']); foreach ($users as $uid => $uMailSent) { $params['user_id'] = $uid; $params['email_sent'] = $uMailSent; DM\Notifications::add($params); } }
/** * save or create an object * @param array $p object properties * @return json responce */ public function save($p) { $d = Util\toJSONArray($p['data']); // check if need to create object instead of update if (empty($d['id']) || !is_numeric($d['id'])) { return $this->create($d); } // SECURITY: check if current user has write access to this action if (!Security::canWrite($d['id'])) { throw new \Exception(L\get('Access_denied')); } /* prepare params */ if (empty($d['date']) && !empty($d['date_start'])) { $d['date'] = $d['date_start']; } /* end of prepare params */ // update object $object = $this->getCachedObject($d['id']); //set sys_data from object, it can contain custom data //that shouldn't be overwritten $d['sys_data'] = $object->getSysData(); $object->update($d); Objects::updateCaseUpdateInfo($d['id']); /* updating saved document into solr directly (before runing background cron) so that it'll be displayed with new name without delay */ if (!\CB\Config::getFlag('disableSolrIndexing')) { $solrClient = new Solr\Client(); $solrClient->updateTree(array('id' => $d['id'])); //running background cron to index other nodes $solrClient->runBackgroundCron(); } return $this->load($d); }
public function getLogRecords() { $s = Log::getSolrLogConnection(); $this->requestParams['sort'] = array('action_date desc'); $p = array('rows' => 50, 'fl' => 'id,action_id,user_id,object_id,object_pid,object_data', 'fq' => $this->fq, 'strictSort' => 'action_date desc'); $id = substr($this->lastNode->id, 1); switch (substr($this->lastNode->id, 0, 1)) { case 'd': $p['fq'][] = 'action_date:["' . $id . 'T00:00:00Z" TO "' . $id . 'T23:59:99Z"]'; break; case 'm': $p['fq'][] = 'action_date:["' . date('Y-m') . '-01T00:00:00Z" TO *]'; break; case 't': $p['fq'][] = 'action_type:' . $id; break; case 'u': $p['fq'][] = 'user_id:' . $id; break; case 't': $p['fq'][] = 'action_type:' . $id; break; } $rez = $s->query($p); foreach ($rez['data'] as &$doc) { $k = @$doc['action_id']; $data = Util\toJSONArray($doc['object_data']); $doc['id'] = $this->getId($k); $doc['pid'] = @$doc['object_pid']; unset($doc['object_pid']); $doc['name'] = Util\coalesce($data['name'], $doc['object_data']); $doc['iconCls'] = $data['iconCls']; $doc['path'] = $data['path']; // $doc['template_id'] = $data['template_id']; $doc['case_id'] = $data['case_id']; if ($data['date']) { $doc['date'] = $data['date']; } $doc['size'] = $data['size']; $doc['cid'] = @$data['cid']; $doc['oid'] = @$data['oid']; $doc['uid'] = @$data['uid']; $doc['cdate'] = $data['cdate']; $doc['udate'] = $data['udate']; $doc['user'] = User::getDisplayName($doc['user_id'], true); $doc['has_childs'] = false; } return $rez; }
/** * add notification records for a given log action * @param array $p * ('object_id', 'object_pid', 'user_id', 'action_type', 'data', 'activity_data_db') * * @return void */ private static function addNotificationRecords($p) { $activityData = Util\toJSONArray($p['activity_data_db']); $users = array(); //backward compatibility if (!empty($activityData['fu'])) { foreach ($activityData['fu'] as $uid) { $users[intval($uid)] = 0; } } if (!empty($activityData['wu'])) { foreach ($activityData['wu'] as $uid) { $users[intval($uid)] = 0; } } //exclude current user from notified users unset($users[User::getId()]); $params = array('object_id' => $p['object_id'], 'action_id' => $p['id'], 'action_type' => $p['action_type'], 'from_user_id' => $p['user_id']); foreach ($users as $uid => $seen) { $params['user_id'] = $uid; $params['seen'] = $seen; DM\Notifications::add($params); } }
/** * decode json fields */ protected static function decodeJsonFields(&$record) { foreach (static::$decodeJsonFields as $fn) { if (!empty($record[$fn])) { $record[$fn] = Util\toJSONArray($record[$fn]); } } return $record; }
/** * transfer config options to tree * @return void */ protected function syncConfigToTree() { $o = new \CB\Objects\Object(); $co = new \CB\Objects\Config(); $recs = DM\Config::readAll(); foreach ($recs as $r) { //detect option type $type = ''; switch ($r['param']) { case 'default_event_template': case 'default_file_template': case 'default_folder_template': case 'default_task_template': $type = 'int'; break; case 'default_language': case 'languages': case 'project_name_en': case 'project_name_ru': $type = 'varchar'; break; case 'folder_templates': case 'max_files_version_count': case 'templateIcons': $type = 'text'; break; case 'facet_configs': case 'js': case 'maintenance_cfg': case 'node_facets': case 'rootNode': case 'object_type_plugins': case 'treeNodes': $type = 'json'; break; case 'responsible_party': case 'responsible_party_default': case 'task_categories': case 'maintenance_mode': continue; default: if (is_numeric($r['value'])) { $type = 'int'; } else { $type = 'text'; } } if (empty($type)) { continue; } $childs = array(); if ($r['param'] == 'folder_templates') { $r['value'] .= ',' . $this->templateIds["Config json option"]; DM\Config::update($r); } if ($r['param'] == 'treeNodes') { $childs = Util\toJSONArray($r['value']); $r['value'] = ''; DM\Config::update($r); } $pid = $o->create(array('id' => null, 'pid' => $this->cfg['configFolderId'], 'template_id' => $this->templateIds["Config {$type} option"], 'name' => $r['param'], 'data' => array('_title' => $r['param'], 'value' => $r['value']))); $i = 1; foreach ($childs as $k => $v) { $co->create(array('id' => null, 'pid' => $pid, 'template_id' => $this->templateIds["Config {$type} option"], 'name' => $k, 'data' => array('_title' => $k, 'value' => json_encode($v, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT), 'order' => $i++))); } } //add menu rule for Menus folder $pid = Objects::getChildId($this->systemFolderId, 'Menus'); $tempalteIds = DM\Templates::getIdsByType('menu'); $o->create(array('id' => null, 'pid' => $pid, 'template_id' => $tempalteIds[0], 'name' => 'Create config options rule', 'data' => array('_title' => 'Create config options rule', 'node_ids' => $this->cfg['configFolderId'], 'menu' => $this->templateIds['Config int option'] . ',' . $this->templateIds['Config varchar option'] . ',' . $this->templateIds['Config text option'] . ',' . $this->templateIds['Config json option']))); }
/** * load template custom data */ protected function loadCustomData() { parent::loadCustomData(); $userLanguageIndex = \CB\Config::get('user_language_index'); $res = DB\dbQuery('SELECT id ,is_folder ,`type` ,name ,l' . $userLanguageIndex . ' `title` ,l1 ,l2 ,l3 ,l4 ,`order` ,`visible` ,iconCls ,default_field ,cfg ,title_template ,info_template FROM templates WHERE is_folder = 0 AND id = $1', $this->id) or die(DB\dbQueryError()); if ($r = $res->fetch_assoc()) { $r['cfg'] = Util\toJSONArray($r['cfg']); $this->data = array_merge($this->data, $r); } else { throw new \Exception("Template load error: no template found with id = " . $this->id); } $res->close(); /* loading template fields */ $this->data['fields'] = array(); $res = DB\dbQuery('SELECT ts.id ,ts.pid ,ts.name ,ts.l' . $userLanguageIndex . ' `title` ,ts.l1 ,ts.l2 ,ts.l3 ,ts.l4 ,ts.`type` ,ts.`level` ,ts.`order` ,ts.cfg ,ts.solr_column_name FROM templates_structure ts JOIN tree t on ts.id = t.id AND t.dstatus = 0 WHERE ts.template_id = $1 ORDER BY ts.`order`', $this->id) or die(DB\dbQueryError()); while ($r = $res->fetch_assoc()) { $r['cfg'] = Util\toJSONArray($r['cfg']); $this->data['fields'][$r['id']] = $r; $this->fieldsOrder[$r['name']] = intval($r['order']); } $res->close(); }
/** * check if current data updates solr configuration * @return boolean */ protected function isSolrConfigUpdated() { $rez = false; $old = empty($this->oldObject) ? $this : $this->oldObject; $od = $old->getData(); $nd =& $this->data; $d1 =& $od['data']; $d2 =& $nd['data']; $cfg1 = empty($d1['cfg']) ? array() : Util\toJSONArray($d1['cfg']); $cfg2 = empty($d2['cfg']) ? array() : Util\toJSONArray($d2['cfg']); $indexed1 = !empty($cfg1['indexed']) || !empty($cfg1['faceting']); $indexed2 = !empty($cfg2['indexed']) || !empty($cfg2['faceting']); $field1 = empty($d1['solr_column_name']) ? '' : $d1['solr_column_name']; $field2 = empty($d2['solr_column_name']) ? '' : $d2['solr_column_name']; $rez = $indexed1 != $indexed2 || $indexed1 && $field1 != $field2; return $rez; }
public function getTemplatesStructure() { $rez = array('success' => true, 'data' => array()); $data = array(); $res = DB\dbQuery('SELECT ts.id ,ts.pid ,t.id template_id ,t.type template_type ,ts.`name` ,ts.l' . Config::get('user_language_index') . ' `title` ,ts.`type` ,ts.`order` ,ts.cfg ,(coalesce(t.title_template,\'\') <> \'\' ) `has_title_template` FROM templates t LEFT JOIN templates_structure ts ON t.id = ts.template_id ,tree tr WHERE ts.id = tr.id and tr.dstatus = 0 ORDER BY ts.template_id, ts.`order`') or die(DB\dbQueryError()); while ($r = $res->fetch_assoc()) { $t = $r['template_id']; unset($r['template_id']); if ($r['type'] == '_auto_title' && $r['has_title_template'] == 0) { $r['type'] = 'varchar'; } unset($r['has_title_template']); if ($r['pid'] == $t) { $r['pid'] = null; } $r['cfg'] = Util\toJSONArray($r['cfg']); //unset server side functions to not be visible on lcient if (!empty($r['cfg']['source']['fn'])) { unset($r['cfg']['source']['fn']); } //set default search conditions: // - varchar: contains // - objects & multiValued: Contains Any // - object & singleValued: Equal // - other fieldTypes: equal if ($r['template_type'] == 'search' && empty($r['cfg']['cond'])) { switch ($r['type']) { case 'varchar': $r['cfg']['cond'] = 'contain'; break; case '_objects': $r['cfg']['cond'] = empty($r['cfg']['multiValued']) ? '=' : '<='; break; default: $r['cfg']['cond'] = '='; } } unset($r['template_type']); // If multiValued=True for Objects field, the default editor=form + default: "renderer": "listObjIcons" if (!empty($r['cfg']['multiValued'])) { if (!isset($r['cfg']['editor'])) { $r['cfg']['editor'] = 'form'; } if (!isset($r['cfg']['renderer'])) { $r['cfg']['renderer'] = 'listObjIcons'; } } $data[$t][] = $r; } $res->close(); return array('success' => true, 'data' => $data); }
/** * update objects system data (sysData field) * this method updates data directly and desnt fire update events * @param variant $sysData array or json encoded string * if not specified then sysTada from current class will be used for update * @return boolean */ public function updateSysData($sysData = false) { $d =& $this->data; if ($sysData !== false) { $d['sys_data'] = Util\toJSONArray($sysData); } $d['sys_data']['lastAction'] = $this->getLastActionData(); $this->collectSolrData(); $data = array('id' => $d['id'], 'sys_data' => Util\jsonEncode($d['sys_data'])); if (DM\Objects::exists($d['id'])) { DM\Objects::update($data); } else { DM\Objects::create($data); } //mark the item as updated so that it'll be reindexed into solr DM\Tree::update(array('id' => $d['id'], 'updated' => 1)); return true; }
public static function getGridViewState($guid) { $rez = array(); $res = DB\dbQuery('SELECT cfg FROM tree_user_config WHERE user_id = $1 and guid = $2', array(User::getId(), $guid)); if ($r = $res->fetch_assoc()) { $rez = Util\toJSONArray($r['cfg']); } $res->close(); //backward compatibility to extjs3 if (!empty($rez['sort']['field']) && empty($rez['sort']['property'])) { $rez['sort']['property'] = $rez['sort']['field']; } return $rez; }