/** * function to get multilanguage strings. * * This is actually a wrapper for ATK's Tools::atktext() method, for * use in templates. * * @author Ivo Jansch <*****@*****.**> * * Example: {atktext id="users.userinfo.description"} * {atktext id="userinfo.description" module="users"} * {atktext id="description" module="users" node="userinfo"} */ function smarty_function_atktext($params, $smarty) { if (!isset($params['id'])) { $params['id'] = $params[0]; } switch (substr_count($params['id'], '.')) { case 1: list($module, $id) = explode('.', $params['id']); $str = Tools::atktext($id, $module, isset($params['node']) ? $params['node'] : ''); break; case 2: list($module, $node, $id) = explode('.', $params['id']); $str = Tools::atktext($id, $module, $node); break; default: $str = Tools::atktext($params['id'], Tools::atkArrayNvl($params, 'module', ''), Tools::atkArrayNvl($params, 'node', ''), Tools::atkArrayNvl($params, 'lng', '')); } if (isset($params['filter'])) { $fn = $params['filter']; $str = $fn($str); } // parse the rest of the params in the string $parser = new StringParser($str); return $parser->parse($params); }
/** * Parse the target string. * * @param string $string The string to parse * @param array $recordset The recordset to use for parsing the string * * @return string The parsed string */ public function parseString($string, $recordset) { $parser = new StringParser($string); // for backwardscompatibility reasons, we also support the '[pk]' var. $recordset['pk'] = $this->getNode()->primaryKey($recordset); $output = $parser->parse($recordset, true); return $output; }
public function search($record, $extended = false, $fieldprefix = '', DataGrid $grid = null) { $this->createDestination(); if ($this->m_destinationFilter != '') { $sp = new StringParser($this->m_destinationFilter); $this->m_destInstance->addFilter($sp->parse($record)); } $recordset = $this->m_destInstance->select()->includes(Tools::atk_array_merge($this->m_destInstance->descriptorFields(), $this->m_destInstance->m_primaryKey))->getAllRows(); $result = '<select class="form-control" name="atksearch[' . $this->fieldName() . ']">'; $result .= '<option value="">' . Tools::atktext('search_all', 'atk'); $result .= $this->createdd($recordset); $result .= '</select>'; return $result; }
/** * Converts a database value to an internal value. * * For this attribute the value will be read from a file (if possible) * * @param array $record The database record that holds this attribute's value * * @return mixed The internal value */ public function db2value($record) { // determine filename. $parser = new StringParser($this->m_filename); $filename = $parser->parse($record); if (!file_exists($filename)) { Tools::atkdebug('[' . $this->fieldName() . "] warning: {$filename} doesn't exist"); return $record[$this->fieldName()]; } else { if ($record[$this->fieldName()] == '') { // db is empty. if file contains stuff, use that. $contents = implode('', file($filename)); Tools::atkdebug('[' . $this->fieldName() . "] succesfully read {$filename}"); return $contents; } else { return $record[$this->fieldName()]; } } }
/** * Renders the summary for the given data grid. * * @return string rendered HTML */ public function render() { $grid = $this->getGrid(); $limit = $grid->getLimit(); $count = $grid->getCount(); if ($count == 0) { return; } if ($limit == -1) { $limit = $count; } $start = $grid->getOffset(); $end = min($start + $limit, $count); $page = floor($start / $limit + 1); $pages = ceil($count / $limit); $string = $grid->text('datagrid_summary'); $params = array('start' => $start + 1, 'end' => $end, 'count' => $count, 'limit' => $limit, 'page' => $page, 'pages' => $pages); $parser = new StringParser($string); $result = $parser->parse($params); return '<div class="dgridsummary">' . $result . '</div>'; }
/** * Parses a record. * * @param array $record Array with fields * @param string $mode * * @return string Parsed string */ public function display($record, $mode) { $stringparser = new StringParser($this->m_text); return $stringparser->parse($record); }
/** * This function returns the list of users that may login. This can be * used to display a dropdown of users from which to choose. * * @return array List of users as an associative array with the following * format: array of records, each record is an associative * array with a userid and a username field. */ public function getUserList() { $db = Db::getInstance(Config::getGlobal('auth_database')); $query = 'SELECT * FROM ' . Config::getGlobal('auth_usertable'); $accountdisablefield = Config::getGlobal('auth_accountdisablefield'); $accountenableexpression = Config::getGlobal('auth_accountenableexpression'); if ($accountenableexpression != '') { $query .= " WHERE {$accountenableexpression}"; if ($accountdisablefield != '') { $query .= " AND {$accountdisablefield} = 0"; } } else { if ($accountdisablefield != '') { $query .= " WHERE {$accountdisablefield} = 0"; } } $recs = $db->getRows($query); $userlist = []; $stringparser = new StringParser(Config::getGlobal('auth_userdescriptor')); for ($i = 0, $_i = count($recs); $i < $_i; ++$i) { $userlist[] = array('userid' => $recs[$i][Config::getGlobal('auth_userfield')], 'username' => $stringparser->parse($recs[$i])); } usort($userlist, array('auth_db', 'userListCompare')); return $userlist; }
/** * Get Concat filter. * * @param string $searchValue Search value * @param string $fieldaliasprefix Field alias prefix * * @return string|bool */ public function getConcatFilter($searchValue, $fieldaliasprefix = '') { // If we have a descriptor with multiple fields, use CONCAT $attribs = $this->m_destInstance->descriptorFields(); if (count($attribs) > 1) { $fields = []; foreach ($attribs as $attribname) { $post = ''; if (strstr($attribname, '.')) { if ($fieldaliasprefix != '') { $table = $fieldaliasprefix . '_AE_'; } else { $table = ''; } $post = substr($attribname, strpos($attribname, '.')); $attribname = substr($attribname, 0, strpos($attribname, '.')); } elseif ($fieldaliasprefix != '') { $table = $fieldaliasprefix . '.'; } else { $table = $this->m_destInstance->m_table . '.'; } /** @var Attribute $p_attrib */ $p_attrib = $this->m_destInstance->m_attribList[$attribname]; $fields[$p_attrib->fieldName()] = $table . $p_attrib->fieldName() . $post; } if (is_array($searchValue)) { // (fix warning trim function) $searchValue = $searchValue[0]; } $value = $this->escapeSQL(trim($searchValue)); $value = str_replace(' ', ' ', $value); if (!$value) { return false; } else { $function = $this->getConcatDescriptorFunction(); if ($function != '' && method_exists($this->m_destInstance, $function)) { $descriptordef = $this->m_destInstance->{$function}(); } elseif ($this->m_destInstance->m_descTemplate != null) { $descriptordef = $this->m_destInstance->m_descTemplate; } elseif (method_exists($this->m_destInstance, 'descriptor_def')) { $descriptordef = $this->m_destInstance->descriptor_def(); } else { $descriptordef = $this->m_destInstance->descriptor(null); } $parser = new StringParser($descriptordef); $concatFields = $parser->getAllParsedFieldsAsArray($fields, true); $concatTags = $concatFields['tags']; $concatSeparators = $concatFields['separators']; $concatSeparators[] = ' '; //the query removes all spaces, so let's do the same here [Bjorn] // to search independent of characters between tags, like spaces and comma's, // we remove all these separators so we can search for just the concatenated tags in concat_ws [Jeroen] foreach ($concatSeparators as $separator) { $value = str_replace($separator, '', $value); } $db = $this->getDb(); $searchcondition = 'UPPER(' . $db->func_concat_ws($concatTags, '', true) . ") LIKE UPPER('%" . $value . "%')"; } return $searchcondition; } return false; }
/** * Render the multiselect list control. * * @param string $name The name of the list control * @param array $recordset The list of records to render in the control * @param string $opposite The name of the list control connected to this list control for shuttle actions * @param string $prefix The prefix which is needed for determining the correct JS name * @param bool $isSelected Whether or not this is the selectbox with the selectedItems (needed for onchangecode) * * @return string piece of html code */ protected function _renderSelect($name, $recordset, $opposite, $prefix, $isSelected) { if ($isSelected) { $onchangecode = $this->getHtmlId($prefix) . '_onChange(\'selected\');'; $action = 'del'; } else { $onchangecode = $this->getHtmlId($prefix) . '_onChange(\'available\');'; $action = 'add'; } $valName = $this->getHtmlId($prefix) . '[selected][][' . $this->getRemoteKey() . ']'; $result = '<select class="shuttle_select" id="' . $name . '" name="' . $name . '" multiple size="10" onDblClick="shuttle_move(\'' . $name . '\', \'' . $opposite . '\',\'' . $action . '\',\'' . $valName . '\');' . $onchangecode . '">'; $parser = null; // Only import the stringparser once. if (isset($this->m_descriptor_tooltip_template)) { $parser = new StringParser($this->m_descriptor_tooltip_template); } for ($i = 0, $_i = count($recordset); $i < $_i; ++$i) { $title = $this->m_destInstance->descriptor($recordset[$i]); $ttip = isset($this->m_descriptor_tooltip_template) ? $parser->parse($recordset[$i]) : $title; $ttip = str_replace('\\r\\n', ' ', strip_tags($ttip)); $result .= '<option value="' . $recordset[$i][$this->m_destInstance->primaryKeyField()] . '" title="' . $ttip . '">' . htmlentities($title) . '</option>'; } $result .= '</select>'; return $result; }
/** * The load method performs the calculation. * * @param Db $db * @param array $record * @param string $mode * * @return string result of the calculation */ public function load($db, $record, $mode) { $parser = new StringParser($this->m_calculation); $result = 0; eval('$result = ' . $parser->parse($record) . ';'); return $result; }
/** * Determine a descriptor of a record. * * The descriptor is a string that describes a record for the user. For * person records, this may be the firstname and the lastname, for * companies it may be the company name plus the city etc. * The descriptor is used when displaying records in a dropdown for * example, or in the title of editpages, delete confirmations etc. * * The descriptor method calls a method named descriptor_def() on the node * to retrieve a template for the descriptor (string with attributenames * between blockquotes, for example "[lastname], [firstname]". * * If the node has no descriptor_def() method, the first attribute of the * node is used as descriptor. * * Derived classes may override this method to implement custom descriptor * logic. * * @param array $record The record for which the descriptor is returned. * * @return string The descriptor for the record. */ public function descriptor($record) { // Descriptor handler is set? if ($this->m_descHandler != null) { return $this->m_descHandler->descriptor($record, $this); } // Descriptor template is set? if ($this->m_descTemplate != null) { $parser = new StringParser($this->m_descTemplate); return $parser->parse($record); } else { if (method_exists($this, 'descriptor_def')) { $parser = new StringParser($this->descriptor_def()); return $parser->parse($record); } else { // default descriptor.. (default is first attribute of a node) $keys = array_keys($this->m_attribList); return $record[$keys[0]]; } } }
/** * Determine the real filename of a file (based on m_filenameTpl). * * @param array $rec The record * @param string $default The default filename * * @return string The real filename based on the filename template */ public function filenameMangle($rec, $default) { if ($this->m_filenameTpl == '') { $filename = $default; } else { $parser = new StringParser($this->m_filenameTpl); $includes = $parser->getAttributes(); $record = $this->m_ownerInstance->updateRecord($rec, $includes, array($this->fieldName())); $record[$this->fieldName()] = substr($default, 0, strrpos($default, '.')); $ext = $this->getFileExtension($default); $filename = $parser->parse($record) . ($ext != '' ? '.' . $ext : ''); } return str_replace(' ', '_', $filename); }
/** * Function outputs an array with all information necessary to output a recordlist. * * @param array $recordset List of records that need to be displayed * @param string $prefix Prefix for each column name (used for subcalls) * @param array $actions List of default actions for each record * @param array $suppress An array of fields that you want to hide * * The result array contains the following information: * "name" => the name of the recordlist * "heading" => for each visible column an array containing: "title" {, "url"} * "search" => for each visible column HTML input field(s) for searching * "rows" => list of rows, per row: "data", "actions", "mra", "record" * "totalraw" => for each totalisable column the sum value field(s) (raw) * "total" => for each totalisable column the sum value (display) * "mra" => list of all multi-record actions * * @return array see above */ private function listArray(&$recordset, $prefix = '', $actions = [], $suppress = array()) { $grid = $this->getGrid(); $flags = $this->convertDataGridFlags(); if (!is_array($suppress)) { $suppress = []; } $result = array('name' => $grid->getName(), 'heading' => [], 'search' => [], 'rows' => [], 'totalraw' => [], 'total' => [], 'mra' => []); $columnConfig = $grid->getNode()->getColumnConfig($grid->getName()); if (!Tools::hasFlag($flags, RecordList::RL_NO_SEARCH) || $grid->isEditing()) { $grid->getNode()->setAttribSizes(); } $this->_addListArrayHeader($result, $prefix, $suppress, $flags, $columnConfig); /* actions array can contain multi-record-actions */ if (count($actions) == 2 && count(array_diff(array_keys($actions), array('actions', 'mra'))) == 0) { $mra = $actions['mra']; $actions = $actions['actions']; } else { $mra = $grid->getNode()->hasFlag(Node::NF_NO_DELETE) ? [] : array('delete'); } /* get the rows */ for ($i = 0, $_i = count($recordset); $i < $_i; ++$i) { $result['rows'][$i] = array('columns' => [], 'actions' => $actions, 'mra' => $mra, 'record' => &$recordset[$i], 'data' => []); $result['rows'][$i]['selector'] = $grid->getNode()->primaryKey($recordset[$i]); $result['rows'][$i]['type'] = 'data'; $row =& $result['rows'][$i]; /* actions / mra */ $grid->getNode()->collectRecordActions($row['record'], $row['actions'], $row['mra']); // filter actions we are allowed to execute foreach ($row['actions'] as $name => $url) { if (!empty($url) && $grid->getNode()->allowed($name, $row['record'])) { /* dirty hack */ $atkencoded = strpos($url, '_15B') > 0; $url = str_replace('%5B', '[', $url); $url = str_replace('%5D', ']', $url); $url = str_replace('_1' . '5B', '[', $url); $url = str_replace('_1' . '5D', ']', $url); if ($atkencoded) { $url = str_replace('[pk]', Tools::atkurlencode(rawurlencode($row['selector']), false), $url); } else { $url = str_replace('[pk]', rawurlencode($row['selector']), $url); } $parser = new StringParser($url); $url = $parser->parse($row['record'], true, false); $row['actions'][$name] = $url; } else { unset($row['actions'][$name]); } } // filter multi-record-actions we are allowed to execute foreach ($row['mra'] as $j => $name) { if (!$grid->getNode()->allowed($name, $row['record'])) { unset($row['mra'][$j]); } } $row['mra'] = array_values($row['mra']); $result['mra'] = array_merge($result['mra'], $row['mra']); /* columns */ $editAllowed = $grid->getPostvar('atkgridedit', false) && $grid->getNode()->allowed('edit', $result['rows'][$i]['record']); $result['rows'][$i]['edit'] = $editAllowed; $this->_addListArrayRow($result, $prefix, $suppress, $flags, $i, $editAllowed); } // override totals if (is_array($result['total']) && count($result['total']) > 0) { $selector = $grid->getNode()->select()->ignoreDefaultFilters(); foreach ($grid->getFilters() as $filter) { $selector->where($filter['filter'], $filter['params']); } $result['totalraw'] = $selector->getTotals(array_keys($result['total'])); foreach ($result['totalraw'] as $attrName => $value) { $result['total'][$attrName] = $grid->getNode()->getAttribute($attrName)->getView('list', $result['totalraw']); } } if (Tools::hasFlag($flags, RecordList::RL_EXT_SORT) && $columnConfig->hasSubTotals()) { $totalizer = new Totalizer($grid->getNode(), $columnConfig); $result['rows'] = $totalizer->totalize($result['rows']); } if (Tools::hasFlag($flags, RecordList::RL_MRA)) { $result['mra'] = array_values(array_unique($result['mra'])); } return $result; }
public function getSearchCondition(Query $query, $table, $value, $searchmode, $fieldname = '') { $searchconditions = []; // Get search condition for all searchFields foreach ($this->m_searchfields as $field) { $p_attrib = $this->m_ownerInstance->getAttribute($field); if (is_object($p_attrib)) { $condition = $p_attrib->getSearchCondition($query, $table, $value, $searchmode); if (!empty($condition)) { $searchconditions[] = $condition; } } } // When searchmode is substring also search the value in a concat of all searchfields if ($searchmode == 'substring') { $value = $this->escapeSQL(trim($value)); $data = []; foreach ($this->m_searchfields as $field) { if (strpos($field, '.') == false) { $data[$field] = $table . '.' . $field; } else { $data[$field] = $field; } } $parser = new StringParser($this->m_template); $concatFields = $parser->getAllParsedFieldsAsArray($data, true); $concatTags = $concatFields['tags']; $concatSeparators = $concatFields['separators']; // to search independent of characters between tags, like spaces and comma's, // we remove all these separators (defined in the node with new atkAggregatedColumn) // so we can search for just the concatenated tags in concat_ws [Jeroen] foreach ($concatSeparators as $separator) { $value = str_replace($separator, '', $value); } $db = $this->getDb(); $condition = 'UPPER(' . $db->func_concat_ws($concatTags, '', true) . ") LIKE UPPER('%" . $value . "%')"; $searchconditions[] = $condition; } if (count($searchconditions)) { return '(' . implode(' OR ', $searchconditions) . ')'; } return ''; }
/** * If the auto-select flag is set and only one record exists we immediately * return with the selected record. * * @param DataGrid $grid data grid * * @return bool auto-select active? */ protected function autoSelectRecord($grid) { $node = $this->getNode(); if (!$node->hasFlag(Node::NF_AUTOSELECT)) { return false; } $grid->loadRecords(); if ($grid->getCount() != 1) { return false; } $sm = SessionManager::getInstance(); if ($sm->atkLevel() > 0 && $grid->getPostvar('atkprevlevel', 0) > $sm->atkLevel()) { $backUrl = $sm->sessionUrl(Config::getGlobal('dispatcher') . '?atklevel=' . $sm->newLevel(SessionManager::SESSION_BACK)); $node->redirect($backUrl); } else { $records = $grid->getRecords(); // There's only one record and the autoselect flag is set, so we // automatically go to the target. $parser = new StringParser(rawurldecode(Tools::atkurldecode($grid->getPostvar('atktarget')))); // For backwardscompatibility reasons, we also support the '[pk]' var. $records[0]['pk'] = $node->primaryKey($records[0]); $target = $parser->parse($records[0], true); $node->redirect($sm->sessionUrl($target, SessionManager::SESSION_NESTED)); } return true; }
/** * Parses the destination filter. * * @param string $destFilter filter to parse * @param array $record the current record * * @return string $filter */ public function parseFilter($destFilter, $record) { if ($destFilter != '') { $parser = new StringParser($destFilter); return $parser->parse($record); } return ''; }
/** * Initialize when we create the datagrid for the first time. */ protected function initOnCreate() { $this->setFlags($this->convertNodeFlags($this->getNode()->getFlags())); $this->setBaseUrl(Tools::partial_url($this->getNode()->atkNodeUri(), $this->getNode()->m_action, 'datagrid')); $this->setDefaultLimit(Config::getGlobal('recordsperpage')); $this->setDefaultActions($this->getNode()->defaultActions('admin')); $this->setDefaultOrderBy($this->getNode()->getOrder()); $this->setTemplate('datagrid.tpl'); $this->setActionSessionStatus(SessionManager::SESSION_NESTED); $this->setMode('admin'); $this->setMRASelectionMode($this->getNode()->getMRASelectionMode()); if (!$this->getNode()->hasFlag(Node::NF_NO_FILTER)) { foreach ($this->getNode()->m_filters as $key => $value) { $this->addFilter($key . "='" . $value . "'"); } foreach ($this->getNode()->m_fuzzyFilters as $filter) { $parser = new StringParser($filter); $filter = $parser->parse(array('table' => $this->getNode()->getTable())); $this->addFilter($filter); } } $this->addComponent('list', __NAMESPACE__ . '\\DataGridList'); $this->addComponent('summary', __NAMESPACE__ . '\\DataGridSummary'); $this->addComponent('limit', __NAMESPACE__ . '\\DataGridLimit', array('showAll' => Config::getGlobal('enable_showall'))); $this->addComponent('norecordsfound', __NAMESPACE__ . '\\DataGridNoRecordsFound'); $this->addComponent('paginator', __NAMESPACE__ . '\\DataGridPaginator'); if (!empty($this->getNode()->m_index)) { $this->addComponent('index', 'atk.datagrid.atkdgindex'); } if (count($this->getNode()->m_editableListAttributes) > 0) { $this->addComponent('editcontrol', __NAMESPACE__ . '\\DataGridEditControl'); } }
/** * Apply node filters to query. * * @param Query $query query */ protected function _applyFiltersToQuery(Query $query) { if ($this->m_ignoreDefaultFilters) { return; } // key/value filters foreach ($this->_getNode()->m_filters as $key => $value) { $query->addCondition($key . "='" . $this->_getDb()->escapeSQL($value) . "'"); } // fuzzy filters foreach ($this->_getNode()->m_fuzzyFilters as $filter) { $parser = new StringParser($filter); $filter = $parser->parse(array('table' => $this->_getNode()->getTable())); $query->addCondition($filter); } }
/** * Recursive funtion which fills an array with all the items of the tree. * * @param bool $showactions Show actions? * @param bool $expandAll Expand all leafs? * @param bool $foldable Is this tree foldable? * * @return string */ public function GraphTreeRender($showactions = true, $expandAll = false, $foldable = true) { global $g_maxlevel, $exp_index; // Return if (count($this->m_tree) == 1) { return ''; } $img_expand = $this->getIcon('expand'); $img_collapse = $this->getIcon('collapse'); $img_line = $this->getIcon('vertline'); $img_split = $this->getIcon('split'); $img_plus = $this->getIcon('split_plus'); $img_minus = $this->getIcon('split_minus'); $img_end = $this->getIcon('end'); $img_end_plus = $this->getIcon('end_plus'); $img_end_minus = $this->getIcon('end_minus'); $img_leaf = $this->getIcon('leaf'); $img_leaflink = $this->getIcon('leaf_link'); $img_spc = $this->getIcon('space'); $img_extfile = $this->getIcon('extfile'); $res = ''; $lastlevel = 0; //echo $this->m_tree[0]["expand"]."--".$this->m_tree[0]["colapse"]; $explevels = []; if ($this->m_tree[0]['expand'] != 1 && $this->m_tree[0]['colapse'] != 1) { // normal operation for ($i = 0; $i < count($this->m_tree); ++$i) { if ($this->m_tree[$i]['level'] < 2) { if ($this->m_tree[$i]['isleaf'] == 1 && $this->m_tree[$i]['level'] < 1) { $expand[$i] = 1; $visible[$i] = 1; } else { $expand[$i] = 0; $visible[$i] = 1; } } else { $expand[$i] = 0; $visible[$i] = 0; } $levels[$i] = 0; } if ($this->m_postvars['atktree'] != '') { $explevels = explode('|', $this->m_postvars['atktree']); } } elseif ($this->m_tree[0]['expand'] == 1) { // expand all mode! for ($i = 0; $i < count($this->m_tree); ++$i) { $expand[$i] = 1; $visible[$i] = 1; $levels[$i] = 0; } $this->m_tree[0]['expand'] = 0; // next time we are back in normal view mode! } elseif ($this->m_tree[0]['colapse'] == 1) { // colapse all mode! for ($i = 0; $i < count($this->m_tree); ++$i) { if ($this->m_tree[$i]['level'] < 2) { if ($this->m_tree[$i]['isleaf'] == 1 && $this->m_tree[$i]['level'] < 1) { $expand[$i] = 1; $visible[$i] = 1; } else { $expand[$i] = 0; $visible[$i] = 1; } } $levels[$i] = 0; } $this->m_tree[0]['colapse'] = 0; // next time we are back in normal view mode! } /* * ****************************************** */ /* Get Node numbers to expand */ /* * ****************************************** */ $i = 0; while ($i < count($explevels)) { //$expand[$explevels[$i]]=1; $expand[$exp_index[$explevels[$i]]] = 1; ++$i; } /* * ****************************************** */ /* Find last nodes of subtrees */ /* * ****************************************** */ $lastlevel = $g_maxlevel; for ($i = count($this->m_tree) - 1; $i >= 0; --$i) { if ($this->m_tree[$i]['level'] < $lastlevel) { for ($j = $this->m_tree[$i]['level'] + 1; $j <= $g_maxlevel; ++$j) { $levels[$j] = 0; } } if ($levels[$this->m_tree[$i]['level']] == 0) { $levels[$this->m_tree[$i]['level']] = 1; $this->m_tree[$i]['isleaf'] = 1; } else { $this->m_tree[$i]['isleaf'] = 0; } $lastlevel = $this->m_tree[$i]['level']; } /* * ****************************************** */ /* Determine visible nodes */ /* * ****************************************** */ $visible[0] = 1; // root is always visible for ($i = 0; $i < count($explevels); ++$i) { $n = $exp_index[$explevels[$i]]; if ($visible[$n] == 1 && $expand[$n] == 1) { $j = $n + 1; while ($this->m_tree[$j]['level'] > $this->m_tree[$n]['level']) { if ($this->m_tree[$j]['level'] == $this->m_tree[$n]['level'] + 1) { $visible[$j] = 1; } ++$j; } } } for ($i = 0; $i < $g_maxlevel; ++$i) { $levels[$i] = 1; } $res .= '<tr>'; // Make cols for max level for ($i = 0; $i < $g_maxlevel; ++$i) { $res .= "<td width=16> </td>\n"; } // Make the last text column $res .= '<td width=300> </td>'; // Column for the functions if ($showactions) { $res .= '<td width=300> </td>'; } $res .= "</tr>\n"; $cnt = 0; while ($cnt < count($this->m_tree)) { if ($visible[$cnt]) { $currentlevel = isset($this->m_tree[$cnt]['level']) ? $this->m_tree[$cnt]['level'] : 0; $nextlevel = isset($this->m_tree[$cnt + 1]['level']) ? $this->m_tree[$cnt + 1]['level'] : 0; /****************************************/ /* start new row */ /****************************************/ $res .= '<tr>'; /****************************************/ /* vertical lines from higher levels */ /****************************************/ $i = 0; while ($i < $this->m_tree[$cnt]['level'] - 1) { if ($levels[$i] == 1) { $res .= '<td><img src="' . $img_line . "\" border=0></td>\n"; } else { $res .= '<td><img src="' . $img_spc . "\" border=0></td>\n"; } ++$i; } /***************************************/ /* corner at end of subtree or t-split */ /***************************************/ if ($this->m_tree[$cnt]['isleaf'] == 1 && $nextlevel < $currentlevel) { if ($cnt != 0) { $res .= '<td><img src="' . $img_end . "\" border=0></td>\n"; } $levels[$this->m_tree[$cnt]['level'] - 1] = 0; } else { if ($expand[$cnt] == 0) { if ($nextlevel > $currentlevel) { /* * ************************************* */ /* Create expand/collapse parameters */ /* * ************************************* */ $i = 0; $params = 'atktree='; while ($i < count($expand)) { if ($expand[$i] == 1 && $cnt != $i || $expand[$i] == 0 && $cnt == $i) { $params = $params . $this->m_tree[$i]['id']; $params = $params . '|'; } ++$i; } if ($this->extraparams) { $params = $params . $this->extraparams; } if ($this->m_tree[$cnt]['isleaf'] == 1) { if ($cnt != 0) { $res .= '<td>' . Tools::href(Config::getGlobal('dispatcher') . '?atknodeuri=' . $this->atkNodeUri() . '&atkaction=' . $this->m_action . '&' . $params, '<img src="' . $img_end_plus . '" border=0>') . "</td>\n"; } } else { if ($cnt != 0) { $res .= '<td>' . Tools::href(Config::getGlobal('dispatcher') . '?atknodeuri=' . $this->atkNodeUri() . '&atkaction=' . $this->m_action . '&' . $params, '<img src="' . $img_plus . '" border=0>') . "</td>\n"; } } } else { $res .= '<td><img src="' . $img_split . "\" border=0></td>\n"; } } else { if ($nextlevel > $currentlevel) { /* * ************************************* */ /* Create expand/collapse parameters */ /* * ************************************* */ $i = 0; $params = 'atktree='; while ($i < count($expand)) { if ($expand[$i] == 1 && $cnt != $i || $expand[$i] == 0 && $cnt == $i) { $params = $params . $this->m_tree[$i]['id']; $params = $params . '|'; } ++$i; } if (isset($this->extraparams)) { $params = $params . $this->extraparams; } if ($this->m_tree[$cnt]['isleaf'] == 1) { if ($cnt != 0) { if ($foldable) { $res .= '<td>' . Tools::href(Config::getGlobal('dispatcher') . '?atknodeuri=' . $this->atkNodeUri() . '&atkaction=' . $this->m_action . '&' . $params, '<img src="' . $img_end_minus . '" border=0>') . "</td>\n"; } else { $res .= '<td><img src="' . $img_end . "\" border=0></td>\n"; } } } else { if ($cnt != 0) { if ($foldable) { $res .= '<td>' . Tools::href(Config::getGlobal('dispatcher') . '?atknodeuri=' . $this->atkNodeUri() . '&atkaction=' . $this->m_action . '&' . $params, '<img src="' . $img_minus . '" border=0>') . "</td>\n"; } else { $res .= '<td><img src="' . $img_split . "\" border=0></td>\n"; } } } } else { $res .= '<td><img src="' . $img_split . "\" border=0></td>\n"; } } if ($this->m_tree[$cnt]['isleaf'] == 1) { $levels[$this->m_tree[$cnt]['level'] - 1] = 0; } else { $levels[$this->m_tree[$cnt]['level'] - 1] = 1; } } /* * ***************************************** */ /* Node (with subtree) or Leaf (no subtree) */ /* * ***************************************** */ if ($nextlevel > $currentlevel) { /* * ************************************* */ /* Create expand/collapse parameters */ /* * ************************************* */ if ($foldable) { $i = 0; $params = 'atktree='; while ($i < count($expand)) { if ($expand[$i] == 1 && $cnt != $i || $expand[$i] == 0 && $cnt == $i) { $params = $params . $this->m_tree[$i]['id']; $params = $params . '|'; } ++$i; } if (isset($this->extraparams)) { $params = $params . $this->extraparams; } if ($expand[$cnt] == 0) { $res .= '<td>' . Tools::href(Config::getGlobal('dispatcher') . '?' . $params, '<img src="' . $img_expand . '" border=0>') . "</td>\n"; } else { $res .= '<td>' . Tools::href(Config::getGlobal('dispatcher') . '?' . $params, '<img src="' . $img_collapse . '" border=0>') . "</td>\n"; } } else { $res .= '<td><img src="' . $img_collapse . "\" border=0></td>\n"; } } else { /* * ********************** */ /* Tree Leaf */ /* * ********************** */ $img = $img_leaf; // the image is a leaf image by default, but it can be overridden // by putting img to something else if ($this->m_tree[$cnt]['img'] != '') { $imgname = $this->m_tree[$cnt]['img']; $img = ${$imgname}; } $res .= '<td><img src="' . $img . "\"></td>\n"; } /* * ************************************* */ /* output item text */ /* * ************************************* */ // If there's an array inside the 'label' thingee, we have an entire record. // Else, it's probably just a textual label. if (is_array($this->m_tree[$cnt]['label'])) { $label = $this->descriptor($this->m_tree[$cnt]['label']); } else { $label = $this->m_tree[$cnt]['label']; } $res .= '<td colspan=' . ($g_maxlevel - $this->m_tree[$cnt]['level']) . ' nowrap><font size=2>' . $label . "</font></td>\n"; /* * ************************************* */ /* end row with the functions */ /* * ************************************* */ if ($showactions) { $res .= '<td nowrap> '; $actions = []; if (!$this->hasFlag(self::NF_NO_ADD) && !($this->hasFlag(self::NF_TREE_NO_ROOT_ADD) && $this->m_tree[$cnt]['level'] == 0)) { $actions['add'] = Config::getGlobal('dispatcher') . '?atknodeuri=' . $this->atkNodeUri() . '&atkaction=add&atkfilter=' . $this->m_parent . '.' . $this->m_primaryKey[0] . rawurlencode("='" . $this->m_tree[$cnt]['id'] . "'"); } if ($cnt > 0) { if (!$this->hasFlag(self::NF_NO_EDIT)) { $actions['edit'] = Config::getGlobal('dispatcher') . '?atknodeuri=' . $this->atkNodeUri() . '&atkaction=edit&atkselector=' . $this->m_table . '.' . $this->m_primaryKey[0] . '=' . $this->m_tree[$cnt]['id']; } if ($this->hasFlag(self::NF_COPY) && $this->allowed('add') && !$this->hasFlag(self::NF_TREE_NO_ROOT_COPY) || $this->m_tree[$cnt]['level'] != 1 && $this->hasFlag(self::NF_COPY) && $this->allowed('add')) { $actions['copy'] = Config::getGlobal('dispatcher') . '?atknodeuri=' . $this->atkNodeUri() . '&atkaction=copy&atkselector=' . $this->m_table . '.' . $this->m_primaryKey[0] . '=' . $this->m_tree[$cnt]['id']; } if ($this->hasFlag(self::NF_NO_DELETE) || $this->hasFlag(self::NF_TREE_NO_ROOT_DELETE) && $this->m_tree[$cnt]['level'] == 1) { // Do nothing } else { $actions['delete'] = Config::getGlobal('dispatcher') . '?atknodeuri=' . $this->atkNodeUri() . '&atkaction=delete&atkselector=' . $this->m_table . '.' . $this->m_primaryKey[0] . '=' . $this->m_tree[$cnt]['id']; } } // Look for custom record actions. $recordactions = $actions; $this->collectRecordActions($this->m_tree[$cnt]['label'], $recordactions, $dummy); foreach ($recordactions as $name => $url) { if (!empty($url)) { /* dirty hack */ $atkencoded = strpos($url, '_1') > 0; $url = str_replace('%5B', '[', $url); $url = str_replace('%5D', ']', $url); $url = str_replace('_1' . '5B', '[', $url); $url = str_replace('_1' . '5D', ']', $url); if ($atkencoded) { $url = str_replace('[pk]', Tools::atkurlencode(rawurlencode($this->primaryKey($this->m_tree[$cnt]['label'])), false), $url); } else { $url = str_replace('[pk]', rawurlencode($this->primaryKey($this->m_tree[$cnt]['label'])), $url); } $stringparser = new StringParser($url); $url = $stringparser->parse($this->m_tree[$cnt]['label'], true); $res .= Tools::href($url, Tools::atktext($name), SessionManager::SESSION_NESTED) . ' '; } } $res .= '</td>'; } $res .= "</tr>\n"; } ++$cnt; } return $res; }