/** * Internal function to get the add link for a atkOneToManyRelation. * * @param array $myrecords The load of all attributes (see comment in edit() code) * @param array $record The record that holds the value for this attribute. * @param bool $saveform Save the values of the form? * @param string $fieldprefix * @param array $params * * @return string The link to add records to the onetomany */ public function _getNestedAddLink($myrecords, $record, $saveform = true, $fieldprefix = '', $params = []) { $url = ''; if ((int) $this->m_maxRecords !== 0 && $this->m_maxRecords <= count($myrecords)) { return $url; } if (!$this->createDestination()) { return $url; } if ($this->m_destInstance->hasFlag(Node::NF_NO_ADD)) { return $url; } $filter = $this->getAddFilterString($record); if (!empty($filter)) { $params['atkfilter'] = $filter; } $onchange = ''; if (count($this->m_onchangecode)) { $onchange = 'onChange="' . $this->fieldName() . '_onChange(this);"'; $this->_renderChangeHandler($fieldprefix); } $add_url = $this->getAddURL($params); $label = $this->getAddLabel(); return Tools::href($add_url, $label, SessionManager::SESSION_NESTED, $saveform, $onchange . ' class="atkonetomanyrelation"'); }
/** * Get the add link to add to the admin header. * * @return string HTML code with link to the add action of the node (if allowed) */ public function getAddLink() { $atk = Atk::getInstance(); $node = $atk->atkGetNode($this->invoke('getAddNodeType')); if (!$node->hasFlag(Node::NF_NO_ADD) && $node->allowed('add')) { $label = $node->text('link_' . $node->m_type . '_add', null, '', '', true); if (empty($label)) { // generic text $label = Tools::atktext('add', 'atk'); } if ($node->hasFlag(Node::NF_ADD_LINK)) { $addurl = $this->invoke('getAddUrl', $node); return Tools::href($addurl, $label, SessionManager::SESSION_NESTED); } } return ''; }
/** * 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; }
/** * Creates and returns the auto edit/view links. * * @param string $id The field html id * @param string $name The field html name * @param string $filter Filter that we want to apply on the destination node * * @return array The HTML code for the autolink links */ public function getRelationAutolink($id, $name, $filter) { $autolink = []; if ($this->hasFlag(self::AF_RELATION_AUTOLINK)) { // auto edit/view link $page = Page::getInstance(); $page->register_script(Config::getGlobal('assets_url') . 'javascript/class.atkmanytoonerelation.js'); $sm = SessionManager::getInstance(); if ($this->m_destInstance->allowed('edit')) { $editlink = $sm->sessionUrl(Tools::dispatch_url($this->getAutoLinkDestination(), 'edit', array('atkselector' => 'REPLACEME')), SessionManager::SESSION_NESTED); $autolink['edit'] = "<a href='javascript:atkSubmit(mto_parse(\"" . Tools::atkurlencode($editlink) . '", document.entryform.' . $id . ".value),true)' class='atkmanytoonerelation atkmanytoonerelation-link'>" . Tools::atktext('edit') . '</a>'; } if ($this->m_destInstance->allowed('add')) { $autolink['add'] = ' ' . Tools::href(Tools::dispatch_url($this->getAutoLinkDestination(), 'add', array('atkpkret' => $name, 'atkfilter' => $this->m_useFilterForAddLink && $filter != '' ? $filter : '')), Tools::atktext('new'), SessionManager::SESSION_NESTED, true, 'class="atkmanytoonerelation atkmanytoonerelation-link"'); } } return $autolink; }
/** * Returns a displayable string for this value. * * @param array $record The record that holds the value for this attribute * @param string $mode The display mode ("view" for viewpages, or "list" * for displaying in recordlists, "edit" for * displaying in editscreens, "add" for displaying in * add screens. "csv" for csv files. Applications can * use additional modes. * * @return string a displayable string for this value */ public function display($record, $mode) { $result = ''; if ($this->createDestination() && Tools::atk_value_in_array($record[$this->fieldName()])) { $recordset = []; $remotekey = $this->getRemoteKey(); for ($i = 0; $i < count($record[$this->fieldName()]); ++$i) { $rec = $record[$this->fieldName()][$i][$remotekey]; if (!is_array($rec)) { $selector = $this->m_destInstance->m_table . '.' . $this->m_destInstance->primaryKeyField() . "= '{$rec}'"; $rec = $this->m_destInstance->select($selector)->includes($this->m_destInstance->descriptorFields())->getFirstRow(); $descr = $this->m_destInstance->descriptor($rec); } else { $descr = $this->m_destInstance->descriptor($rec); } if ($this->hasFlag(self::AF_MANYTOMANY_DETAILVIEW) && $this->m_destInstance->allowed('view')) { $descr = Tools::href(Tools::dispatch_url($this->m_destination, 'view', array('atkselector' => $this->getDestination()->primaryKey($rec))), $descr, SessionManager::SESSION_NESTED); } $recordset[] = $descr; } if (!in_array($mode, array('csv', 'plain'))) { $result = '<ul><li>' . implode('<li>', $recordset) . '</ul>'; } else { $result = implode(', ', $recordset); } } else { if (!in_array($mode, array('csv', 'plain'))) { $result = $this->text('none'); } } return $result; }
/** * Return a piece of html code to edit the attribute. * * @param array $record Current record * @param string $fieldprefix The fieldprefix to put in front of the name * of any html form element for this attribute. * @param string $mode The mode we're in ('add' or 'edit') * * @return string piece of html code */ public function edit($record, $fieldprefix, $mode) { $this->createDestination(); $this->createLink(); $result = ''; $selectedPk = $this->getSelectedRecords($record); $recordset = $this->_getSelectableRecords($record, $mode); $total_records = count($recordset); if ($total_records > 0) { $page = Page::getInstance(); $page->register_script(Config::getGlobal('assets_url') . 'javascript/class.atkprofileattribute.js'); if (!$this->hasFlag(self::AF_MANYBOOL_NO_TOOLBAR)) { $result .= '<div align="left"> [<a href="javascript:void(0)" onclick="profile_checkAll(\'' . $this->getHtmlId($fieldprefix) . '\'); return false;">' . Tools::atktext('check_all', 'atk') . '</a> <a href="javascript:void(0)" onclick="profile_checkNone(\'' . $this->getHtmlId($fieldprefix) . '\'); return false;">' . Tools::atktext('check_none', 'atk') . '</a> <a href="javascript:void(0)" onclick="profile_checkInvert(\'' . $this->getHtmlId($fieldprefix) . '\'); return false;">' . Tools::atktext('invert_selection', 'atk') . '</a>]</div>'; } $result .= '<div>'; for ($i = 0; $i < $total_records; ++$i) { $detailLink = ''; $sel = ''; $onchange = ''; $inputId = $this->getHtmlId($fieldprefix) . '_' . $i; if (in_array($this->m_destInstance->primaryKey($recordset[$i]), $selectedPk)) { $sel = 'checked'; if ($this->getShowDetailsLink() && !$this->m_linkInstance->hasFlag(Node::NF_NO_EDIT) && $this->m_linkInstance->allowed('edit')) { $localPkAttr = $this->getOwnerInstance()->getAttribute($this->getOwnerInstance()->primaryKeyField()); $localValue = $localPkAttr->value2db($record); $remotePkAttr = $this->getDestination()->getAttribute($this->getDestination()->primaryKeyField()); $remoteValue = $remotePkAttr->value2db($recordset[$i]); $selector = $this->m_linkInstance->m_table . '.' . $this->getLocalKey() . '=' . $localValue . '' . ' AND ' . $this->m_linkInstance->m_table . '.' . $this->getRemoteKey() . "='" . $remoteValue . "'"; $detailLink = Tools::href(Tools::dispatch_url($this->m_link, 'edit', array('atkselector' => $selector)), '[' . Tools::atktext('edit', 'atk') . ']', SessionManager::SESSION_NESTED, true); } } if (count($this->m_onchangecode)) { $onchange = ' onChange="' . $inputId . '_onChange(this);"'; $this->_renderChangeHandler($fieldprefix, '_' . $i); } $value = $recordset[$i][$this->m_destInstance->primaryKeyField()]; $css = $this->getCSSClassAttribute('atkcheckbox'); $label = $this->m_destInstance->descriptor($recordset[$i]); $result .= '<div>'; $result .= ' <input type="checkbox" id="' . $inputId . '" name="' . $this->getHtmlName($fieldprefix) . '[][' . $this->getRemoteKey() . ']" value="' . $value . '" ' . $css . ' ' . $sel . $onchange . ' />'; $result .= ' <label for="' . $inputId . '">' . $label . '</label>'; if ($detailLink != '') { $result .= ' ' . $detailLink; } $result .= '</div>'; } $result .= '</div>'; } else { $nodename = $this->m_destInstance->m_type; $modulename = $this->m_destInstance->m_module; $result .= Tools::atktext('select_none', $modulename, $nodename) . ' '; } if ($this->hasFlag(self::AF_MANYBOOL_AUTOLINK) && $this->m_destInstance->allowed('add')) { $result .= Tools::href(Tools::dispatch_url($this->m_destination, 'add'), $this->getAddLabel(), SessionManager::SESSION_NESTED) . "\n"; } return $result; }
/** * Get records for a recordlist without actually rendering the recordlist. * * @param array $recordset the list of records * @param array $actions the default actions array * @param array $suppressList fields we don't display * * @return string The rendered recordlist */ private function getRecordlistData($recordset, $actions, $suppressList = array()) { $grid = $this->getGrid(); $page = $this->getPage(); $sm = SessionManager::getInstance(); $edit = $grid->isEditing(); $page->register_script(Config::getGlobal('assets_url') . 'javascript/recordlist.js'); $listName = $grid->getName(); $defaulthighlight = Config::getGlobal('highlight'); $selectcolor = Config::getGlobal('select'); /* retrieve list array */ $list = $this->listArray($recordset, '', $actions, $suppressList); /* Check if some flags are still valid or not... */ $hasMRA = $grid->hasFlag(DataGrid::MULTI_RECORD_ACTIONS); if ($hasMRA && (count($list['mra']) == 0 || count($list['rows']) == 0)) { $hasMRA = false; } $hasSearch = $grid->hasFlag(DataGrid::SEARCH) && !$grid->isEditing(); if ($hasSearch && count($list['search']) == 0) { $hasSearch = false; } if ($grid->hasFlag(DataGrid::MULTI_RECORD_PRIORITY_ACTIONS) && (count($grid->getNode()->m_priority_actions) == 0 || count($list['rows']) == 0)) { $grid->removeFlag(DataGrid::MULTI_RECORD_PRIORITY_ACTIONS); } else { if ($grid->hasFlag(DataGrid::MULTI_RECORD_PRIORITY_ACTIONS)) { $grid->removeFlag(DataGrid::MULTI_RECORD_ACTIONS); if ($grid->getNode()->m_priority_max == 0) { $grid->getNode()->m_priority_max = $grid->getNode()->m_priority_min + count($list['rows']) - 1; } } } $hasActionCol = $this->_hasActionColumn($list, $hasSearch); $orientation = Config::getGlobal('recordlist_orientation'); /* * *********** */ /* HEADER ROW */ /* * *********** */ $headercols = []; if ($hasActionCol && count($list['rows']) == 0) { if ($orientation == 'left' || $orientation == 'both') { // empty cell above search button, if zero rows // if $orientation is empty, no search button is shown, so no empty cell is needed $headercols[] = array('content' => ' '); } } if (!$edit && ($hasMRA || $grid->hasFlag(DataGrid::MULTI_RECORD_PRIORITY_ACTIONS))) { $headercols[] = array('content' => ''); // Empty leader on top of mra action list. } if (($orientation == 'left' || $orientation == 'both') && ($hasActionCol && count($list['rows']) > 0)) { $headercols[] = array('content' => ''); } foreach (array_values($list['heading']) as $head) { if (!$grid->hasFlag(DataGrid::SORT) || empty($head['order'])) { $headercols[] = array('content' => $head['title']); } else { $call = $grid->getUpdateCall(array('atkorderby' => $head['order'], 'atkstartat' => 0)); $headercols[] = array('content' => $this->_getHeadingAnchorHtml($call, $head['title'])); } } if (($orientation == 'right' || $orientation == 'both') && ($hasActionCol && count($list['rows']) > 0)) { $headercols[] = array('content' => ''); } if ($hasActionCol && count($list['rows']) == 0) { if ($orientation == 'right' || $orientation == 'both') { // empty cell above search button, if zero rows // if $orientation is empty, no search button is shown, so no empty cell is needed $headercols[] = array('content' => ' '); } } /* * *********** */ /* SORT ROW */ /* * *********** */ $sortcols = []; $sortstart = ''; $sortend = ''; if ($grid->hasFlag(DataGrid::EXTENDED_SORT)) { $call = htmlentities($grid->getUpdateCall(array('atkstartat' => 0), [], 'ATK.DataGrid.extractExtendedSortOverrides')); $button = '<input type="button" value="' . Tools::atktext('sort') . '" onclick="' . $call . '">'; if (!$edit && ($hasMRA || $grid->hasFlag(DataGrid::MULTI_RECORD_PRIORITY_ACTIONS))) { $sortcols[] = array('content' => ''); // Empty leader on top of mra action list. } if ($orientation == 'left' || $orientation == 'both') { $sortcols[] = array('content' => $button); } foreach (array_keys($list['heading']) as $key) { if (isset($list['sort'][$key])) { $sortcols[] = array('content' => $list['sort'][$key]); } } if ($orientation == 'right' || $orientation == 'both') { $sortcols[] = array('content' => $button); } } /* * *********** */ /* SEARCH ROW */ /* * *********** */ $searchcols = []; $searchstart = ''; $searchend = ''; if ($hasSearch) { $call = htmlentities($grid->getUpdateCall(array('atkstartat' => 0), [], 'ATK.DataGrid.extractSearchOverrides')); $buttonType = $grid->isEmbedded() ? 'button' : 'submit'; $button = '<input type="' . $buttonType . '" class="btn btn-default btn_search" value="' . Tools::atktext('search') . '" onclick="' . $call . ' return false;">'; if ($grid->hasFlag(DataGrid::EXTENDED_SEARCH)) { $button .= ' ' . Tools::href(Config::getGlobal('dispatcher') . '?atknodeuri=' . $grid->getActionNode()->atkNodeUri() . '&atkaction=' . $grid->getActionNode()->getExtendedSearchAction(), '(' . Tools::atktext('search_extended') . ')', SessionManager::SESSION_NESTED); } $button = '<div class="search-buttons">' . $button . '</div>'; // $searchstart = '<a name="searchform"></a>'; $searchstart = ''; if (!$edit && ($hasMRA || $grid->hasFlag(DataGrid::MULTI_RECORD_PRIORITY_ACTIONS))) { $searchcols[] = array('content' => ''); } if ($orientation == 'left' || $orientation == 'both') { $searchcols[] = array('content' => $button); } foreach (array_keys($list['heading']) as $key) { if (isset($list['search'][$key])) { $searchcols[] = array('content' => $list['search'][$key]); } else { $searchcols[] = array('content' => ''); } } if ($orientation == 'right' || $orientation == 'both') { $searchcols[] = array('content' => $button); } } /* * **************************************** */ /* MULTI-RECORD-(PRIORITY-)ACTIONS FORM DATA */ /* * **************************************** */ $liststart = ''; $listend = ''; if (!$edit && ($hasMRA || $grid->hasFlag(DataGrid::MULTI_RECORD_PRIORITY_ACTIONS))) { $page->register_script(Config::getGlobal('assets_url') . 'javascript/formselect.js'); if ($hasMRA) { $liststart .= '<script language="javascript" type="text/javascript">var ' . $listName . ' = new Object();</script>'; } } /* * ***** */ /* ROWS */ /* * ***** */ $records = []; $keys = array_keys($actions); $actionurl = count($actions) > 0 ? $actions[$keys[0]] : ''; $actionloader = "rl_a['" . $listName . "'] = {};"; $actionloader .= "\nrl_a['" . $listName . "']['base'] = '" . $sm->sessionVars($grid->getActionSessionStatus(), 1, $actionurl) . "';"; $actionloader .= "\nrl_a['" . $listName . "']['embed'] = " . ($grid->isEmbedded() ? 'true' : 'false') . ';'; for ($i = 0, $_i = count($list['rows']); $i < $_i; ++$i) { $record = []; /* Special rowColor method makes it possible to change the row color based on the record data. * the method can return a simple value (which will be used for the normal row color), or can be * an array, in which case the first element will be the normal row color, and the second the mouseover * row color, example: function rowColor(&$record, $num) { return array('red', 'blue'); } */ $method = 'rowColor'; $bgn = ''; $bgh = $defaulthighlight; if (method_exists($grid->getNode(), $method)) { $bgn = $grid->getNode()->{$method}($recordset[$i], $i); if (is_array($bgn)) { list($bgn, $bgh) = $bgn; } } $record['class'] = $grid->getNode()->rowClass($recordset[$i], $i); foreach ($grid->getNode()->getRowClassCallback() as $callback) { $record['class'] .= ' ' . call_user_func_array($callback, array($recordset[$i], $i)); } /* alternate colors of rows */ $record['background'] = $bgn; $record['highlight'] = $bgh; $record['rownum'] = $i; $record['id'] = $listName . '_' . $i; $record['type'] = $list['rows'][$i]['type']; /* multi-record-priority-actions -> priority selection */ if (!$edit && $grid->hasFlag(DataGrid::MULTI_RECORD_PRIORITY_ACTIONS)) { $select = '<select name="' . $listName . '_atkselector[]" class="form-control select-standard">' . '<option value="' . htmlentities($list['rows'][$i]['selector']) . '"></option>'; for ($j = $grid->getNode()->m_priority_min; $j <= $grid->getNode()->m_priority_max; ++$j) { $select .= '<option value="' . $j . '">' . $j . '</option>'; } $select .= '</select>'; $record['cols'][] = array('content' => $select, 'type' => 'mrpa'); } elseif (!$edit && $hasMRA) { if (count($list['rows'][$i]['mra']) > 0) { switch ($grid->getMRASelectionMode()) { case Node::MRA_SINGLE_SELECT: $inputHTML = '<input type="radio" name="' . $listName . '_atkselector[]" value="' . $list['rows'][$i]['selector'] . '" class="atkradiobutton" onclick="if (this.disabled) this.checked = false">'; break; case Node::MRA_NO_SELECT: $inputHTML = '<input type="checkbox" disabled="disabled" checked="checked">' . '<input type="hidden" name="' . $listName . '_atkselector[]" value="' . $list['rows'][$i]['selector'] . '">'; break; case Node::MRA_MULTI_SELECT: default: $inputHTML = '<input type="checkbox" name="' . $listName . '_atkselector[' . $i . ']" value="' . $list['rows'][$i]['selector'] . '" class="atkcheckbox" onclick="if (this.disabled) this.checked = false">'; } $record['cols'][] = array('content' => $inputHTML . ' <script language="javascript" type="text/javascript">' . $listName . '["' . htmlentities($list['rows'][$i]['selector']) . '"] = new Array("' . implode($list['rows'][$i]['mra'], '","') . '"); </script>', 'type' => 'mra'); } else { $record['cols'][] = array('content' => ''); } } else { if ($edit && $list['rows'][$i]['edit']) { $liststart .= '<input type="hidden" name="atkdatagriddata_AE_' . $i . '_AE_atkprimkey" value="' . htmlentities($list['rows'][$i]['selector']) . '">'; } } $str_actions = '<span class="actions">'; $actionloader .= "\nrl_a['" . $listName . "'][" . $i . '] = {};'; $icons = Config::getGlobal('recordlist_icons'); foreach ($list['rows'][$i]['actions'] as $name => $url) { if (substr($url, 0, 11) == 'javascript:') { $call = substr($url, 11); $actionloader .= "\nrl_a['{$listName}'][{$i}]['{$name}'] = function() { {$call}; };"; } else { $actionloader .= "\nrl_a['{$listName}'][{$i}]['{$name}'] = '{$url}';"; } $module = $grid->getNode()->m_module; $nodetype = $grid->getNode()->m_type; $actionKeys = array('action_' . $module . '_' . $nodetype . '_' . $name, 'action_' . $nodetype . '_' . $name, 'action_' . $name, $name); $link = htmlentities($this->text($actionKeys)); if ($icons == true) { $normalizedName = strtolower(str_replace('-', '_', $name)); $icon = Config::get($module, 'icon_' . $nodetype . '_' . $normalizedName, false); if (!$icon) { $icon = Config::getGlobal('icon_' . $nodetype . '_' . $normalizedName, false); } if (!$icon) { $icon = Config::getGlobal('icon_' . $normalizedName, false); } if ($icon) { $link = '<i class="' . $icon . '" title="' . $link . '"></i>'; } } $confirmtext = 'false'; if (Config::getGlobal('recordlist_javascript_delete') && $name == 'delete') { $confirmtext = "'" . $grid->getNode()->confirmActionText($name) . "'"; } $str_actions .= $this->_renderRecordActionLink($url, $link, $listName, $i, $name, $confirmtext); } $str_actions .= '</span>'; /* actions (left) */ if ($orientation == 'left' || $orientation == 'both') { if (!empty($list['rows'][$i]['actions'])) { $record['cols'][] = array('content' => $str_actions, 'type' => 'actions'); } else { if ($hasActionCol) { $record['cols'][] = array('content' => ''); } } } /* columns */ foreach ($list['rows'][$i]['data'] as $html) { $record['cols'][] = array('content' => $html, 'type' => 'data'); } /* actions (right) */ if ($orientation == 'right' || $orientation == 'both') { if (!empty($list['rows'][$i]['actions'])) { $record['cols'][] = array('content' => $str_actions, 'type' => 'actions'); } else { if ($hasActionCol) { $record['cols'][] = array('content' => ''); } } } $records[] = $record; } $page->register_scriptcode($actionloader); $this->m_actionloader = $actionloader; /*************/ /* TOTAL ROW */ /*************/ $totalcols = []; if (count($list['total']) > 0) { if (!$edit && ($hasMRA || $grid->hasFlag(DataGrid::MULTI_RECORD_PRIORITY_ACTIONS))) { $totalcols[] = array('content' => ''); } if (($orientation == 'left' || $orientation == 'both') && ($hasActionCol && count($list['rows']) > 0)) { $totalcols[] = array('content' => ''); } foreach (array_keys($list['heading']) as $key) { $totalcols[] = array('content' => isset($list['total'][$key]) ? $list['total'][$key] : ''); } if (($orientation == 'right' || $orientation == 'both') && ($hasActionCol && count($list['rows']) > 0)) { $totalcols[] = array('content' => ''); } } /* * ********************************************** */ /* MULTI-RECORD-PRIORITY-ACTION FORM (CONTINUED) */ /* * ********************************************** */ $mra = ''; if (!$edit && $grid->hasFlag(DataGrid::MULTI_RECORD_PRIORITY_ACTIONS)) { $target = $sm->sessionUrl(Config::getGlobal('dispatcher') . '?atknodeuri=' . $grid->getActionNode()->atkNodeUri(), SessionManager::SESSION_NESTED); /* multiple actions -> dropdown */ if (count($grid->getNode()->m_priority_actions) > 1) { $mra = '<select name="' . $listName . '_atkaction" class="form-control select-standard">' . '<option value="">' . Tools::atktext('with_selected') . ':</option>'; foreach ($grid->getNode()->m_priority_actions as $name) { $mra .= '<option value="' . $name . '">' . Tools::atktext($name) . '</option>'; } $mra .= '</select> ' . $this->getCustomMraHtml() . '<input type="button" class="btn" value="' . Tools::atktext('submit') . '" onclick="atkSubmitMRPA(\'' . $listName . '\', this.form, \'' . $target . '\')">'; } else { $mra = $this->getCustomMraHtml() . '<input type="hidden" name="' . $listName . '_atkaction" value="' . $grid->getNode()->m_priority_actions[0] . '">' . '<input type="button" class="btn" value="' . Tools::atktext($grid->getNode()->m_priority_actions[0]) . '" onclick="atkSubmitMRPA(\'' . $listName . '\', this.form, \'' . $target . '\')">'; } } elseif (!$edit && $hasMRA) { $postvars = $grid->getNode()->m_postvars; $target = $sm->sessionUrl(Config::getGlobal('dispatcher') . '?atknodeuri=' . $grid->getNode()->atkNodeUri() . '&atktarget=' . (!empty($postvars['atktarget']) ? $postvars['atktarget'] : '') . '&atktargetvar=' . (!empty($postvars['atktargetvar']) ? $postvars['atktargetvar'] : '') . '&atktargetvartpl=' . (!empty($postvars['atktargetvartpl']) ? $postvars['atktargetvartpl'] : ''), SessionManager::SESSION_NESTED); $mra = count($list['rows']) > 1 && $grid->getMRASelectionMode() == Node::MRA_MULTI_SELECT ? '<a href="javascript:void(0)" onclick="updateSelection(\'' . $listName . '\', $(this).up(\'form\'), \'all\')">' . Tools::atktext('select_all') . '</a> | ' . '<a href="javascript:void(0)" onclick="updateSelection(\'' . $listName . '\', $(this).up(\'form\'), \'none\')">' . Tools::atktext('deselect_all') . '</a> | ' . '<a href="javascript:void(0)" onclick="updateSelection(\'' . $listName . '\', $(this).up(\'form\'), \'invert\')">' . Tools::atktext('select_invert') . '</a> ' : ''; $module = $grid->getNode()->m_module; $nodetype = $grid->getNode()->m_type; /* multiple actions -> dropdown */ if (count($list['mra']) > 1) { $default = $this->getGrid()->getMRADefaultAction(); $mra .= '<select name="' . $listName . '_atkaction" onchange="javascript:updateSelectable(\'' . $listName . '\', this.form)" class="form-control select-standard">' . '<option value="">' . Tools::atktext('with_selected') . '</option>'; foreach ($list['mra'] as $name) { if ($grid->getNode()->allowed($name)) { $actionKeys = array('action_' . $module . '_' . $nodetype . '_' . $name, 'action_' . $nodetype . '_' . $name, 'action_' . $name, $name); $mra .= '<option value="' . $name . '"'; if ($default == $name) { $mra .= 'selected="selected"'; } $mra .= '>' . Tools::atktext($actionKeys, $grid->getNode()->m_module, $grid->getNode()->m_type) . '</option>'; } } $embedded = $this->getGrid()->isEmbedded() ? 'true' : 'false'; $mra .= '</select> ' . $this->getCustomMraHtml() . '<input type="button" class="btn" value="' . Tools::atktext('submit') . '" onclick="atkSubmitMRA(\'' . $listName . '\', this.form, \'' . $target . '\', ' . $embedded . ', false)">'; } else { if ($grid->getNode()->allowed($list['mra'][0])) { $name = $list['mra'][0]; $actionKeys = array('action_' . $module . '_' . $nodetype . '_' . $name, 'action_' . $nodetype . '_' . $name, 'action_' . $name, $name); $embedded = $this->getGrid()->isEmbedded() ? 'true' : 'false'; $mra .= '<input type="hidden" name="' . $listName . '_atkaction" value="' . $name . '">' . $this->getCustomMraHtml() . '<input type="button" class="btn" value="' . Tools::atktext($actionKeys, $grid->getNode()->m_module, $grid->getNode()->m_type) . '" onclick="atkSubmitMRA(\'' . $listName . '\', this.form, \'' . $target . '\', ' . $embedded . ', false)">'; } } } else { if ($edit) { $mra = '<input type="button" class="btn" value="' . Tools::atktext('save') . '" onclick="' . htmlentities($this->getGrid()->getSaveCall()) . '">'; } } $recordListData = array('rows' => $records, 'header' => $headercols, 'search' => $searchcols, 'sort' => $sortcols, 'total' => $totalcols, 'searchstart' => $searchstart, 'searchend' => $searchend, 'sortstart' => $sortstart, 'sortend' => $sortend, 'liststart' => $liststart, 'listend' => $listend, 'listid' => $listName, 'mra' => $mra, 'editing' => $this->getGrid()->isEditing()); // print_r($recordListData); return $recordListData; }
/** * Sets the sortorder options for this attribute which is used in recordlists * and search actions. * * @param ColumnConfig $columnConfig The config that contains options for * extended sorting and grouping to a * recordlist. * @param string $fieldprefix The prefix of the attribute on HTML forms * @param DataGrid $grid The grid that this attribute lives on. * * @return string HTML */ public function sortOrder($columnConfig, $fieldprefix = '', $grid = null) { $fieldname = $this->fieldName(); $currentOrder = $columnConfig->getOrder($fieldname); $res = ''; if ($currentOrder > 0) { $direction = $columnConfig->getSortDirection($this->fieldName()) == 'desc' ? 'asc' : 'desc'; if ($grid == null) { $res = Tools::href(Config::getGlobal('dispatcher') . '?' . $columnConfig->getUrlCommand($fieldname, $direction), Tools::atktext('column_' . $direction)) . ' '; } else { $call = $grid->getUpdateCall($columnConfig->getUrlCommandParams($fieldname, $direction)); $res = '<a href="javascript:void(0)" onclick="' . htmlentities($call) . '">' . $this->text('column_' . $direction) . '</a>'; } } $res .= '<select class="form-control select-standard" name="atkcolcmd[][setorder][' . $fieldprefix . $fieldname . ']">'; $res .= '<option value="">'; for ($i = 1; $i < 6; ++$i) { $selected = $currentOrder == $i ? 'selected' : ''; $res .= '<option value="' . $i . '" ' . $selected . '>' . $i; } $res .= '</select>'; return $res; }
/** * The default view link. * * @param array $record * * @return string */ protected function getViewActionLink($record) { return Tools::href(Tools::dispatch_url($this->getDestination()->atkNodeUri(), 'view', array('atkselector' => $this->getDestination()->primaryKey($record))), $this->text('view'), SessionManager::SESSION_NESTED, true, 'class="atkmanytomanyselectrelation-link"'); }