/** * Has module category clearance * * @param integer $category_id, ID of category we test * @param integer $clearance, default is CLEARANCE_MODULE_VIEW * @param string $module : the module codename * @return boolean * @access public */ function hasModuleCategoryClearance($category_id, $clearance = CLEARANCE_MODULE_VIEW, $module = false) { if (!SensitiveIO::isPositiveInteger($category_id)) { return false; } //get denied cats (including deleted cats) $cats_denied = $this->getRootModuleCategoriesDenied($module); if ($this->hasAdminClearance(CLEARANCE_ADMINISTRATION_EDITVALIDATEALL)) { if (in_array($category_id, $cats_denied)) { return false; } return true; } $a_category_lineage = CMS_moduleCategories_catalog::getLineageOfCategory($category_id); $a_category_lineage = array_reverse($a_category_lineage); switch ($clearance) { case CLEARANCE_MODULE_VIEW: $matching_cats = $this->getRootModuleCategoriesReadable($module); break; case CLEARANCE_MODULE_EDIT: $cats_denied = array_merge((array) $cats_denied, (array) $this->getRootModuleCategoriesReadable($module)); $matching_cats = $this->getRootModuleCategoriesWritable($module); break; case CLEARANCE_MODULE_MANAGE: $cats_denied = array_merge((array) $cats_denied, (array) $this->getRootModuleCategoriesReadable($module)); $cats_denied = array_merge((array) $cats_denied, (array) $this->getRootModuleCategoriesWritable($module)); $matching_cats = $this->getRootModuleCategoriesManagable($module); break; } foreach ($a_category_lineage as $aCat) { if (is_array($matching_cats) && in_array($aCat, $matching_cats)) { return true; } elseif (in_array($aCat, $cats_denied)) { return false; } } //no match found so we return false for security return false; }
/** * Gives a string representing the lineage of a category whose ID was given * From oldest ancestor to itself, imploded with ; (semicolon) by Default * * @access public * @param integer $category_id, the category ID * @param string $separator, the separator we want to use instead of semicolon (;) * @return string * @static */ static function getLineageOfCategoryAsString($category_id, $separator = ";") { static $modulesCategories; if (!$separator) { CMS_grandFather::raiseError("Bad separator given : {$separator}"); return false; } if (!SensitiveIO::isPositiveInteger($category_id)) { CMS_grandFather::raiseError("Bad category ID given : {$category_id}"); return false; } if (!isset($modulesCategories[$category_id])) { $modulesCategories[$category_id] = (string) @implode($separator, CMS_moduleCategories_catalog::getLineageOfCategory($category_id)); } return $modulesCategories[$category_id]; }
/** * For a given category, return options tag list (for a select tag) of all sub categories * * @param array $values : parameters values array(parameterName => parameterValue) in : * selected : the category id which is selected (optional) * usedcategories : display only used categories (optional, default : true) * usedbyitemsids : display only categories used by items list. Accept array of items ids or list of ids (comma separated). Used only if 'usedcategories' is active (optional, default : false) * editableonly : display only editable categories (optional, default : false) * root : the category id to use as root (optional) * crosslanguage : returned categories do not filter by language and return all categories even if current language has no label (default : false) * @param multidimentionnal array $tags : xml2Array content of atm-function tag (nothing for this one) * @return string : options tag list * @access public */ function selectOptions($values, $tags) { global $cms_language; if (!isset($values['usedcategories']) || $values['usedcategories'] == 'true' || $values['usedcategories'] == '1') { $usedCategories = true; if (isset($values['usedbyitemsids']) && is_array($values['usedbyitemsids'])) { $usedByItemsIds = $values['usedbyitemsids']; } elseif (isset($values['usedbyitemsids']) && is_string($values['usedbyitemsids'])) { $usedByItemsIds = explode(',', $values['usedbyitemsids']); } else { $usedByItemsIds = false; } } else { $usedCategories = false; $usedByItemsIds = false; } $disableCategories = array(); if (isset($values['disable'])) { $disableCategories = explode(';', $values['disable']); if (count($disableCategories) == 1) { $disableCategories = explode(',', $values['disable']); } } if (!isset($values['editableonly']) || $values['editableonly'] == 'false' || $values['editableonly'] == '0') { $editableOnly = false; } else { $editableOnly = true; } if (!isset($values['crosslanguage']) || $values['crosslanguage'] == 'false' || $values['crosslanguage'] == '0') { $crossLanguage = false; } else { $crossLanguage = true; } if (isset($values['root']) && sensitiveIO::isPositiveInteger($values['root'])) { $rootCategory = $values['root']; } else { $rootCategory = false; } $maxlevel = isset($values['maxlevel']) ? (int) $values['maxlevel'] : 0; $categories = $this->getAllCategoriesAsArray($cms_language, $usedCategories, false, $editableOnly, $rootCategory, false, $usedByItemsIds, $crossLanguage); $return = ""; if (is_array($categories) && $categories) { //natsort objects by name case insensitive if (isset($values['sort']) && (io::strtolower($values['sort']) == 'asc' || io::strtolower($values['sort']) == 'desc')) { uasort($categories, array('CMS_object_categories', '_natecasecomp')); if (io::strtolower($values['sort']) == 'desc') { $categories = array_reverse($categories, true); } } foreach ($categories as $catID => $catLabel) { // Disable categories if (is_array($disableCategories) && $disableCategories) { $lineage = CMS_moduleCategories_catalog::getLineageOfCategory($catID); foreach ($disableCategories as $disableCategory) { if (SensitiveIO::isPositiveInteger($disableCategory) && in_array($disableCategory, $lineage)) { continue; } } } //max level if ($maxlevel) { if (substr_count($catLabel, '- ') >= $maxlevel) { continue; } } $selected = isset($values['selected']) && $catID == $values['selected'] ? ' selected="selected"' : ''; $return .= '<option title="' . io::htmlspecialchars($catLabel) . '" value="' . $catID . '"' . $selected . '>' . $catLabel . '</option>'; } } return $return; }
/** * Writes into persistence (MySQL for now), along with base data. * * @return boolean true on success, false on failure * @access public */ function writeToPersistence() { if (!$this->_uuid) { $this->_uuid = io::uuid(); } $isNew = $this->_categoryID === NULL; // Inform modules of the object creation $modules = CMS_modulesCatalog::getAll('id'); foreach ($modules as $codename => $module) { if (method_exists($module, 'moduleCategoryPreSave')) { $module->moduleCategoryPreSave($this, $isNew); } } // Prepare SQL $sql_fields = "\n\t\t\tmodule_mca='" . SensitiveIO::sanitizeSQLString($this->_moduleCodename) . "',\n\t\t\troot_mca='" . SensitiveIO::sanitizeSQLString($this->_rootID) . "',\n\t\t\tparent_mca='" . SensitiveIO::sanitizeSQLString($this->_parentID) . "',\n\t\t\torder_mca='" . SensitiveIO::sanitizeSQLString($this->_order) . "',\n\t\t\ticon_mca='" . SensitiveIO::sanitizeSQLString($this->_icon) . "',\n\t\t\tuuid_mca='" . SensitiveIO::sanitizeSQLString($this->_uuid) . "',\n\t\t\tprotected_mca='" . ($this->_protected ? 1 : 0) . "'\n\t\t"; // Finish SQL if ($this->_categoryID) { $sql = "\n\t\t\t\tupdate\n\t\t\t\t\tmodulesCategories\n\t\t\t\tset\n\t\t\t\t\t" . $sql_fields . "\n\t\t\t\twhere\n\t\t\t\t\tid_mca='" . $this->_categoryID . "'\n\t\t\t"; } else { $sql = "\n\t\t\t\tinsert into\n\t\t\t\t\tmodulesCategories\n\t\t\t\tset\n\t\t\t\t\t" . $sql_fields; } $q = new CMS_query($sql); if ($q->hasError()) { return false; } elseif (!$this->_categoryID) { $this->_categoryID = $q->getLastInsertedID(); } //reset catalog info CMS_moduleCategories_catalog::getParentIdOf($this->_categoryID, true); // Update lineage again with current ID $lineage = (string) @implode(';', CMS_moduleCategories_catalog::getLineageOfCategory($this->_categoryID, true)); if ($this->_lineageFromDB != $lineage) { $sql = "\n\t\t\t\tupdate\n\t\t\t\t\tmodulesCategories\n\t\t\t\tset\n\t\t\t\t\tlineage_mca='" . SensitiveIO::sanitizeSQLString($lineage) . "'\n\t\t\t\twhere\n\t\t\t\t\tid_mca='" . $this->_categoryID . "'\n\t\t\t"; $q = new CMS_query($sql); //update siblings lineage if any if ($this->hasSiblings()) { $siblings = $this->getSiblings(); foreach ($siblings as $aSibling) { $aSibling->writeToPersistence(); } } } // Save translations // Number of languages availables depends on module // instead of languages initially stored into object // A way to support easily any new language if (is_array($this->_labels) && $this->_labels && $this->_categoryID) { $err = 0; // Insert each label foreach (CMS_languagesCatalog::getAllLanguages($this->_moduleCodename) as $aLanguage) { $lang = $aLanguage->getCode(); // Delete $sql = "\n\t\t\t\t\tdelete\n\t\t\t\t\tfrom\n\t\t\t\t\t\tmodulesCategories_i18nm\n\t\t\t\t\twhere\n\t\t\t\t\t\tcategory_mcl='" . $this->_categoryID . "'\n\t\t\t\t\t\tand language_mcl='" . SensitiveIO::sanitizeSQLString($lang) . "'\n\t\t\t\t"; $qD = new CMS_query($sql); if ($qD->hasError()) { $err++; $this->raiseError("Error deleting label in language : `{$lang}`"); } // Insert $sql = "\n\t\t\t\t\tinsert into\n\t\t\t\t\t\tmodulesCategories_i18nm\n\t\t\t\t\tset\n\t\t\t\t\t\tlanguage_mcl='" . SensitiveIO::sanitizeSQLString($lang) . "',\n\t\t\t\t\t\tcategory_mcl = " . $this->_categoryID . ",\n\t\t\t\t\t\tlabel_mcl='" . SensitiveIO::SanitizeSQLString(@$this->_labels[$lang]) . "',\n\t\t\t\t\t\tdescription_mcl='" . SensitiveIO::SanitizeSQLString(@$this->_descriptions[$lang]) . "',\n\t\t\t\t\t\tfile_mcl='" . SensitiveIO::SanitizeSQLString(@$this->_files[$lang]) . "'\n\t\t\t\t"; $q = new CMS_query($sql); if ($q->hasError()) { $err++; $this->raiseError("Error inserting label in language : `{$lang}`"); } } // have to repeat the call here $modules = CMS_modulesCatalog::getAll('id'); foreach ($modules as $codename => $module) { if (method_exists($module, 'moduleCategoryPostSave')) { $module->moduleCategoryPostSave($this, $isNew); } } //Clear polymod cache //CMS_cache::clearTypeCacheByMetas('polymod', array('module' => $this->_moduleCodename)); CMS_cache::clearTypeCache('polymod'); return $err <= 0; } $modules = CMS_modulesCatalog::getAll('id'); foreach ($modules as $codename => $module) { if (method_exists($module, 'moduleCategoryPostSave')) { $module->moduleCategoryPostSave($this, $isNew); } } //Clear polymod cache //CMS_cache::clearTypeCacheByMetas('polymod', array('module' => $this->_moduleCodename)); CMS_cache::clearTypeCache('polymod'); return true; }