/** * Add an Attribute (or one of its derivatives) to the node. * * @param Attribute $attribute The attribute you want to add * @param mixed $sections The sections/tab(s) on which the attribute should be * displayed. Can be a tabname (String) or a list of * tabs (array) or "*" if the attribute should be * displayed on all tabs. * @param int $order The order at which the attribute should be displayed. * If ommitted, this defaults to 100 for the first * attribute, and 100 more for each next attribute that * is added. * * @return Attribute the attribute just added */ public function add($attribute, $sections = null, $order = 0) { $tabs = null; $column = null; $attribute->m_owner = $this->m_type; if (!$this->atkReadOptimizer()) { $this->resolveSectionsTabsOrder($sections, $tabs, $column, $order); // check for parent fieldname (treeview) if ($attribute->hasFlag($attribute::AF_PARENT)) { $this->m_parent = $attribute->fieldName(); } // check for cascading delete flag if ($attribute->hasFlag($attribute::AF_CASCADE_DELETE)) { $this->m_cascadingAttribs[] = $attribute->fieldName(); } if ($attribute->hasFlag($attribute::AF_HIDE_LIST) && !$attribute->hasFlag($attribute::AF_PRIMARY)) { if (!in_array($attribute->fieldName(), $this->m_listExcludes)) { $this->m_listExcludes[] = $attribute->fieldName(); } } if ($attribute->hasFlag($attribute::AF_HIDE_VIEW) && !$attribute->hasFlag($attribute::AF_PRIMARY)) { if (!in_array($attribute->fieldName(), $this->m_viewExcludes)) { $this->m_viewExcludes[] = $attribute->fieldName(); } } } else { // when the read optimizer is enabled there is no active tab // we circument this by putting all attributes on all tabs if ($sections !== null && is_int($sections)) { $order = $sections; } $tabs = '*'; $sections = '*'; $column = $this->getDefaultColumn(); } // NOTE: THIS SHOULD WORK. BUT, since add() is called from inside the $this // constructor, m_ownerInstance ends up being a copy of $this, rather than // a reference. Don't ask me why, it has something to do with the way PHP // handles the constructor. // To work around this, we reassign the this pointer to the attributes as // soon as possible AFTER the constructor. (the dispatcher function) $attribute->setOwnerInstance($this); if ($attribute->hasFlag(Attribute::AF_PRIMARY)) { if (!in_array($attribute->fieldName(), $this->m_primaryKey)) { $this->m_primaryKey[] = $attribute->fieldName(); } } $attribute->init(); $exist = false; if (isset($this->m_attribList[$attribute->fieldName()]) && is_object($this->m_attribList[$attribute->fieldName()])) { $exist = true; // if order is set, overwrite it with new order, last order will count if ($order != 0) { $this->m_attribIndexList[$this->m_attribList[$attribute->fieldName()]->m_index]['order'] = $order; } $attribute->m_index = $this->m_attribList[$attribute->fieldName()]->m_index; } if (!$exist) { if ($order == 0) { $this->m_attribOrder += 100; $order = $this->m_attribOrder; } if (!$this->atkReadOptimizer()) { // add new tab(s) to the tab list ("*" isn't a tab!) if ($tabs != '*') { if (!$attribute->hasFlag(Attribute::AF_HIDE_ADD)) { $this->m_tabList['add'] = isset($this->m_tabList['add']) ? Tools::atk_array_merge($this->m_tabList['add'], $tabs) : $tabs; } if (!$attribute->hasFlag(Attribute::AF_HIDE_EDIT)) { $this->m_tabList['edit'] = isset($this->m_tabList['edit']) ? Tools::atk_array_merge($this->m_tabList['edit'], $tabs) : $tabs; } if (!$attribute->hasFlag(Attribute::AF_HIDE_VIEW)) { $this->m_tabList['view'] = isset($this->m_tabList['view']) ? Tools::atk_array_merge($this->m_tabList['view'], $tabs) : $tabs; } } if ($sections != '*') { if (!$attribute->hasFlag(Attribute::AF_HIDE_ADD)) { $this->m_sectionList['add'] = isset($this->m_sectionList['add']) ? Tools::atk_array_merge($this->m_sectionList['add'], $sections) : $sections; } if (!$attribute->hasFlag(Attribute::AF_HIDE_EDIT)) { $this->m_sectionList['edit'] = isset($this->m_sectionList['edit']) ? Tools::atk_array_merge($this->m_sectionList['edit'], $sections) : $sections; } if (!$attribute->hasFlag(Attribute::AF_HIDE_VIEW)) { $this->m_sectionList['view'] = isset($this->m_sectionList['view']) ? Tools::atk_array_merge($this->m_sectionList['view'], $sections) : $sections; } } } $attribute->m_order = $order; $this->m_attribIndexList[] = array('name' => $attribute->fieldName(), 'tabs' => $tabs, 'sections' => $sections, 'order' => $attribute->m_order); $attribute->m_index = max(array_keys($this->m_attribIndexList)); // might contain gaps $attribute->setTabs($tabs); $attribute->setSections($sections); $this->m_attributeTabs[$attribute->fieldName()] = $tabs; } // Order the tablist $this->m_attribList[$attribute->fieldName()] = $attribute; $attribute->setTabs($this->m_attributeTabs[$attribute->fieldName()]); $attribute->setSections($this->m_attribIndexList[$attribute->m_index]['sections']); $attribute->setColumn($column); return $attribute; }
/** * Is attribute load required? * * @param Attribute $attr attribute * * @return bool load required? */ protected function _isAttributeLoadRequired($attr) { $attrName = $attr->fieldName(); return !$this->m_ignorePrimaryKey && in_array($attrName, $this->_getNode()->m_primaryKey) || !$this->m_ignoreForceLoad && $attr->hasFlag(Attribute::AF_FORCE_LOAD) || ($this->m_includes != null && in_array($attrName, $this->m_includes) || $this->m_excludes != null && !in_array($attrName, $this->m_excludes)) || $this->m_excludes == null && $this->m_includes == null; }
/** * Check if the currently logged-in user has the right to view, edit etc. * an attribute of a node. * * @param SecurityManager $securityMgr the security manager * @param Attribute $attr attribute reference * @param string $mode mode (add, edit, view etc.) * @param array $record record data * * @return bool true if access is granted, false if not. */ public function attribAllowed($securityMgr, $attr, $mode, $record = null) { $node = $attr->m_ownerInstance->atkNodeUri(); $attribute = $attr->fieldName(); // security disabled or user is superuser? (may do anything) if ($securityMgr->m_scheme == 'none' || !Config::getGlobal('security_attributes') || $securityMgr->hasLevel(-1) || strtolower($securityMgr->m_user['name']) == 'administrator') { $allowed = true; } else { if ($securityMgr->hasLevel(-2) || strtolower($securityMgr->m_user['name']) == 'guest') { $allowed = false; } else { // all other situations $required = $this->getAttribEntity($node, $attribute, $mode); if ($required == -1) { // No access restrictions found.. $allowed = true; } else { if ($securityMgr->m_scheme == 'level') { $allowed = $securityMgr->m_user['level'] >= $required; } else { if ($securityMgr->m_scheme == 'group') { $level = is_array($securityMgr->m_user['level']) ? $securityMgr->m_user['level'] : [$securityMgr->m_user['level']]; $required = is_array($required) ? $required : [$required]; $allowed = array_intersect($level, $required) ? true : false; if (Config::getGlobal('reverse_attributeaccess_logic', false)) { $allowed = !$allowed; } } else { // unknown scheme?? $allowed = false; } } } } } return $allowed; }