/** * Builds where statement with a key and its value * The key can be known, this class will create statements in consequence * or not known so key is understood as a field name and this * method will append a statement such $key='$value' * * @access public * @param string $key name of statement to set * @param string $value , the value to give */ function addWhereCondition($type, $value) { switch ($type) { case "language": array_push($this->_where, "language_frm='" . SensitiveIO::sanitizeSQLString($value->getCode()) . "'"); break; case "profile": if (APPLICATION_ENFORCES_ACCESS_CONTROL != false) { $a_where = CMS_moduleCategories_catalog::getViewvableCategoriesForProfile($value, MOD_CMS_FORMS_CODENAME, true); array_push($this->_tables, "modulesCategories"); array_push($this->_where, "id_mca=category_fca"); array_push($this->_tables, "mod_cms_forms_categories"); array_push($this->_where, "id_frm=form_fca"); if (sizeof($a_where)) { $a_where = array_keys($a_where); array_push($this->_where, 'category_fca in (' . @implode(',', $a_where) . ')'); } else { $a_where = array_keys($a_where); array_push($this->_where, 'category_fca = NULL'); } } break; case "category": $value = $this->_sanitizeSQLString($value); if (SensitiveIO::isPositiveInteger($value) && ($s_lineage = CMS_moduleCategories_catalog::getLineageOfCategoryAsString($value))) { array_push($this->_tables, "modulesCategories"); array_push($this->_tables, "mod_cms_forms_categories"); array_push($this->_where, "id_mca=category_fca"); array_push($this->_where, "id_frm=form_fca"); array_push($this->_where, "(lineage_mca = '" . SensitiveIO::sanitizeSQLString($s_lineage) . "' or lineage_mca like '" . SensitiveIO::sanitizeSQLString($s_lineage) . ";%')"); } break; case "keywords": $value = $this->_sanitizeSQLString($value); $kwrds = @explode(" ", $value); $kwrds = SensitiveIO::sanitizeSQLString(@implode("%", $kwrds)); if (trim($kwrds) != '%') { array_push($this->_where, "name_frm like '%" . $kwrds . "%'"); } break; default: $value = $this->_sanitizeSQLString($value); array_push($this->_where, $type . "='" . SensitiveIO::sanitizeSQLString($value) . "'"); break; } $this->_tables = @array_unique($this->_tables); $this->_where = @array_unique($this->_where); }
/** * Get field search SQL request (used by class CMS_object_search) * * @param integer $fieldID : this field id in object (aka $this->_field->getID()) * @param integer $value : the category value to search * @param string $operator : additionnal search operator * @param string $where : where clauses to add to SQL * @param boolean $public : values are public or edited ? (default is edited) * @return string : the SQL request * @access public */ function getFieldSearchSQL($fieldID, $value, $operator, $where, $public = false) { $statusSuffix = $public ? "_public" : "_edited"; $supportedOperator = array('editableOnly', 'strict', 'not in', 'not in strict'); if ($operator && !in_array($operator, $supportedOperator)) { $this->raiseError("Unkown search operator : " . $operator . ", use default search instead"); $operator = false; } if ($operator == 'editableOnly') { global $cms_user; //get module codename $moduleCodename = CMS_poly_object_catalog::getModuleCodenameForField($this->_field->getID()); //get a list of all viewvable categories for current user $editableCats = array_keys(CMS_moduleCategories_catalog::getViewvableCategoriesForProfile($cms_user, $moduleCodename, true, true)); //if no viewvable categories, user has no rights to view anything if (!$editableCats) { return false; } //add previously found IDs to where clause $sql = "\n\t\t\t\t\tselect\n\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\tfrom\n\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . "\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectFieldID = '" . $fieldID . "'\n\t\t\t\t\t\tand value in (" . @implode(',', $editableCats) . ")\n\t\t\t\t\t\t{$where}\n\t\t\t\t\t"; $q = new CMS_query($sql); $IDs = array(); if (!$q->hasError()) { while ($id = $q->getValue('objectID')) { $IDs[$id] = $id; } } //if no results, no need to continue if (!$IDs) { return false; } $where = $IDs ? ' and objectID in (' . implode(',', $IDs) . ')' : ''; } if ($value == CMS_moduleCategory::LINEAGE_PARK_POSITION) { //if it is a public search, and field is mandatory, no objects should be returned if ($this->_field->getValue('required') && $public) { return false; } $module = CMS_poly_object_catalog::getModuleCodenameForField($fieldID); //add deleted cats to searchs $viewvableCats = CMS_moduleCategories_catalog::getDeletedCategories($module); //add zero value for objects without categories $viewvableCats[] = 0; //get object type id $objectID = CMS_poly_object_catalog::getObjectIDForField($fieldID); //first we get objects with deleted or no categories (value 0) $sqlTmp = "\n\t\t\t\tselect\n\t\t\t\t\tdistinct objectID\n\t\t\t\tfrom\n\t\t\t\t\tmod_subobject_integer" . $statusSuffix . "\n\t\t\t\twhere\n\t\t\t\t\tobjectFieldID = '" . $fieldID . "'\n\t\t\t\t\tand value in (" . implode(',', $viewvableCats) . ")\n\t\t\t\t\t{$where}\n\t\t\t\t"; $qTmp = new CMS_query($sqlTmp); $deletedIDs = array(); while ($r = $qTmp->getArray()) { if ($r['objectID']) { $deletedIDs[$r['objectID']] = $r['objectID']; } } //then if we get objects with no categories at all (not referenced in mod_subobject_integer table) $sqlTmp = "\n\t\t\t\tselect\n\t\t\t\t\tdistinct objectID\n\t\t\t\tfrom\n\t\t\t\t\tmod_subobject_integer" . $statusSuffix . "\n\t\t\t\twhere\n\t\t\t\t\tobjectFieldID = '" . $fieldID . "'\n\t\t\t\t\t{$where}\n\t\t\t\t"; $qTmp = new CMS_query($sqlTmp); $noCatsIDs = $catsIDs = array(); while ($r = $qTmp->getArray()) { if ($r['objectID']) { $catsIDs[$r['objectID']] = $r['objectID']; } } $IDs = array(); if (preg_match_all('#\\d+#', $where, $IDs)) { $IDs = array_shift($IDs); } $noCatsIDs = array_diff($IDs, $catsIDs); $IDs = array_merge($deletedIDs, $noCatsIDs); //if no results, no need to continue if (!$IDs) { return false; } //then we mix the too results and we return it as a fake SQL request to keep system compatibility $sql = "\n\t\t\t\tselect\n\t\t\t\t\tdistinct id_moo as objectID\n\t\t\t\tfrom\n\t\t\t\t\tmod_object_polyobjects\n\t\t\t\twhere \n\t\t\t\t\tid_moo in (" . implode(',', $IDs) . ")\n\t\t\t\t"; } else { if ($operator == 'strict') { if (!is_array($value)) { $value = array($value); } //get categories searched $sql = "\n\t\t\t\t\tselect\n\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\tfrom\n\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . ",\n\t\t\t\t\t\tmodulesCategories\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectFieldID = '" . $fieldID . "'\n\t\t\t\t\t\tand id_mca = value\n\t\t\t\t\t\tand value in (" . implode(',', $value) . ")\n\t\t\t\t\t\t{$where}\n\t\t\t\t\t"; } elseif ($operator == 'not in strict') { if (!is_array($value)) { $value = array($value); } //get categories searched $sql = "\n\t\t\t\t\tselect\n\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\tfrom\n\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . ",\n\t\t\t\t\t\tmodulesCategories\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectFieldID = '" . $fieldID . "'\n\t\t\t\t\t\tand id_mca = value\n\t\t\t\t\t\tand value not in (" . implode(',', $value) . ")\n\t\t\t\t\t\t{$where}\n\t\t\t\t\t"; } else { if (!is_array($value)) { $value = array($value); } $lineages = array(); foreach ($value as $catID) { if ($catID) { //get lineage of category searched $lineages[] = CMS_moduleCategories_catalog::getLineageOfCategoryAsString($catID); } } $sql = ''; if ($operator == 'not in') { foreach ($lineages as $lineage) { $sql .= $sql ? ' and ' : ''; $sql .= "\n\t\t\t\t\t\tlineage_mca != '" . SensitiveIO::sanitizeSQLString($lineage) . "'\n\t\t\t\t\t\tand lineage_mca not like '" . SensitiveIO::sanitizeSQLString($lineage) . ";%' "; } } else { foreach ($lineages as $lineage) { $sql .= $sql ? ' or ' : ''; $sql .= "\n\t\t\t\t\t\tlineage_mca = '" . SensitiveIO::sanitizeSQLString($lineage) . "'\n\t\t\t\t\t\tor lineage_mca like '" . SensitiveIO::sanitizeSQLString($lineage) . ";%' "; } } $sql = "\n\t\t\t\t\tselect\n\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\tfrom\n\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . ",\n\t\t\t\t\t\tmodulesCategories\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectFieldID = '" . $fieldID . "'\n\t\t\t\t\t\tand id_mca=value\n\t\t\t\t\t\t" . ($sql ? " and (" . $sql . ") " : '') . "\n\t\t\t\t\t\t{$where}"; } } return $sql; }
/** * filter array of categories ID with user clearance * * @param array $categories, IDs of categories to filter * @param integer $clearance, default is CLEARANCE_MODULE_VIEW * @param string $module : the module codename * @param boolean $strict : strict filtering of categories : do not allow parent categories of lower levels * @return array * @access public */ function filterModuleCategoriesClearance($categories, $clearance = CLEARANCE_MODULE_VIEW, $module = false, $strict = false) { if (!is_array($categories)) { return array(); } $filteredCategories = array(); //get denied cats (including deleted cats) $deniedCats = $this->getRootModuleCategoriesDenied($module); if (!is_array($deniedCats)) { $deniedCats = array(); } if (!$strict) { switch ($clearance) { case CLEARANCE_MODULE_VIEW: $matchingCats = $this->getRootModuleCategoriesReadable($module); break; case CLEARANCE_MODULE_EDIT: $matchingCats = $this->getRootModuleCategoriesWritable($module); break; case CLEARANCE_MODULE_MANAGE: $matchingCats = $this->getRootModuleCategoriesManagable($module); break; } if (!is_array($matchingCats)) { $matchingCats = array(); } if ($this->hasAdminClearance(CLEARANCE_ADMINISTRATION_EDITVALIDATEALL)) { //only remove catsDenied foreach ($deniedCats as $deniedCatID) { unset($categories[$deniedCatID]); } return $categories; } //construct n level tree with all of these categories and array of lineages $nLevelArray = array(); foreach ($categories as $catID) { //get category lineage $lineage = CMS_moduleCategories_catalog::getLineageOfCategoryAsString($catID); if ($lineage) { $lineageArray[$catID] = $lineage; //then create n level table $ln = sensitiveIO::sanitizeExecCommand('if (!isset($nLevelArray[' . str_replace(';', '][', $lineage) . '])) $nLevelArray[' . str_replace(';', '][', $lineage) . '] = array();'); eval($ln); } } $filteredCategories = $this->_filterModuleCategoriesClearanceRecursion($nLevelArray, $matchingCats, $deniedCats, false); $returnedFilteredCategories = array(); foreach ($filteredCategories as $catID) { $returnedFilteredCategories[$catID] = $catID; } } else { $returnedFilteredCategories = array(); foreach ($categories as $catID) { if (!in_array($catID, $deniedCats) && $this->hasModuleCategoryClearance($catID, $clearance, $module)) { $returnedFilteredCategories[$catID] = $catID; } } } return $returnedFilteredCategories; }
/** * Returns a multidimentionnal array of categories viewvable * If access control is active, we need to limit serch to user's * permissions on categories * * @access public * @param CMS_profile $cms_user, the profile concerned by these restrictions * @param string $module the module codename we want * @param boolean $returnLineageArray return array like array(catID => catLineage) instead * @param mixed $clearanceLevel * - false : CLEARANCE_MODULE_VIEW * - true : CLEARANCE_MODULE_EDIT * - constant value : clearanceLevel value * @param boolean $strict return only categories from this clearance (default : false, else, return complete categories tree until given clearance) * @return array(catID => array(catID => array(...))) * @static */ static function getViewvableCategoriesForProfile(&$cms_user, $module = false, $returnLineageArray = false, $clearanceLevel = false, $strict = false) { static $viewvableCats; $type = $module ? $module : 'all'; if ($clearanceLevel === false || $clearanceLevel === '' || $clearanceLevel === null) { $clearanceLevel = CLEARANCE_MODULE_VIEW; } elseif ($clearanceLevel === true) { $clearanceLevel = CLEARANCE_MODULE_EDIT; } $type = $type . (string) $clearanceLevel . ($strict ? 'strict' : '') . ($cms_user instanceof CMS_profile ? $cms_user->getId() : ''); //check if result is not allready in global var if (!isset($viewvableCats[$type])) { //first we get an array of all categories id for this module $catsID = array(); $s_where = $module ? " and module_mca = '" . $module . "'" : ""; $sql = "\n\t\t\t\tselect\n\t\t\t\t\tid_mca as id\n\t\t\t\tfrom\n\t\t\t\t\tmodulesCategories\n\t\t\t\twhere\n\t\t\t\t\tparent_mca != '" . CMS_moduleCategory::LINEAGE_PARK_POSITION . "'\n\t\t\t\t\t{$s_where}\n\t\t\t"; $q = new CMS_query($sql); while ($id = $q->getValue('id')) { $catsID[$id] = $id; } //then for each category, check if user have right to view it //if not, unset category if ($cms_user instanceof CMS_profile) { $categories = array(); if (is_array($catsID) && $catsID) { $categories = $cms_user->filterModuleCategoriesClearance($catsID, $clearanceLevel, $module, $strict); } } else { $categories = $catsID; } //then create returned arrays $nLevelArray = $lineageArray = array(); if (is_array($categories) && $categories) { foreach ($categories as $catID) { //construct n level tree with all of these categories and array of lineages //get category lineage $lineage = CMS_moduleCategories_catalog::getLineageOfCategoryAsString($catID); if ($lineage) { $lineageArray[$catID] = $lineage; //then create n level table $ln = sensitiveIO::sanitizeExecCommand('if (!isset($nLevelArray[' . str_replace(';', '][', $lineage) . '])) $nLevelArray[' . str_replace(';', '][', $lineage) . '] = array();'); eval($ln); } } } $viewvableCats[$type]["lineageArray"] = $lineageArray; $viewvableCats[$type]["nLevelArray"] = $nLevelArray; } return $returnLineageArray ? $viewvableCats[$type]["lineageArray"] : $viewvableCats[$type]["nLevelArray"]; }