/** * update tree nodes into solr * * @param string[] $p { * @type boolean $all if true then all nodes will be updated into solr, * otherwise - only the nodes marked as updated will be reindexed in solr * @type int[] $id id or array of object ids to update * * @type varchar $cron_id when this function is called by a cron then cron_id should be passed * * @type boolean $nolimit if true then no limit will be applied to maximum indexed nodes * (default 2000) * } */ public function updateTree($p = array()) { /* connect to solr service */ $this->connect(); $eventParams = array('class' => &$this, 'params' => &$p); $this->folderTemplates = \CB\Config::get('folder_templates'); \CB\fireEvent('onBeforeSolrUpdate', $eventParams); /** @type int the last processed document id */ $lastId = 0; $indexedDocsCount = 0; $all = !empty($p['all']); $nolimit = !empty($p['nolimit']); /* prepeare where condition for sql depending on incomming params */ $where = '(t.updated > 0) AND (t.draft = 0) AND (t.id > $1)'; if ($all) { $this->deleteByQuery('*:*'); $where = '(t.id > $1) AND (t.draft = 0) '; \CB\Templates\SingletonCollection::getInstance()->loadAll(); } elseif (!empty($p['id'])) { $ids = \CB\Util\toNumericArray($p['id']); $where = '(t.id in (0' . implode(',', $ids) . ') ) and (t.id > $1)'; } $sql = 'SELECT t.id ,t.pid ,ti.pids ,ti.case_id ,ti.acl_count ,ti.security_set_id ,t.name ,t.system ,t.template_id ,t.target_id ,t.size ,DATE_FORMAT(t.`date`, \'%Y-%m-%dT%H:%i:%sZ\') `date` ,DATE_FORMAT(t.`date_end`, \'%Y-%m-%dT%H:%i:%sZ\') `date_end` ,t.oid ,t.cid ,DATE_FORMAT(t.cdate, \'%Y-%m-%dT%H:%i:%sZ\') `cdate` ,t.uid ,DATE_FORMAT(t.udate, \'%Y-%m-%dT%H:%i:%sZ\') `udate` ,t.did ,DATE_FORMAT(t.ddate, \'%Y-%m-%dT%H:%i:%sZ\') `ddate` ,t.dstatus ,t.updated ,o.sys_data FROM tree t LEFT JOIN tree_info ti ON t.id = ti.id LEFT JOIN objects o ON o.id = t.id where ' . $where . ' ORDER BY t.id LIMIT 500'; $docs = true; while (!empty($docs) && ($nolimit || $indexedDocsCount < 2000)) { $docs = array(); $res = DB\dbQuery($sql, $lastId) or die(DB\dbQueryError()); while ($r = $res->fetch_assoc()) { $lastId = $r['id']; /* process full object update only if: - updated = 1 - specific ids are specified - if $all parameter is true */ if ($all || !empty($p['id']) || $r['updated'] & 1) { $r['sys_data'] = Util\toJsonArray($r['sys_data']); $this->prepareDBRecord($r); $docs[$r['id']] = $r; } $this->updateCronLastActionTime(@$p['cron_id']); } $res->close(); if (!empty($docs)) { //append file contents for files to content field $this->appendFileContents($docs); $this->addDocuments($docs); /* reset updated flag into database for processed documents */ DB\dbQuery('UPDATE tree ,tree_info SET tree.updated = 0 ,tree_info.updated = 0 WHERE tree.id in (' . implode(',', array_keys($docs)) . ') AND tree_info.id = tree.id') or die(DB\dbQueryError()); $this->updateCronLastActionTime(@$p['cron_id']); $this->commit(); $indexedDocsCount += sizeof($docs); } } $this->updateTreeInfo($p); \CB\fireEvent('onSolrUpdate', $eventParams); }
/** * method to generate preview blocks and return them as an array * now there are only top and bottom blocks * top contains fields from grid, bottom - complex fileds (html, text) edited outside the grid * * @return array */ public function getPreviewBlocks() { $top = ''; $body = ''; $bottom = ''; $gf = array(); if (!$this->loaded && !empty($this->id)) { $this->load(); } $linearData = $this->getLinearData(true); $template = $this->getTemplate(); //group fields in display blocks foreach ($linearData as $field) { $tf = $template->getField($field['name']); if (empty($tf)) { //fantom data of deleted or moved fields continue; } if (empty($tf['cfg'])) { $group = 'body'; } elseif (@$tf['cfg']['showIn'] == 'top') { $group = 'body'; //top } elseif (@$tf['cfg']['showIn'] == 'tabsheet') { $group = 'bottom'; } else { $group = 'body'; } //show field name if no title set if (empty($tf['title'])) { $tf['title'] = $tf['name']; } $field['tf'] = $tf; $gf[$group][] = $field; } $eventParams = array('object' => &$this, 'groupedFields' => &$gf); \CB\fireEvent('beforeGeneratePreview', $eventParams); if (!empty($gf['top'])) { foreach ($gf['top'] as $f) { if ($f['name'] == '_title') { continue; } $v = $template->formatValueForDisplay($f['tf'], $f); //['value'] if (is_array($v)) { $v = implode(', ', $v); } if (!empty($v)) { $top .= '<tr><td class="prop-key">' . $f['tf']['title'] . '</td><td class="prop-val">' . $v . '</td></tr>'; } } } if (!empty($gf['body'])) { $previousHeader = ''; foreach ($gf['body'] as $f) { $v = $template->formatValueForDisplay($f['tf'], @$f); if (is_array($v)) { $v = implode('<br />', $v); } if (!empty($f['tf']['cfg']['hidePreview']) || empty($v) && empty($f['info'])) { continue; } $headerField = $template->getHeaderField($f['tf']['id']); if (!empty($headerField) && $previousHeader != $headerField) { $body .= '<tr class="prop-header"><th colspan="3"' . (empty($headerField['level']) ? '' : ' style="padding-left: ' . $headerField['level'] * 20 . 'px"') . '>' . $headerField['title'] . '</th></tr>'; } $previousHeader = $headerField; $body .= '<tr>'; if (empty($f['tf']['cfg']['noHeader'])) { $body .= '<td' . (empty($f['tf']['level']) ? '' : ' style="padding-left: ' . $f['tf']['level'] * 20 . 'px"') . ' class="prop-key">' . $f['tf']['title'] . '</td>' . '<td class="prop-val">'; } else { $body .= '<td class="prop-val" colspan="2">'; } $body .= $v . (empty($f['info']) ? '' : '<p class="prop-info">' . $f['info'] . '</p>') . '</td></tr>'; } } if (!empty($gf['bottom'])) { foreach ($gf['bottom'] as $f) { $v = $template->formatValueForDisplay($f['tf'], $f); if (empty($v)) { continue; } $bottom .= '<div class="obj-preview-h">' . $f['tf']['title'] . '</div>' . '<div style="padding: 0 5px">' . $v . '</div><br />'; } } $top .= $body; if (!empty($top)) { $top = '<table class="obj-preview"><tbody>' . $top . '</tbody></table><br />'; } $rez = array($top, $bottom); $eventParams['result'] =& $rez; \CB\fireEvent('generatePreview', $eventParams); return $rez; }
protected function fireEvent($eventName, &$params) { if ($this->fireEvents) { \CB\fireEvent($eventName, $params); } }
/** * method to get multiple object properties from solr * Multilanguage plugin works also * * @param array | string $ids * @param string $fieldList * @return array associative array of properties per id */ public static function getObjects($ids, $fieldList = 'id,name') { $rez = array(); $ids = Util\toNumericArray($ids); if (!empty($ids)) { $chunks = array_chunk($ids, 200); //connect or get solr service connection $conn = Cache::get('solr_service'); if (empty($conn)) { $conn = new Solr\Service(); Cache::set('solr_service', $conn); } //execute search try { foreach ($chunks as $chunk) { $params = array('defType' => 'dismax', 'q.alt' => '*:*', 'fl' => $fieldList, 'fq' => array('id:(' . implode(' OR ', $chunk) . ')')); $inputParams = array('ids' => $chunk); $eventParams = array('params' => &$params, 'inputParams' => &$inputParams); \CB\fireEvent('beforeSolrQuery', $eventParams); $searchRez = $conn->search('', 0, 200, $params); if (!empty($searchRez->response->docs)) { foreach ($searchRez->response->docs as $d) { $rd = array(); foreach ($d as $fn => $fv) { $rd[$fn] = $fv; } $rez[$d->id] = $rd; } } $eventParams['result'] = array('data' => &$rez); \CB\fireEvent('solrQuery', $eventParams); } } catch (\Exception $e) { throw new \Exception("An error occured in getObjects: \n\n {$e->__toString()}"); } } return $rez; }
/** * method to collect all node ids needed for rendering of loaded data set * @param array &$result containing recxords in 'data' property * @return void */ protected function warmUpNodes(&$result) { $d =& $result['data']; $requiredIds = array(); $paths = array(); foreach ($d as &$rec) { if (!empty($rec['id'])) { $requiredIds[$rec['id']] = 1; } //add shorcut targets if (!empty($rec['target_id'])) { $requiredIds[$rec['target_id']] = 1; } //add path ids if (isset($rec['path']) && !isset($paths[$rec['path']])) { $path = Util\toNumericArray($rec['path'], '/'); if (!empty($path)) { $paths[$rec['path']] = $path; foreach ($path as $id) { $requiredIds[$id] = 1; } } } } $requiredIds = array_keys($requiredIds); //preload templates Templates\SingletonCollection::getInstance()->loadAll(); //preload all users display data //now there objects should be loaded in bulk before firing event //because DisplayColumns analizes each object from result Objects::getCachedObjects($requiredIds); $requiredIds = array(); $eventParams = array('inputParams' => &$this->inputParams, 'params' => &$this->params, 'data' => &$d, 'requiredIds' => &$requiredIds); \CB\fireEvent('solrQueryWarmUp', $eventParams); return $requiredIds; }