/** * Gets a validation for a given item * * @param integer $itemID The item we want the validations for * @param CMS_user $user The user we want the validations for * @param integer $getEditionType The validation type we want. * by default function return RESOURCE_EDITION_LOCATION then RESOURCE_EDITION_CONTENT then RESOURCE_EDITION_SIBLINGSORDER * @return array(CMS_resourceValidation) The resourceValidations objects, false if none found for the given user. * @access public */ function getValidationByID($itemID, &$user, $getEditionType = false) { if (!$user instanceof CMS_profile_user) { $this->raiseError("User is not a valid CMS_profile_user object"); return false; } if (!$user->hasValidationClearance($this->_codename)) { return false; } if (CMS_poly_object_catalog::hasPrimaryResource($this->getCodename())) { //get object type ID $objectID = CMS_poly_object_catalog::getPrimaryResourceObjectType($this->getCodename()); //get viewvable objects list for current user if (CMS_poly_object_catalog::objectHasCategories($objectID)) { $objects = CMS_poly_object_catalog::getAllObjects($objectID, false, array(), false); //$where = (is_array($objects) && $objects) ? ' and objectID in ('.implode(',',$objects).')' : ''; if (is_array($objects) && $objects) { $where = ' and objectID in (' . implode(',', $objects) . ')'; } else { return false; } } else { $where = ''; } $this->getPrimaryResourceDefinition(); if (!$getEditionType) { $getEditionType = RESOURCE_EDITION_LOCATION + RESOURCE_EDITION_CONTENT; } $sql = "\n\t\t\t\t\tselect\n\t\t\t\t\t\tobjectID as id,\n\t\t\t\t\t\tlocation_rs as location,\n\t\t\t\t\t\tproposedFor_rs as proposedFor,\n\t\t\t\t\t\tvalidationsRefused_rs as validationsRefused,\n\t\t\t\t\t\teditions_rs as editions,\n\t\t\t\t\t\tmod_subobject_integer_edited.id as fieldID\n\t\t\t\t\tfrom\n\t\t\t\t\t\tmod_subobject_integer_edited,\n\t\t\t\t\t\tmod_object_polyobjects,\n\t\t\t\t\t\tresources,\n\t\t\t\t\t\tresourceStatuses\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectID = '" . $itemID . "'\n\t\t\t\t\t\tand value = id_res\n\t\t\t\t\t\tand object_type_id_moo = '" . $objectID . "'\n\t\t\t\t\t\tand id_moo = objectID\n\t\t\t\t\t\tand objectFieldID = 0\n\t\t\t\t\t\tand objectSubFieldID = 0\n\t\t\t\t\t\tand status_res = id_rs\n\t\t\t\t\t\t{$where}\n\t\t\t\t"; $q = new CMS_query($sql); if ($q->getNumRows() >= 1) { $r = $q->getArray(); $id = $r["id"]; //here, this is an ugly hack to resolve a strange bug (multiple resources for an unique object). //not time to found the real cause for now ... if ($q->getNumRows() > 1) { while ($exceptionFiledID = $q->getValue('fieldID')) { $sql_delete = "delete from mod_subobject_integer_edited where id = '" . $exceptionFiledID . "'"; $q_delete = new CMS_query($sql_delete); } } //search the type of edition //RESOURCE_EDITION_LOCATION if ($r["location"] == RESOURCE_LOCATION_USERSPACE && $r["proposedFor"] != 0 && !($r["validationsRefused"] & RESOURCE_EDITION_LOCATION) && $getEditionType & RESOURCE_EDITION_LOCATION) { $language = $user->getLanguage(); $item = $this->getResourceByID($id); $validation = new CMS_resourceValidation($this->_codename, RESOURCE_EDITION_LOCATION, $item); if (!$validation->hasError()) { $validation->setValidationTypeLabel($language->getMessage(self::MESSAGE_MOD_POLYMOD_VALIDATION_LOCATIONCHANGE, array($this->_primaryResourceObjectDefinition->getLabel($language)), MOD_POLYMOD_CODENAME)); $validation->setValidationLabel($language->getMessage(self::MESSAGE_MOD_POLYMOD_VALIDATION_LOCATIONCHANGE_OFRESOURCE, array($this->_primaryResourceObjectDefinition->getLabel($language)), MOD_POLYMOD_CODENAME) . " " . io::decodeEntities($item->{$this->_resourceNameMethod}())); $validation->setValidationShortLabel(io::decodeEntities($item->{$this->_resourceNameMethod}())); $previzURL = $item->getPrevizPageURL(); if ($previzURL) { $validation->addHelpUrl($language->getMessage(self::MESSAGE_PAGE_ACTION_PREVIZ), $previzURL); } $validation->setEditorsStack($item->getEditorsStack()); return $validation; } else { return false; } //RESOURCE_EDITION_CONTENT } elseif ($r["location"] == RESOURCE_LOCATION_USERSPACE && $r["proposedFor"] == 0 && ($r["editions"] & RESOURCE_EDITION_CONTENT && !($r["validationsRefused"] & RESOURCE_EDITION_CONTENT)) && $getEditionType & RESOURCE_EDITION_CONTENT) { $language = $user->getLanguage(); $editions = $r["editions"]; //RESOURCE_EDITION_CONTENT $item = $this->getResourceByID($id); $validation = new CMS_resourceValidation($this->_codename, $editions, $item); if (!$validation->hasError()) { $validation->setValidationTypeLabel($language->getMessage(self::MESSAGE_MOD_POLYMOD_VALIDATION_EDITION, array($this->_primaryResourceObjectDefinition->getLabel($language)), MOD_POLYMOD_CODENAME)); $validation->setValidationLabel($language->getMessage(self::MESSAGE_MOD_POLYMOD_VALIDATION_EDITION_OFRESOURCE, array($this->_primaryResourceObjectDefinition->getLabel($language)), MOD_POLYMOD_CODENAME) . " " . io::decodeEntities($item->{$this->_resourceNameMethod}())); $validation->setValidationShortLabel(io::decodeEntities($item->{$this->_resourceNameMethod}())); $previzURL = $item->getPrevizPageURL(); if ($previzURL) { $validation->addHelpUrl($language->getMessage(self::MESSAGE_PAGE_ACTION_PREVIZ), $previzURL); } $validation->setEditorsStack($item->getEditorsStack()); return $validation; } else { return false; } } } elseif ($q->getNumRows() == 0) { return false; } else { $this->raiseError("Can't have more than one item for a given ID"); return false; } } else { return false; } }
/** * Get all searched objects ids * * @access private * @return array of object ids unsorted */ protected function _getIds() { $IDs = array(); $statusSuffix = $this->_public ? "_public" : "_edited"; //loop on each conditions foreach ($this->_whereConditions as $type => $typeWhereConditions) { foreach ($typeWhereConditions as $whereConditionsValues) { $value = $whereConditionsValues['value']; $operator = $whereConditionsValues['operator']; $sql = ''; switch ($type) { case "object": //add previously found IDs to where clause $where = $IDs ? ' and id_moo in (' . $this->_getSQLTmpList() . ')' : ''; //to remove deleted objects from results $sql = "\n\t\t\t\t\tselect\n\t\t\t\t\t\tid_moo as objectID\n\t\t\t\t\tfrom\n\t\t\t\t\t\tmod_object_polyobjects\n\t\t\t\t\twhere\n\t\t\t\t\t\tobject_type_id_moo = '" . $this->_object->getID() . "'\n\t\t\t\t\t\tand deleted_moo = '0'\n\t\t\t\t\t\t{$where}\n\t\t\t\t\t"; break; case "item": //add previously found IDs to where clause $where = $IDs ? ' and objectID in (' . $this->_getSQLTmpList() . ')' : ''; //check operator $supportedOperator = array('=', '!=', '>=', '>', '<=', '<'); if ($operator && !in_array($operator, $supportedOperator)) { $this->raiseError("Unknown search operator : " . $operator . ", use default search instead"); $operator = false; } if (!$operator) { $operator = '='; } $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_text" . $statusSuffix . "\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectID " . $operator . " '" . $value . "'\n\t\t\t\t\t\t{$where}\n\t\t\t\t\tunion distinct\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\tobjectID " . $operator . " '" . $value . "'\n\t\t\t\t\t\t{$where}\n\t\t\t\t\tunion distinct\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_string" . $statusSuffix . "\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectID " . $operator . " '" . $value . "'\n\t\t\t\t\t\t{$where}\n\t\t\t\t\tunion distinct\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_date" . $statusSuffix . "\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectID " . $operator . " '" . $value . "'\n\t\t\t\t\t\t{$where}\n\t\t\t\t\t"; break; case "items": //add previously found IDs to where clause $where = $IDs ? ' and objectID in (' . $this->_getSQLTmpList() . ')' : ''; //check operator $supportedOperator = array('in', 'not in'); if ($operator && !in_array($operator, $supportedOperator)) { $this->raiseError("Unknown search operator : " . $operator . ", use default search instead"); $operator = false; } if (!$operator) { $operator = 'in'; } //no values to found so break search if ((!is_array($value) || !$value) && $operator == 'in') { $IDs = array(); break; } //no filter to do so break search if ((!is_array($value) || !$value) && $operator == 'not in') { break; } $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_text" . $statusSuffix . "\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectID " . $operator . " (" . implode(',', $value) . ")\n\t\t\t\t\t\t{$where}\n\t\t\t\t\tunion distinct\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\tobjectID " . $operator . " (" . implode(',', $value) . ")\n\t\t\t\t\t\t{$where}\n\t\t\t\t\tunion distinct\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_string" . $statusSuffix . "\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectID " . $operator . " (" . implode(',', $value) . ")\n\t\t\t\t\t\t{$where}\n\t\t\t\t\tunion distinct\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_date" . $statusSuffix . "\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectID " . $operator . " (" . implode(',', $value) . ")\n\t\t\t\t\t\t{$where}\n\t\t\t\t\t"; break; case "profile": //if user has no right on module, he cannot search object on it if (!$value->hasModuleClearance($this->_object->getValue('module'), CLEARANCE_MODULE_VIEW)) { break; } //if object has categories, check rights on it if ($this->_object->hasCategories()) { //get field of categories for searched object type (assume it uses categories) $categoriesFields = CMS_poly_object_catalog::objectHasCategories($this->_object->getId()); //BUG : in websites without APPLICATION_ENFORCES_ACCESS_CONTROL, backend rights on categories are checked on visibility instead of edition if (!$this->_public) { $clearance = CLEARANCE_MODULE_EDIT; $strict = true; } else { $clearance = CLEARANCE_MODULE_VIEW; $strict = false; } //get a list of all viewvable categories for current user $cats = array_keys(CMS_moduleCategories_catalog::getViewvableCategoriesForProfile($value, $this->_object->getValue('module'), true, $clearance, $strict)); foreach ($categoriesFields as $categoriesField) { //load category field if not exists if (!isset($this->_fieldsDefinitions[$categoriesField]) || !is_object($this->_fieldsDefinitions[$categoriesField])) { //get object fields definition $this->_fieldsDefinitions = CMS_poly_object_catalog::getFieldsDefinition($this->_object->getID()); } if (!isset($this->_fieldsDefinitions[$categoriesField])) { break; } //we can see objects without categories only if is not public or field is not required and user has admin right on module if ($this->_public && !$this->_fieldsDefinitions[$categoriesField]->getValue('required') || !$this->_public && $value->hasModuleClearance($this->_object->getValue('module'), CLEARANCE_MODULE_EDIT)) { //add deleted cats to searchs $viewvableCats = array_merge(CMS_moduleCategories_catalog::getDeletedCategories($this->_object->getValue('module')), $cats); //add zero value for objects without categories $viewvableCats[] = 0; } else { $viewvableCats = $cats; //add zero value for objects without categories $viewvableCats[] = 0; } //if no viewvable categories, user has no rights to view anything if (!$viewvableCats) { break; } $removedIDs = array(); //add previously found IDs to where clause $where = $IDs ? ' and objectID in (' . $this->_getSQLTmpList() . ')' : ''; $sqlTmp = "\n\t\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . "\n\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\tobjectFieldID = '" . $categoriesField . "'\n\t\t\t\t\t\t\t\t\tand value not in (" . @implode(',', $viewvableCats) . ")\n\t\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t"; $qTmp = new CMS_query($sqlTmp); while ($r = $qTmp->getArray()) { if ($r['objectID'] && isset($IDs[$r['objectID']])) { $removedIDs[$r['objectID']] = $r['objectID']; } } //add (again) ids which has a category visible and a category not visible if ($removedIDs) { $sqlTmp = "\n\t\t\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . "\n\t\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\t\tobjectFieldID = '" . $categoriesField . "'\n\t\t\t\t\t\t\t\t\t\tand value in (" . @implode(',', $viewvableCats) . ")\n\t\t\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t\t"; $qTmp = new CMS_query($sqlTmp); while ($r = $qTmp->getArray()) { if ($r['objectID'] && isset($removedIDs[$r['objectID']])) { unset($removedIDs[$r['objectID']]); } } //then finally remove ids foreach ($removedIDs as $idToRemove) { unset($IDs[$idToRemove]); } } //if no IDs break if (!$IDs) { break; } //if field is required and if it is a public search, object must have this category in DB if ($this->_fieldsDefinitions[$categoriesField]->getValue('required') && $this->_public) { //update tmp table with found ids $this->_updateTmpList($IDs); $sqlTmp = "\n\t\t\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . "\n\t\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\t\tobjectFieldID = '" . $categoriesField . "'\n\t\t\t\t\t\t\t\t\t\tand objectID in (" . $this->_getSQLTmpList() . ")\n\t\t\t\t\t\t\t\t"; $qTmp = new CMS_query($sqlTmp); $IDs = array(); while ($r = $qTmp->getArray()) { $IDs[$r['objectID']] = $r['objectID']; } } //if no IDs break if (!$IDs) { break; } } //if no IDs break if (!$IDs) { break; } } elseif (!$this->_public && !$value->hasModuleClearance($this->_object->getValue('module'), CLEARANCE_MODULE_EDIT)) { break; } elseif ($this->_public && !$value->hasModuleClearance($this->_object->getValue('module'), CLEARANCE_MODULE_VIEW)) { break; } //update tmp table with found ids $this->_updateTmpList($IDs); //add previously found IDs to where clause $where = $IDs ? ' id_moo in (' . $this->_getSQLTmpList() . ')' : ''; $sql = "\n\t\t\t\t\t\tselect\n\t\t\t\t\t\t\tdistinct id_moo as objectID\n\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\tmod_object_polyobjects\n\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t"; break; case "keywords": if ($value) { //check operators $supportedOperator = array('any', 'all', 'phrase', 'beginswith'); if ($operator && !in_array($operator, $supportedOperator)) { $this->raiseError("Unkown search operator : " . $operator . ", use default search instead"); $operator = 'any'; } elseif (!$operator) { $operator = 'any'; } //if ASE module exists (and is active) and object is indexed, and search is public, use it to do this search if ($operator == 'any' && class_exists('CMS_module_ase') && CMS_module_ase::isActive() && $this->_object->getValue('indexable') && $this->_public) { //get language code for stemming $languageCode = ''; if ($languageFieldIDs = CMS_poly_object_catalog::objectHasLanguageField($this->_object->getID())) { $languageFieldID = array_shift($languageFieldIDs); //if any query use this field, use the queried value for stemming strategy if (isset($this->_whereConditions[$languageFieldID]) && $this->_whereConditions[$languageFieldID]) { $languageCode = $this->_whereConditions[$languageFieldID][0]['value']; } } //otherwise, we use current language if (!$languageCode) { global $cms_language; $languageCode = $cms_language->getCode(); } if (!$languageCode) { $languageCode = io::strtolower(APPLICATION_DEFAULT_LANGUAGE); } $module = $this->_object->getValue('module'); //create Xapian search object $search = new CMS_XapianQuery(trim($value), array($module), $languageCode, true); //load module interface if (!($moduleInterface = CMS_ase_interface_catalog::getModuleInterface($module))) { $this->raiseError('No active Xapian interface for module : ' . $module); return false; } //add previously found IDs to search filters $moduleInterface->addFilter('items', $IDs); //set module interface to search engine $search->setModuleInterface($module, $moduleInterface); //set page number and max results for xapian query //we must do a complete search all the time so we start from page 0 $page = 0; //we limit to a maximum of 1000 results $maxResults = 1000; //then search if (!$search->query($page, $maxResults)) { $this->raiseError('Error in Xapian query for search : ' . io::htmlspecialchars($value)); return false; } //pr($search->getQueryDesc(true)); //if no results : break if (!$search->getMatchesNumbers()) { break; } $xapianResults = $search->getMatches(); } else { //get fields if (!isset($this->_fieldsDefinitions[$type]) || !is_object($this->_fieldsDefinitions[$type])) { //get object fields definition $this->_fieldsDefinitions = CMS_poly_object_catalog::getFieldsDefinition($this->_object->getID()); } //search only in "searchable" fields $fields = array(); $aseExists = class_exists('CMS_module_ase') && CMS_module_ase::isActive() && $this->_object->getValue('indexable') ? true : false; foreach ($this->_fieldsDefinitions as $fieldDefinition) { if ($fieldDefinition->getValue($aseExists ? 'indexable' : 'searchable')) { $fields[] = $fieldDefinition->getID(); } } if (!$fields) { //if no fields after cleaning, return break; } //add previously found IDs to where clause $where = $IDs ? ' objectID in (' . $this->_getSQLTmpList() . ') and ' : ''; //filter on specified fields $where .= $fields ? ' objectFieldID in (' . implode(',', $fields) . ') and ' : ''; //clean user keywords (never trust user input, user is evil) $value = strtr($value, ",;", " "); $words = array(); $words = array_map("trim", array_unique(explode(" ", $value))); $cleanedWords = array(); foreach ($words as $aWord) { if ($aWord && $aWord != '' && io::strlen($aWord) >= 3) { $aWord = str_replace(array('%', '_'), array('\\%', '\\_'), $aWord); $cleanedWords[] = $aWord; } } if (!$cleanedWords) { //if no words after cleaning, return break; } switch ($operator) { case 'any': $where .= '('; //then add keywords $count = '0'; foreach ($cleanedWords as $aWord) { $where .= $count ? ' or ' : ''; $count++; $where .= "value like '%" . $aWord . "%'"; if (htmlentities($aWord) != $aWord) { $where .= " or value like '%" . htmlentities($aWord) . "%'"; } } $where .= ')'; break; case 'all': $where .= '('; //then add keywords $count = '0'; foreach ($cleanedWords as $aWord) { $where .= $count ? ' and ' : ''; $count++; if (htmlentities($aWord) != $aWord) { $where .= "(value like '%" . $aWord . "%' or value like '%" . htmlentities($aWord) . "%')"; } else { $where .= "value like '%" . $aWord . "%'"; } } $where .= ')'; break; case 'phrase': $value = str_replace(array('%', '_'), array('\\%', '\\_'), trim($value)); if (htmlentities($value) != $value) { $where .= "(value like '%" . $value . "%' or value like '%" . htmlentities($value) . "%')"; } else { $where .= "value like '%" . $value . "%'"; } break; case 'beginswith': $value = str_replace(array('%', '_'), array('\\%', '\\_'), trim($value)); if (htmlentities($value) != $value) { $where .= "(value like '" . $value . "%' or value like '" . htmlentities($value) . "%')"; } else { $where .= "value like '" . $value . "%'"; } break; } $sql = "\n\t\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\t\tmod_subobject_text" . $statusSuffix . "\n\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t\tunion distinct\n\t\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . "\n\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t\tunion distinct\n\t\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\t\tmod_subobject_string" . $statusSuffix . "\n\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t\tunion distinct\n\t\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\t\tmod_subobject_date" . $statusSuffix . "\n\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t"; } } break; case "publication date after": // Date start //add previously found IDs to where clause $where = $IDs ? ' and objectID in (' . $this->_getSQLTmpList() . ')' : ''; $sql = "\n\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . ",\n\t\t\t\t\t\t\t\tresources,\n\t\t\t\t\t\t\t\tresourceStatuses\n\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\tobjectFieldID = '0'\n\t\t\t\t\t\t\t\tand value = id_res\n\t\t\t\t\t\t\t\tand status_res=id_rs\n\t\t\t\t\t\t\t\tand publicationDateStart_rs >= '" . $value->getDBValue(true) . "'\n\t\t\t\t\t\t\t\tand publicationDateStart_rs != '0000-00-00'\n\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t"; break; case "publication date before": // Date End //add previously found IDs to where clause $where = $IDs ? ' and objectID in (' . $this->_getSQLTmpList() . ')' : ''; $sql = "\n\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . ",\n\t\t\t\t\t\t\t\tresources,\n\t\t\t\t\t\t\t\tresourceStatuses\n\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\tobjectFieldID = '0'\n\t\t\t\t\t\t\t\tand value = id_res\n\t\t\t\t\t\t\t\tand status_res=id_rs\n\t\t\t\t\t\t\t\tand publicationDateStart_rs <= '" . $value->getDBValue(true) . "'\n\t\t\t\t\t\t\t\tand publicationDateStart_rs != '0000-00-00'\n\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t"; break; case "publication date end": // End Date of publication //add previously found IDs to where clause $where = $IDs ? ' and objectID in (' . $this->_getSQLTmpList() . ')' : ''; $sql = "\n\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . ",\n\t\t\t\t\t\t\t\tresources,\n\t\t\t\t\t\t\t\tresourceStatuses\n\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\tobjectFieldID = '0'\n\t\t\t\t\t\t\t\tand value = id_res\n\t\t\t\t\t\t\t\tand status_res=id_rs\n\t\t\t\t\t\t\t\tand (publicationDateEnd_rs >= '" . $value->getDBValue(true) . "'\n\t\t\t\t\t\t\t\tor publicationDateEnd_rs = '0000-00-00')\n\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t"; break; case "status": // Publication status //add previously found IDs to where clause $where = $IDs ? ' and objectID in (' . $this->_getSQLTmpList() . ')' : ''; switch ($value) { case 'online': $sql = "\n\t\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . ",\n\t\t\t\t\t\t\t\t\tresources,\n\t\t\t\t\t\t\t\t\tresourceStatuses\n\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\tobjectFieldID = '0'\n\t\t\t\t\t\t\t\t\tand value = id_res\n\t\t\t\t\t\t\t\t\tand status_res=id_rs\n\t\t\t\t\t\t\t\t\tand location_rs='" . RESOURCE_LOCATION_USERSPACE . "'\n\t\t\t\t\t\t\t\t\tand publication_rs='" . RESOURCE_PUBLICATION_PUBLIC . "'\n\t\t\t\t\t\t\t\t\tand publicationDateStart_rs <= '" . date('Y-m-d') . "'\n\t\t\t\t\t\t\t\t\tand publicationDateStart_rs != '0000-00-00'\n\t\t\t\t\t\t\t\t\tand (publicationDateEnd_rs >= '" . date('Y-m-d') . "'\n\t\t\t\t\t\t\t\t\tor publicationDateEnd_rs = '0000-00-00')\n\t\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t\t"; break; case 'offline': $sql = "\n\t\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . ",\n\t\t\t\t\t\t\t\t\tresources,\n\t\t\t\t\t\t\t\t\tresourceStatuses\n\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\tobjectFieldID = '0'\n\t\t\t\t\t\t\t\t\tand value = id_res\n\t\t\t\t\t\t\t\t\tand status_res=id_rs\n\t\t\t\t\t\t\t\t\tand (publication_rs='" . RESOURCE_PUBLICATION_NEVERVALIDATED . "' or publication_rs='" . RESOURCE_PUBLICATION_VALIDATED . "')\n\t\t\t\t\t\t\t\t\tand (publicationDateStart_rs > '" . date('Y-m-d') . "' or publicationDateEnd_rs < '" . date('Y-m-d') . "')\n\t\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t\t"; break; case 'validated': $sql = "\n\t\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . ",\n\t\t\t\t\t\t\t\t\tresources,\n\t\t\t\t\t\t\t\t\tresourceStatuses\n\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\tobjectFieldID = '0'\n\t\t\t\t\t\t\t\t\tand value = id_res\n\t\t\t\t\t\t\t\t\tand status_res=id_rs\n\t\t\t\t\t\t\t\t\tand editions_rs=0\n\t\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t\t"; break; case 'awaiting': $sql = "\n\t\t\t\t\t\t\t\tselect\n\t\t\t\t\t\t\t\t\tdistinct objectID\n\t\t\t\t\t\t\t\tfrom\n\t\t\t\t\t\t\t\t\tmod_subobject_integer" . $statusSuffix . ",\n\t\t\t\t\t\t\t\t\tresources,\n\t\t\t\t\t\t\t\t\tresourceStatuses\n\t\t\t\t\t\t\t\twhere\n\t\t\t\t\t\t\t\t\tobjectFieldID = '0'\n\t\t\t\t\t\t\t\t\tand value = id_res\n\t\t\t\t\t\t\t\t\tand status_res=id_rs\n\t\t\t\t\t\t\t\t\tand editions_rs!=0\n\t\t\t\t\t\t\t\t\t{$where}\n\t\t\t\t\t\t\t\t"; break; } break; default: //add previously found IDs to where clause $where = $IDs ? ' and objectID in (' . $this->_getSQLTmpList() . ')' : ''; if (!isset($this->_fieldsDefinitions[$type]) || !is_object($this->_fieldsDefinitions[$type])) { //get object fields definition $this->_fieldsDefinitions = CMS_poly_object_catalog::getFieldsDefinition($this->_object->getID()); } //get type object for field if (isset($this->_fieldsDefinitions[$type])) { $objectField = $this->_fieldsDefinitions[$type]->getTypeObject(); $sql = $objectField->getFieldSearchSQL($type, $value, $operator, $where, $this->_public); } else { $this->raiseError('Unknown field ' . $type . ' to filter with value ' . print_r($value, true)); } break; } if ($sql || isset($xapianResults) || isset($fullTextResults)) { if ($sql) { //pr($sql); //$this->raiseError($sql); $q = new CMS_query($sql); $IDs = array(); if (!$q->hasError()) { while ($id = $q->getValue('objectID')) { $IDs[$id] = $id; } } } elseif (isset($xapianResults)) { $IDs = array(); foreach ($xapianResults as $id) { $IDs[$id] = $id; } //if we only have objectID as orderCondition or if order by relevance is queried, use order provided by Xapian if (isset($this->_orderConditions['objectID']) && $this->_orderConditions['objectID'] && sizeof($this->_orderConditions) <= 1 || isset($this->_orderConditions['relevance']) && $this->_orderConditions['relevance']) { if ($this->_orderConditions['relevance'] == 'desc') { $this->_orderConditions = array('itemsOrdered' => array('order' => array_reverse($IDs, true))); } else { $this->_orderConditions = array('itemsOrdered' => array('order' => $IDs)); } if (isset($this->_orderConditions['relevance']) && $this->_orderConditions['relevance']) { unset($this->_orderConditions['relevance']); } } } else { //if we only have objectID as orderCondition or if order by relevance is queried, use order provided by MySQL Fulltext if (isset($this->_orderConditions['relevance']) && $this->_orderConditions['relevance']) { if ($this->_orderConditions['relevance'] == 'desc') { $this->_orderConditions = array('itemsOrdered' => array('order' => array_reverse($fullTextResults, true))); } else { $this->_orderConditions = array('itemsOrdered' => array('order' => $fullTextResults)); } unset($this->_orderConditions['relevance']); } } //if no results, no need to continue if (!$IDs) { $IDs = array(); $this->_numRows = 0; return $IDs; } //update tmp table with found ids $this->_updateTmpList($IDs); } else { //if no sql request, then no results (can be used by 'profile'), no need to continue $IDs = array(); $this->_numRows = sizeof($IDs); return $IDs; } } } $this->_numRows = sizeof($IDs); return $IDs; }
/** * Does given user have the requested clearance for this object ? * This method is pretty heavy, so if it must be used on a lots of objects, prefer usage of a search on those objects, it is much faster. * * @param cms_profile_user $user : the user to check clearance * @param constant $clearance : the requested clearance to check (default : CLEARANCE_MODULE_VIEW) * @param boolean $checkParent : if no categories fields found, check the parent object (if any) to see if it as some (beware this is heavy). Default : false * @return boolean * @access public */ function userHasClearance($user, $clearance = CLEARANCE_MODULE_VIEW, $checkParent = false) { if (!$this->_public || APPLICATION_ENFORCES_ACCESS_CONTROL === true) { //user is an administrator? if ($user->hasAdminClearance(CLEARANCE_ADMINISTRATION_EDITVALIDATEALL)) { return true; } //get Object definition $objectDef = $this->getObjectDefinition(); //get module codename $polyModuleCodename = $objectDef->getValue('module'); //check user right on module (check only minimum needed : VIEW, proper right is checked after on category) if (!$user->hasModuleClearance($polyModuleCodename, CLEARANCE_MODULE_VIEW)) { return false; } //object has categories fields ? $categoriesFields = CMS_poly_object_catalog::objectHasCategories($this->getObjectID()); $allCategories = array(); if (!$categoriesFields && !$checkParent) { //no categories on object so user has rights return true; } elseif (!$categoriesFields && $checkParent) { //check for module Categories usage if (!CMS_poly_object_catalog::moduleHasCategories($polyModuleCodename)) { //no categories used on module : item is viewvable return true; } //check for a parent for the given object if ($objectParentsIDs = CMS_poly_object_catalog::getParentsObject($this->getObjectID())) { $found = false; //check object for each parent objects found foreach ($objectParentsIDs as $objectParentID => $objectParentFields) { $categoriesFields = CMS_poly_object_catalog::objectHasCategories($objectParentID); if (is_array($categoriesFields) && $categoriesFields) { //load current object definition $object = CMS_poly_object_catalog::getObjectDefinition($objectParentID); foreach ($objectParentFields as $fieldID) { $search = new CMS_object_search($object, $this->_public); $search->addWhereCondition($fieldID, $this->getID()); $ids = $search->search(CMS_object_search::POLYMOD_SEARCH_RETURN_IDS); $found = $ids ? true : $found; } } } //if one parent was found then object is visible return $found; } else { //no parent object for this object, item is viewvable return true; } } elseif (is_array($categoriesFields) && $categoriesFields) { $search = new CMS_object_search($objectDef, $clearance == CLEARANCE_MODULE_VIEW); $search->addWhereCondition('item', $this->getID()); $search->addWhereCondition("profile", $user); $ids = $search->search(CMS_object_search::POLYMOD_SEARCH_RETURN_IDS); return $ids ? true : false; } } //user has clearance return true; }
/** * Returns all categories IDs who has used by this type of object (ie : this field) * * @param mixed (boolean or array) $restrictToItemsIds, restrict results to given items ids. False to restrict to only used categories (default) * @access public * @return array(interger id => integer id) the object ids * @static */ function getAllUsedCategoriesForField($restrictToItemsIds = false) { if (is_array($restrictToItemsIds) && (!$restrictToItemsIds || !implode($restrictToItemsIds, ', '))) { //restrict to no ids so return nothing return array(); } //get field of categories for searched object type (assume it uses categories) $categoriesFields = CMS_poly_object_catalog::objectHasCategories(CMS_poly_object_catalog::getObjectIDForField($this->_field->getID())); $fieldsDefinitions = array(); //bypass field categories rights if needed foreach ($categoriesFields as $key => $catFieldID) { if (!isset($fieldsDefinitions[$catFieldID]) || !is_object($fieldsDefinitions[$catFieldID])) { //get object fields definition $fieldsDefinitions = CMS_poly_object_catalog::getFieldsDefinition(CMS_poly_object_catalog::getObjectIDForField($this->_field->getID())); } /*if ($fieldsDefinitions[$catFieldID]->getParameter('bypassRights')) { unset($categoriesFields[$key]); }*/ } if (!$categoriesFields) { return array(); } //if this field is the only one which use categories if (sizeof($categoriesFields) == 1 && in_array($this->_field->getID(), $categoriesFields)) { if ($this->_public) { //check for publication dates $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_public,\n\t\t\t\t\t\tresources,\n\t\t\t\t\t\tresourceStatuses\n\t\t\t\t\twhere\n\t\t\t\t\t\tobjectFieldID = '0'\n\t\t\t\t\t\tand value = id_res\n\t\t\t\t\t\tand status_res=id_rs\n\t\t\t\t\t\tand location_rs='" . RESOURCE_LOCATION_USERSPACE . "'\n\t\t\t\t\t\tand publication_rs='" . RESOURCE_PUBLICATION_PUBLIC . "'\n\t\t\t\t\t\tand publicationDateStart_rs <= '" . date('Y-m-d') . "'\n\t\t\t\t\t\tand publicationDateStart_rs != '0000-00-00'\n\t\t\t\t\t\tand (publicationDateEnd_rs >= '" . date('Y-m-d') . "'\n\t\t\t\t\t\tor publicationDateEnd_rs = '0000-00-00')\n\t\t\t\t\t"; if ($restrictToItemsIds) { $sql .= " and objectID in (" . implode($restrictToItemsIds, ', ') . ")"; } else { $sql .= " and objectID in (select objectID from mod_subobject_integer_public where objectFieldID = '" . $this->_field->getID() . "')"; } $q = new CMS_query($sql); $restrictToItemsIds = array(); if ($q->getNumRows()) { while ($arr = $q->getArray()) { $restrictToItemsIds[] = $arr['objectID']; } } } $table = $this->_public ? 'mod_subobject_integer_public' : 'mod_subobject_integer_edited'; $sql = "\n\t\t\t\tselect\n\t\t\t\t\tvalue\n\t\t\t\tfrom\n\t\t\t\t\t{$table}\n\t\t\t\twhere\n\t\t\t\t\tobjectFieldID = '" . $this->_field->getID() . "'\n\t\t\t"; if ($restrictToItemsIds) { $sql .= " and objectID in (" . implode($restrictToItemsIds, ', ') . ")"; } $q = new CMS_query($sql); $r = array(); if ($q->getNumRows()) { while ($arr = $q->getArray()) { //check for value because it can be null ! if ($arr['value']) { $r[$arr['value']] = $arr['value']; } } } } else { //if this field is not only one which use categories global $cms_user; if (APPLICATION_ENFORCES_ACCESS_CONTROL && !is_object($cms_user)) { $this->raiseError("Valid user missing"); return false; } if (!is_object($cms_user)) { //TODO : ugly but missing time (need to redo the getAllCategoriesAsArray to accept no valid cms_user : append only in frontend without APPLICATION_ENFORCES_ACCESS_CONTROL. Medias module already doing something like this) $user = new CMS_profile_user(ROOT_PROFILEUSER_ID); } else { $user = $cms_user; } //get a list of all viewvable categories for current user $viewvableCats = array_keys(CMS_moduleCategories_catalog::getViewvableCategoriesForProfile($user, CMS_poly_object_catalog::getModuleCodenameForField($this->_field->getID()), true)); //if no viewvable categories, user has no rights to view anything if (!$viewvableCats) { return array(); } $table = $this->_public ? 'mod_subobject_integer_public' : 'mod_subobject_integer_edited'; $sql = "\n\t\t\t\tselect\n\t\t\t\t\tdistinct objectID\n\t\t\t\tfrom\n\t\t\t\t\t{$table}\n\t\t\t\twhere\n\t\t\t\t\tobjectFieldID in (" . @implode(',', $categoriesFields) . ")\n\t\t\t\t\tand value in (" . @implode(',', $viewvableCats) . ")\n\t\t\t\t\t"; if ($restrictToItemsIds) { $sql .= " and objectID in (" . implode($restrictToItemsIds, ', ') . ")"; } $q = new CMS_query($sql); $r = array(); if ($q->getNumRows()) { while ($arr = $q->getArray()) { //check for value because it can be null ! if ($arr['objectID']) { $r[$arr['objectID']] = $arr['objectID']; } } } if (!$r) { return array(); } //add previously found IDs to where clause $sql = "\n\t\t\t\tselect\n\t\t\t\t\tdistinct value\n\t\t\t\tfrom\n\t\t\t\t\t{$table}\n\t\t\t\twhere\n\t\t\t\t\tobjectFieldID = '" . $this->_field->getID() . "'\n\t\t\t\t\tand objectID in(" . @implode(',', $r) . ")\n\t\t\t"; $q = new CMS_query($sql); $r = array(); if ($q->getNumRows()) { while ($arr = $q->getArray()) { //check for value because it can be null ! if ($arr['value']) { $r[$arr['value']] = $arr['value']; } } } } return $r; }
/** * Return a list of objects infos to be displayed in module index according to user privileges * * @return string : HTML scripts infos * @access public */ function getObjectsInfos($user) { $objectsInfos = array(); $cms_language = $user->getLanguage(); $catFieldsNames = array(); //objects $objects = $this->getObjects(); if (APPLICATION_ENFORCES_ACCESS_CONTROL === false || APPLICATION_ENFORCES_ACCESS_CONTROL === true && $user->hasModuleClearance($this->getCodename(), CLEARANCE_MODULE_EDIT)) { foreach ($objects as $anObjectType) { //if object is editable or if user has full privileges if ($anObjectType->getValue("admineditable") == 0 || $anObjectType->getValue("admineditable") == 2 && $user->hasAdminClearance(CLEARANCE_ADMINISTRATION_EDITVALIDATEALL)) { //load fields objects for object $objectFields = CMS_poly_object_catalog::getFieldsDefinition($anObjectType->getID()); if (sizeof($objectFields)) { $objectsInfos[] = array('label' => $anObjectType->getLabel($cms_language), 'adminLabel' => $anObjectType->getLabel($cms_language), 'description' => $anObjectType->getDescription($cms_language), 'objectId' => $anObjectType->getID(), 'url' => PATH_ADMIN_MODULES_WR . '/' . MOD_POLYMOD_CODENAME . '/items.php', 'module' => $this->getCodename(), 'class' => 'atm-elements'); //get categories fields for object if (count($catFieldsNames) < 3) { $thisFieldsCategories = CMS_poly_object_catalog::objectHasCategories($anObjectType->getID()); if ($thisFieldsCategories) { $fields = CMS_poly_object_catalog::getFieldsDefinition($anObjectType->getID()); foreach ($thisFieldsCategories as $catField) { if (isset($fields[$catField]) && is_object($fields[$catField])) { $label = new CMS_object_i18nm($fields[$catField]->getValue("labelID")); $catFieldsNames[] = $label->getValue($cms_language->getCode()) . ' (' . $anObjectType->getLabel($cms_language) . ')'; } } } } else { if (!in_array('...', $catFieldsNames)) { $catFieldsNames[] = '...'; } } } } } } //Categories //if user has some categories to manage $userManageCategories = $user->getRootModuleCategoriesManagable($this->getCodename()); if ($catFieldsNames && (is_array($userManageCategories) && $userManageCategories || $user->hasAdminClearance(CLEARANCE_ADMINISTRATION_EDITVALIDATEALL))) { $objectsInfos[] = array('label' => $cms_language->getMessage(self::MESSAGE_PAGE_CATEGORIES), 'adminLabel' => $cms_language->getMessage(self::MESSAGE_PAGE_ADMIN_CATEGORIES), 'description' => $cms_language->getMessage(self::MESSAGE_PAGE_CATEGORIES_USED, false, MOD_POLYMOD_CODENAME) . io::htmlspecialchars(implode(', ', $catFieldsNames)), 'objectId' => 'categories', 'url' => PATH_ADMIN_WR . '/modules-categories.php', 'module' => $this->getCodename(), 'class' => 'atm-categories'); } return $objectsInfos; }
/** * is this object use categories ? * * @return boolean * @access public */ function hasCategories() { return CMS_poly_object_catalog::objectHasCategories($this->getID()); }