/** * catch server side errors and return json encoded exception * @return void */ function extDirectShutdownFunction() { $data = \CB\Cache::get('ExtDirectData'); $error = error_get_last(); if (in_array($error['type'], array(1, 4))) { $data['type'] = 'exception'; $data['result'] = array('success' => false); $data['msg'] = 'Internal server error.'; if (\CB\IS_DEBUG_HOST) { $data['msg'] = $error['message']; $data['where'] = print_r(debug_backtrace(false), true); } //notify admin if (!(php_sapi_name() == "cli")) { @mail(Config::get('ADMIN_EMAIL'), 'Remote router error on ' . Config::get('core_url'), var_export($data, true), 'From: ' . Config::get('SENDER_EMAIL') . "\r\n"); } echo Util\jsonEncode($data); } if (\CB\User::isLoged()) { \CB\User::updateLastActionTime(); } }
/** * 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; }
/** * create templates defined in config * By default this method is not colled in this base class * Call it in descendant classes if needed * @return void */ protected function addCustomTemplates() { $o = new \CB\Objects\Template(); $tf = new \CB\Objects\TemplateField(); foreach ($this->cfg['templates'] as $k => $v) { echo "creating template '{$k}' .. "; $v['id'] = null; $v['pid'] = BBM::$cfg['templatesFolderId']; $v['template_id'] = BBM::$cfg['templatesTemplateId']; //create correct data if (empty($v['name'])) { $v['name'] = $k; } $type = empty($v['type']) ? 'object' : $v['type']; $data = array('_title' => $k, 'en' => $v['name'], 'type' => $type, 'visible' => 1); if (!empty($v['iconCls'])) { $data['iconCls'] = $v['iconCls']; } if (!empty($v['cfg'])) { $data['cfg'] = $v['cfg']; } if (!empty($v['title_template'])) { $data['title_template'] = $v['title_template']; } $v['data'] = $data; $fields = empty($v['fields']) ? array() : $v['fields']; unset($v['fields']); $id = $o->create($v); $this->templateIds[$k] = $id; // analize fields // ,'country' => array( // 'en' => 'Country' // ,'type' => '_objects' // ,'cfg' => array( // 'source' => 'tree' // ,'scope' => '/Country' // ) // ) $i = 1; foreach ($fields as $fn => $fv) { //check if we have field reference if (is_scalar($fv)) { $fn = $fv; $fv = $this->cfg['templateFields'][$fn]; } $fv['id'] = null; $fv['pid'] = $id; $fv['template_id'] = BBM::$cfg['fieldTemplateId']; $name = empty($fv['en']) ? $fn : $fv['en']; $type = empty($fv['type']) ? 'varchar' : $fv['type']; $order = empty($fv['order']) ? $i++ : $fv['order']; $data = array('name' => $fn, 'en' => $name, 'type' => $type, 'order' => $order); if (!empty($fv['solr_column_name'])) { $data['solr_column_name'] = $fv['solr_column_name']; } $cfg = empty($fv['cfg']) ? array() : $fv['cfg']; if (!empty($cfg['scope']) && substr($cfg['scope'], 0, 1) == '/') { $cfg['scope'] = $this->thesauriIds[$cfg['scope']]['id']; } if (!empty($cfg)) { $data['cfg'] = Util\jsonEncode($cfg); } $fv['name'] = $fn; $fv['type'] = $type; $fv['order'] = $order; $fv['data'] = $data; $tf->create($fv); } /* {"_title":"assigned" ,"en":"Assigned" ,"type":"_objects" ,"order":7 ,"cfg":"{ \"editor\": \"form\" ,\"source\": \"users\" ,\"renderer\": \"listObjIcons\" ,\"autoLoad\": true ,\"multiValued\": true ,\"hidePreview\": true\n}" } */ echo "Ok\n"; } }
/** * updating multiple documents into solr using atomic updates * @param array $docs array of documents to be updated into solr */ public function updateDocuments($docs) { $url = 'http://' . $this->host . ':' . $this->port . $this->core . '/update/json'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type:application/json; charset=utf-8")); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, Util\jsonEncode(array_values($docs))); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLINFO_HEADER_OUT, 1); $data = curl_exec($ch); if (curl_errno($ch)) { throw new \Exception("curl_error:" . curl_error($ch) . $this->debugInfo(), 1); } }
/** * formats a value for display according to it's field definition * @param array | int $field array of field properties or field id * @param variant $value field value to be formated * @param boolean $html default true - format for html, otherwise format for text display * @return varchar formated value */ public static function formatValueForDisplay($field, $value, $html = true) { $cacheVarName = ''; if (is_numeric($field)) { $field = $this->data->fields[$field]; } //condition is specified for values from search templates $condition = null; if (is_array($value)) { if (isset($value['cond'])) { $condition = Template::formatConditionForDisplay($field, $value['cond'], $html) . ' '; } if (isset($value['value'])) { $value = $value['value']; } else { $value = null; } } //we'll cache scalar by default, but will exclude textual fields $cacheValue = is_scalar($value); if ($cacheValue) { $fid = empty($field['id']) ? $field['name'] : $field['id']; $cacheVarName = 'dv' . $html . '_' . $fid . '_' . $value; //check if value is in cache and return if (Cache::exist($cacheVarName)) { return Cache::get($cacheVarName); } } /*check if field is not rezerved field for usernames (cid, oid, uid, did)*/ if (!empty($field['name']) && in_array($field['name'], array('cid', 'oid', 'uid', 'did'))) { $value = Util\toNumericArray($value); for ($i = 0; $i < sizeof($value); $i++) { $value[$i] = User::getDisplayName($value[$i]); } $value = implode(', ', $value); } else { switch ($field['type']) { case 'boolean': case 'checkbox': $value = empty($value) ? '' : ($value < 0 ? L\get('no') : L\get('yes')); break; case '_sex': switch ($value) { case 'm': $value = L\get('male'); break; case 'f': $value = L\get('female'); break; default: $value = ''; } break; case '_language': @($value = @\CB\Config::get('language_settings')[\CB\Config::get('languages')[$value - 1]][0]); break; case 'combo': case '_objects': if (empty($value)) { $value = ''; break; } $ids = Util\toNumericArray($value); if (empty($ids)) { if (empty($field['cfg']['source']) || !is_array($field['cfg']['source'])) { $value = ''; } break; } $value = array(); if (in_array(@$field['cfg']['source'], array('users', 'groups', 'usersgroups'))) { $udp = UsersGroups::getDisplayData($ids); foreach ($ids as $id) { if (empty($udp[$id])) { continue; } $r =& $udp[$id]; $label = @htmlspecialchars(Util\coalesce($r['title'], $r['name']), ENT_COMPAT); if ($html) { switch (@$field['cfg']['renderer']) { case 'listGreenIcons': $label = '<li class="icon-padding icon-element">' . $label . '</li>'; break; // case 'listObjIcons': // case 'listObjIcons': default: $icon = empty($r['iconCls']) ? 'icon-none' : $r['iconCls']; $label = '<li class="icon-padding ' . $icon . '">' . $label . '</li>'; break; } } $value[] = $label; } } else { $objects = \CB\Objects::getCachedObjects($ids); foreach ($ids as $id) { if (empty($objects[$id])) { continue; } $obj =& $objects[$id]; $d = $obj->getData(); $label = $obj->getHtmlSafeName(); $pids = $d['pids']; if ($html && !empty($pids)) { $pids = str_replace(',', '/', $pids); $linkType = empty($field['cfg']['linkType']) ? '' : 'link-type-' . $field['cfg']['linkType']; $label = '<a class="click ' . $linkType . '" template_id="' . $d['template_id'] . '" path="' . $pids . '" nid="' . $id . '">' . $label . '</a>'; } switch (@$field['cfg']['renderer']) { case 'listGreenIcons': $value[] = $html ? '<li class="icon-padding icon-element">' . $label . '</li>' : $label; break; // case 'listObjIcons': // case 'listObjIcons': default: $icon = \CB\Browser::getIcon($d); if (empty($icon)) { $icon = 'icon-none'; } $value[] = $html ? '<li class="icon-padding ' . $icon . '">' . $label . '</li>' : $label; break; } } } $value = $html ? '<ul class="clean">' . implode('', $value) . '</ul>' : implode(', ', $value); break; case '_fieldTypesCombo': $value = L\get(@static::$fieldTypeNames[$value]); break; case 'date': $value = Util\formatMysqlDate(Util\dateISOToMysql($value)); break; case 'datetime': $value = Util\UTCTimeToUserTimezone($value); break; case 'time': if (empty($value)) { continue; } $format = empty($field['format']) ? 'H:i' : $field['format']; if (is_numeric($value)) { $s = $value % 60; $value = floor($value / 60); $m = $value % 60; $value = floor($value / 60); if (strlen($value) < 2) { $value = '0' . $value; } if (strlen($m) < 2) { $m = '0' . $m; } $value .= ':' . $m; if (!empty($s)) { if (strlen($s) < 2) { $s = '0' . $s; } $value .= ':' . $s; } } else { $date = \DateTime::createFromFormat($format, $value); if (is_object($date)) { $value = $date->format($format); } } break; case 'html': $cacheValue = false; // $value = trim(strip_tags($value)); // $value = nl2br($value); break; case 'varchar': case 'memo': case 'text': $cacheValue = false; $renderers = ''; if (!empty($field['cfg']['linkRenderers'])) { $renderers = $field['cfg']['linkRenderers']; } elseif (!empty($field['cfg']['text_renderer'])) { $renderers = $field['cfg']['text_renderer']; } $value = empty($renderers) ? nl2br(htmlspecialchars($value, ENT_COMPAT)) : nl2br(Comment::processAndFormatMessage($value), $renderers); break; default: if (is_array($value)) { $cacheValue = false; $value = Util\jsonEncode($value); } else { $value = htmlspecialchars($value, ENT_COMPAT); } } } if ($cacheValue) { Cache::set($cacheVarName, $condition . $value); } return $condition . $value; }
/** * add/update record into solr * @param array $p action params */ private static function addSolrRecord(&$p) { $solr = static::getSolrLogConnection(); if (empty($solr)) { return; } $data = empty($p['new']) ? empty($p['old']) ? $p['data'] : $p['old']->getData() : $p['new']->getData(); $fu = @$p['activityData']['fu']; $wu = @$p['activityData']['wu']; $record = array('id' => Config::get('core_name') . '_' . $p['action_id'], 'core_id' => Config::get('core_id'), 'action_id' => $p['action_id'], 'action_type' => $p['type'], 'action_date' => date('Y-m-d\\TH:i:s\\Z'), 'user_id' => User::getId(), 'object_id' => $data['id'], 'object_pid' => empty($data['pid']) ? null : $data['pid'], 'object_pids' => $p['logData']['pids'], 'object_data' => Util\jsonEncode($p['logData'])); //delete empty values because solr raises exception when sending empty values for ints foreach ($record as $k => $v) { if (empty($v)) { unset($record[$k]); } } $record['dstatus'] = 0; $record['system'] = 0; $rez = $solr->addDocument($record); $solr->commit(); }
/** * collect data from a given array corresponding to current table definition * also encodes json fields defined in static::$decodeJsonFields * @param array $a * @return array associative array of fieldName => value */ public static function collectData($a) { $rez = array_intersect_key($a, static::$tableFields); foreach (static::$decodeJsonFields as $fn) { if (isset($rez[$fn]) && !is_null($rez[$fn] && !is_scalar($rez[$fn]))) { $rez[$fn] = Util\jsonEncode($rez[$fn]); } } return $rez; }
<?php namespace ExtDirect; use CB\Util; require_once '../init.php'; require_once 'config.php'; header('Content-Type: text/javascript'); // convert API config to Ext.Direct spec $actions = array(); foreach ($API as $aname => &$a) { $methods = array(); foreach ($a['methods'] as $mname => &$m) { $md = array('name' => $mname, 'len' => $m['len']); if (isset($m['formHandler']) && $m['formHandler']) { $md['formHandler'] = true; } $methods[] = $md; } $actions[$aname] = $methods; } $cfg = array('url' => 'remote/router.php', 'type' => 'remoting', 'enableBuffer' => true, 'maxRetries' => 0, 'actions' => $actions); echo 'Ext.app.REMOTING_API = '; echo Util\jsonEncode($cfg); echo ';';
/** * 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; }
/** * 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']; } elseif (!empty($p['params']['query'])) { $guid = 'search'; } 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->getDC(); $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, User::getId(), Util\jsonEncode($p['state']))); } return $rez; }
/** * get associative params array according to tableFields from object data * @return array */ protected function getParamsFromData() { $rez = array(); $p =& $this->data; foreach ($this->tableFields as $fieldName) { $field = null; $addField = false; $value = null; if (!empty($this->template)) { $field = $this->template->getField($fieldName); } if (empty($field) && $fieldName == 'name') { //update name to _title field if present in data (actually it should be present) $value = @$this->getFieldValue('_title', 0)['value']; if (empty($value)) { $value = $p['name']; } $addField = true; } elseif (!empty($field)) { //template field exists so it should be in data $addField = true; $value = @$this->getFieldValue($fieldName, 0)['value']; } elseif (isset($p[$fieldName]) && $p[$fieldName] !== 'id') { $addField = true; $value = $p[$fieldName]; } /** if empty and is language field - check if language field is defined as language abreviation */ // this if should be removed after complete migration to language abreviation titles if (!$addField && in_array($fieldName, array('l1', 'l2', 'l3', 'l4'))) { $addField = true; $lang = @\CB\Config::get('languages')[$fieldName[1] - 1]; $value = empty($lang) ? null : @$this->getFieldValue($lang, 0)['value']; } if ($addField) { $value = is_scalar($value) || is_null($value) ? $value : Util\jsonEncode($value); $rez[$fieldName] = $value; } } return $rez; }