/** * Validate a record. * * @param string $mode Override the mode * @param array $ignoreList Override the ignoreList */ public function validate($mode = '', $ignoreList = array()) { // check overrides if (count($ignoreList)) { $this->setIgnoreList($ignoreList); } if ($mode != '') { $this->setMode($mode); } Tools::atkdebug('validate() with mode ' . $this->m_mode . ' for node ' . $this->m_nodeObj->atkNodeUri()); // set the record $record =& $this->m_record; // Check flags and values $db = $this->m_nodeObj->getDb(); foreach ($this->m_nodeObj->m_attribIndexList as $attribdata) { $attribname = $attribdata['name']; if (!Tools::atk_in_array($attribname, $this->m_ignoreList)) { $p_attrib = $this->m_nodeObj->m_attribList[$attribname]; $this->validateAttributeValue($p_attrib, $record); if ($p_attrib->hasFlag(Attribute::AF_PRIMARY) && !$p_attrib->hasFlag(Attribute::AF_AUTO_INCREMENT)) { $atkorgkey = $record['atkprimkey']; if ($atkorgkey == '' || $atkorgkey != $this->m_nodeObj->primaryKey($record)) { $cnt = $this->m_nodeObj->select($this->m_nodeObj->primaryKey($record))->ignoreDefaultFilters(true)->ignorePostvars(true)->getRowCount(); if ($cnt > 0) { Tools::triggerError($record, $p_attrib, 'error_primarykey_exists'); } } } // if no root elements may be added to the tree, then every record needs to have a parent! if ($p_attrib->hasFlag(Attribute::AF_PARENT) && $this->m_nodeObj->hasFlag(TreeNode::NF_TREE_NO_ROOT_ADD) && $this->m_nodeObj->m_action == 'save') { $p_attrib->m_flags |= Attribute::AF_OBLIGATORY; } // validate obligatory fields (but not the auto_increment ones, because they don't have a value yet) if ($p_attrib->hasFlag(Attribute::AF_OBLIGATORY) && !$p_attrib->hasFlag(Attribute::AF_AUTO_INCREMENT) && $p_attrib->isEmpty($record)) { Tools::atkTriggerError($record, $p_attrib, 'error_obligatoryfield'); } else { if ($p_attrib->hasFlag(Attribute::AF_UNIQUE) && !$p_attrib->hasFlag(Attribute::AF_PRIMARY) && !$p_attrib->isEmpty($record)) { $condition = $this->m_nodeObj->getTable() . ".{$attribname}='" . $db->escapeSQL($p_attrib->value2db($record)) . "'"; if ($this->m_mode != 'add') { $condition .= ' AND NOT (' . $this->m_nodeObj->primaryKey($record) . ')'; } $cnt = $this->m_nodeObj->select($condition)->ignoreDefaultFilters(true)->ignorePostvars(true)->getRowCount(); if ($cnt > 0) { Tools::atkTriggerError($record, $p_attrib, 'error_uniquefield'); } } } } } if (isset($record['atkerror']) && count($record['atkerror']) > 0) { for ($i = 0, $_i = count($record['atkerror']); $i < $_i; ++$i) { $record['atkerror'][$i]['node'] = $this->m_nodeObj->m_type; } } $this->validateUniqueFieldSets($record); if (isset($record['atkerror'])) { for ($i = 0, $_i = count($record['atkerror']); $i < $_i; ++$i) { $record['atkerror'][$i]['node'] = $this->m_nodeObj->m_type; } return false; } return true; }
/** * Override the store method of this attribute to search. * * @param Db $db * @param array $rec The record * @param string $mode * * @return bool */ public function store($db, $rec, $mode) { $resultset = []; if (is_array($rec[$this->fieldName()])) { // If the value is an array, this means we must have come from a select. // The user has selected some options, and we must process those. // First, load the records, based on the where clauses. $wheres = []; $matches = $rec[$this->fieldName()]; for ($i = 0, $_i = count($matches); $i < $_i; ++$i) { if ($matches[$i] != '') { $wheres[] = $matches[$i]; } } if (count($wheres) && $this->createSearchNodeInstance()) { $whereclause = '((' . implode(') OR (', $wheres) . '))'; $resultset = $this->m_searchnodeInstance->select($whereclause)->excludes($this->m_searchnodeInstance->m_listExcludes)->mode('admin')->getAllRows(); } } else { if (count($this->m_matches) > 0) { // We didn't come from a select, but we found something anyway. // Depending on our mode parameter, we either pass all records to // the callback, or the first for every keyword, or the very first. if ($this->m_mode == 'all') { // Pass all matches. foreach ($this->m_matches as $keyword => $matches) { for ($i = 0, $_i = count($matches); $i < $_i; ++$i) { // Make sure there are no duplicates if (!in_array($matches[$i], $resultset)) { $resultset[] = $matches[$i]; } } } } else { if ($this->m_mode == 'firstperkeyword') { // Pass first matches of all keywords. foreach ($this->m_matches as $keyword => $matches) { if (count($matches)) { $resultset[] = $matches[0]; } } } else { if ($this->m_mode == 'first') { // Pass only the first record of the first match. if (count($this->m_matches)) { $first = reset($this->m_matches); if (count($first)) { $resultset[] = $first[0]; } } } else { // We get here if one of the SELECT modes is active, but no // selection was made. Getting here means that the validate() // method above decided that presenting a selector was not // necessary. We trust that judgement, and pass all records // that were found. foreach ($this->m_matches as $keyword => $matches) { for ($i = 0, $_i = count($matches); $i < $_i; ++$i) { // Make sure there are no duplicates if (!in_array($matches[$i], $resultset)) { $resultset[] = $matches[$i]; } } } } } } } } if (count($resultset)) { if (method_exists($this->m_ownerInstance, $this->m_callback)) { $funcname = $this->m_callback; return $this->m_ownerInstance->{$funcname}($rec, $resultset); } } return true; }