$nodeAssignments = $contentObject->attribute('assigned_nodes'); if (count($nodeAssignments) === 0) { // oops, no locations. probably it's related object. Let's check his owners $ownerList = eZContentObject::fetch($contentObjectID)->reverseRelatedObjectList(false, false, false, false); foreach ($ownerList as $owner) { if (is_object($owner)) { $ownerNodeAssignments = $owner->attribute('assigned_nodes'); $nodeAssignments = array_merge($nodeAssignments, $ownerNodeAssignments); } } } // If exists location that current user has access to and location is visible. $canAccess = false; $isContentDraft = $contentObject->attribute('status') == eZContentObject::STATUS_DRAFT; foreach ($nodeAssignments as $nodeAssignment) { if (eZContentObjectTreeNode::showInvisibleNodes() || !$nodeAssignment->attribute('is_invisible') and $nodeAssignment->canRead()) { $canAccess = true; break; } } if (!$canAccess && !$isContentDraft) { return $Module->handleError(eZError::KERNEL_NOT_AVAILABLE, 'kernel'); } // If $version is not current version (published) // we should check permission versionRead for the $version. if ($version != $currentVersion || $isContentDraft) { $versionObj = eZContentObjectVersion::fetchVersion($version, $contentObjectID); if (is_object($versionObj) and !$versionObj->canVersionRead()) { return $Module->handleError(eZError::KERNEL_NOT_AVAILABLE, 'kernel'); } }
*/ $module = $Params['Module']; $viewMode = 'full'; $nodeID = $Params['NodeID']; $userParameters = array(); if (isset($Params['UserParameters'])) { $userParameters = $Params['UserParameters']; } if (!$nodeID) { return $module->handleError(eZError::KERNEL_NOT_AVAILABLE, 'kernel'); } $node = eZContentObjectTreeNode::fetch($nodeID); if (!$node) { return $module->handleError(eZError::KERNEL_NOT_AVAILABLE, 'kernel'); } if ($node->attribute('is_invisible') && !eZContentObjectTreeNode::showInvisibleNodes()) { return $Module->handleError(eZError::KERNEL_ACCESS_DENIED, 'kernel'); } $object = $node->attribute('object'); if (!$object) { return $module->handleError(eZError::KERNEL_NOT_AVAILABLE, 'kernel'); } if (!$object->attribute('can_read')) { return $module->handleError(eZError::KERNEL_ACCESS_DENIED, 'kernel'); } $http = eZHTTPTool::instance(); $tpl = eZTemplate::factory(); $icMap = array(); if ($http->hasSessionVariable('InformationCollectionMap')) { $icMap = $http->sessionVariable('InformationCollectionMap'); }
/** * Search on the Solr search server * * @param string search term * @param array parameters. * Example: * <code> * array( 'SearchOffset' => <offset>, * 'SearchLimit' => <limit>, * 'SearchSubTreeArray' => array( <node ID1>[, <node ID2>]... ), * 'SearchContentClassID' => array( <class ID1>[, <class ID2>]... ), * 'SearchContentClassAttributeID' => <class attribute ID>, * 'Facet' => array( array( 'field' => <class identifier>/<attribute identifier>[/<option>], ... ) ) ), * 'Filter' => array( <base_name> => <value>, <base_name2> => <value2> ), * 'SortBy' => array( <field> => <asc|desc> [, <field2> => <asc|desc> [,...]] ) | * array( array( <field> => <asc|desc> )[, array( <field2> => <asc|desc> )[,...]] ), * 'BoostFunctions' => array( 'fields' => array( * 'article/title' => 2, * 'modified:5' * ), * 'functions' => array( 'rord(meta_modified_dt)^10' ) * ), * 'ForceElevation' => false, * 'EnableElevation' => true * 'DistributedSearch" => array ( 'shards', array( 'shard1', 'shard2' , ... ) * 'searchfields', array ( 'myfield1, 'myfield2', ... ) * 'returnfields', array ( 'myfield1, 'myfield2', ... ) * 'rawfilterlist, array ( 'foreignfield:a', '(foreignfield:b AND otherfield:c)', ... ) * ) * ); * </code> * For full facet description, see facets design document. * For full description about 'ForceElevation', see elevate support design document ( elevate_support.rst.txt ) * * the rawFilterList in distributed search is appended to the policyfilterlist with an 'OR' for each entry, as the policy list will * in general not be applicable to foreign indexes. To be used with care! * * @param array Search types. Reserved. * * @return array Solr query results. * * @see ezfeZPSolrQueryBuilder::buildBoostFunctions() */ public function buildSearch($searchText, $params = array(), $searchTypes = array()) { eZDebugSetting::writeDebug('extension-ezfind-query', $params, 'search params'); $searchCount = 0; $eZFindIni = eZINI::instance('ezfind.ini'); $solrIni = eZINI::instance('solr.ini'); $siteIni = eZINI::instance('site.ini'); $offset = isset($params['SearchOffset']) ? $params['SearchOffset'] : 0; $limit = isset($params['SearchLimit']) ? $params['SearchLimit'] : 10; $subtrees = isset($params['SearchSubTreeArray']) ? $params['SearchSubTreeArray'] : array(); $contentClassID = isset($params['SearchContentClassID']) && $params['SearchContentClassID'] != -1 ? $params['SearchContentClassID'] : false; $contentClassAttributeID = isset($params['SearchContentClassAttributeID']) && $params['SearchContentClassAttributeID'] != -1 ? $params['SearchContentClassAttributeID'] : false; $sectionID = isset($params['SearchSectionID']) && $params['SearchSectionID'] > 0 ? $params['SearchSectionID'] : false; $dateFilter = isset($params['SearchDate']) && $params['SearchDate'] > 0 ? $params['SearchDate'] : false; $asObjects = isset($params['AsObjects']) ? $params['AsObjects'] : true; $spellCheck = isset($params['SpellCheck']) && $params['SpellCheck'] > 0 ? $params['SpellCheck'] : array(); $queryHandler = isset($params['QueryHandler']) ? $params['QueryHandler'] : $eZFindIni->variable('SearchHandler', 'DefaultSearchHandler'); // eZFInd 2.3: check ini setting and take it as a default instead of false $visibilityDefaultSetting = $siteIni->variable('SiteAccessSettings', 'ShowHiddenNodes'); $visibilityDefault = $visibilityDefaultSetting === 'true' ? true : false; $ignoreVisibility = isset($params['IgnoreVisibility']) ? $params['IgnoreVisibility'] : $visibilityDefault; $this->searchPluginInstance->postSearchProcessingData['ignore_visibility'] = $ignoreVisibility; $limitation = isset($params['Limitation']) ? $params['Limitation'] : null; $boostFunctions = isset($params['BoostFunctions']) ? $params['BoostFunctions'] : null; $forceElevation = isset($params['ForceElevation']) ? $params['ForceElevation'] : false; $enableElevation = isset($params['EnableElevation']) ? $params['EnableElevation'] : true; $distributedSearch = isset($params['DistributedSearch']) ? $params['DistributedSearch'] : false; $fieldsToReturn = isset($params['FieldsToReturn']) ? $params['FieldsToReturn'] : array(); $highlightParams = isset($params['HighLightParams']) ? $params['HighLightParams'] : array(); $searchResultClusterParams = isset($params['SearchResultClustering']) ? $params['SearchResultClustering'] : array(); $extendedAttributeFilter = isset($params['ExtendedAttributeFilter']) ? $params['ExtendedAttributeFilter'] : array(); // distributed search option // @since ezfind 2.2 $extraFieldsToSearch = array(); $extraFieldsToReturn = array(); $shardURLs = array(); $iniShards = $solrIni->variable('SolrBase', 'Shards'); $shardQuery = NULL; $shardFilterQuery = array(); if (isset($distributedSearch['shards'])) { foreach ($distributedSearch['shards'] as $shard) { $shardURLs[] = $iniShards[$shard]; } $shardQuery = implode(',', $shardURLs); } if (isset($distributedSearch['searchfields'])) { $extraFieldsToSearch = $distributedSearch['searchfields']; } if (isset($distributedSearch['returnfields'])) { $extraFieldsToReturn = $distributedSearch['returnfields']; } if (isset($distributedSearch['rawfilterlist'])) { $shardFilterQuery = $distributedSearch['rawfilterlist']; } // check if filter parameter is indeed an array, and set it otherwise if (isset($params['Filter']) && !is_array($params['Filter'])) { $params['Filter'] = array($params['Filter']); } $pathFieldName = eZSolr::getMetaFieldName($ignoreVisibility ? 'path' : 'visible_path'); $filterQuery = array(); // Add subtree query filter if (!empty($subtrees)) { $this->searchPluginInstance->postSearchProcessingData['subtree_array'] = $subtrees; $subtreeQueryParts = array(); foreach ($subtrees as $subtreeNodeID) { $subtreeQueryParts[] = $pathFieldName . ':' . $subtreeNodeID; } $filterQuery[] = implode(' OR ', $subtreeQueryParts); } // Add policy limitation query filter $policyLimitationFilterQuery = $this->policyLimitationFilterQuery($limitation, $ignoreVisibility); if ($policyLimitationFilterQuery !== false) { $filterQuery[] = $policyLimitationFilterQuery; } // Add time/date query filter if ($dateFilter > 0) { switch ($dateFilter) { // last day case 1: $searchTimestamp = strtotime('-1 day'); break; // last week // last week case 2: $searchTimestamp = strtotime('-1 week'); break; // last month // last month case 3: $searchTimestamp = strtotime('-1 month'); break; // last three month // last three month case 4: $searchTimestamp = strtotime('-3 month'); break; // last year // last year case 5: $searchTimestamp = strtotime('-1 year'); break; } $filterQuery[] = eZSolr::getMetaFieldName('published') . ':[' . ezfSolrDocumentFieldBase::preProcessValue($searchTimestamp, 'date') . '/DAY TO *]'; } if ((!eZContentObjectTreeNode::showInvisibleNodes() || !$ignoreVisibility) && $eZFindIni->variable('SearchFilters', 'FilterHiddenFromDB') == 'enabled') { $db = eZDB::instance(); $invisibleNodeIDArray = $db->arrayQuery('SELECT node_id FROM ezcontentobject_tree WHERE ezcontentobject_tree.is_invisible = 1', array('column' => 0)); $hiddenNodesQueryText = 'meta_main_node_id_si:[* TO *] -meta_main_node_id_si:('; foreach ($invisibleNodeIDArray as $element) { $hiddenNodesQueryText = $hiddenNodesQueryText . $element['node_id'] . ' '; } $hiddenNodesQueryText = $hiddenNodesQueryText . ')'; // only add filter if there are hidden nodes after all if ($invisibleNodeIDArray) { $filterQuery[] = $hiddenNodesQueryText; } } // Add content class query filter $classLimitationFilter = $this->getContentClassFilterQuery($contentClassID); if ($classLimitationFilter !== null) { $filterQuery[] = $classLimitationFilter; } // Add section to query filter. if ($sectionID) { $filterQuery[] = eZSolr::getMetaFieldName('section_id') . ':' . $sectionID; } $languageFilterQuery = $this->buildLanguageFilterQuery(); if ($languageFilterQuery) { $filterQuery[] = $languageFilterQuery; } $paramFilterQuery = $this->getParamFilterQuery($params); if (!empty($paramFilterQuery)) { $filterQuery = array_merge($filterQuery, $paramFilterQuery); } //add raw filters if ($eZFindIni->hasVariable('SearchFilters', 'RawFilterList')) { $rawFilters = $eZFindIni->variable('SearchFilters', 'RawFilterList'); if (is_array($rawFilters)) { $filterQuery = array_merge($filterQuery, $rawFilters); } } // Build and get facet query prameters. $facetQueryParamList = $this->buildFacetQueryParamList($params); // search only text type declared fields $fieldTypeExcludeList = $this->fieldTypeExludeList(NULL); // Create sort parameters based on the parameters. $sortParameter = $this->buildSortParameter($params); //the array_unique below is necessary because attribute identifiers are not unique .. and we get as //much highlight snippets as there are duplicate attribute identifiers //these are also in the list of query fields (dismax, ezpublish) request handlers $queryFields = array_unique($this->getClassAttributes($contentClassID, $contentClassAttributeID, $fieldTypeExcludeList)); //highlighting only in the attributes, otherwise the object name is repeated in the highlight, which is already //partly true as it is mostly composed of one or more attributes. //maybe we should add meta data to the index to filter them out. $highLightFields = $queryFields; //@since eZ Find 2.3 //when dedicated attributes are searched for, don't add meta-fields to the $queryfields list if (!$contentClassAttributeID) { $queryFields[] = eZSolr::getMetaFieldName('name'); if (!$eZFindIni->hasVariable('SearchFilters', 'ExcludeOwnerName') || $eZFindIni->variable('SearchFilters', 'ExcludeOwnerName') !== 'enabled') { $queryFields[] = eZSolr::getMetaFieldName('owner_name'); } } $spellCheckParamList = array(); // @param $spellCheck expects array (true|false, dictionary identifier, ...) if (isset($spellCheck[0]) and $spellCheck[0] or $eZFindIni->variable('SpellCheck', 'SpellCheck') == 'enabled' and (isset($spellCheck[0]) and !$spellCheck[0])) { $dictionary = isset($spellCheck[1]) ? $spellCheck[1] : $eZFindIni->variable('SpellCheck', 'DefaultDictionary'); $spellCheckParamList = array('spellcheck' => 'true', 'spellcheck.q' => $searchText, 'spellcheck.dictionary' => $dictionary, 'spellcheck.collate' => 'true', 'spellcheck.extendedResults' => 'true', 'spellcheck.onlyMorePopular' => 'true', 'spellcheck.count' => 1); } // Create the Elevate-related parameters here : $elevateParamList = eZFindElevateConfiguration::getRuntimeQueryParameters($forceElevation, $enableElevation, $searchText); // process query handler: standard, simplestandard, ezpublish, heuristic // first determine which implemented handler to use when heuristic is specified if (strtolower($queryHandler) === 'heuristic') { // @todo: this code will evolve of course if (preg_match('/[\\^\\*\\~]|AND|OR/', $searchText) > 0) { $queryHandler = 'simplestandard'; } else { $queryHandler = 'ezpublish'; } } $handlerParameters = array(); $queryHandler = strtolower($queryHandler); switch ($queryHandler) { case 'standard': // @todo: this is more complicated // build the query against all "text" like fields // should take into account all the filter fields and class filters to shorten the query // need to build: Solr q if (array_key_exists('fields', $boostFunctions)) { $handlerParameters = array('q' => $this->buildMultiFieldQuery($searchText, array_merge($queryFields, $extraFieldsToSearch), $boostFunctions['fields']), 'qt' => 'standard'); } else { $handlerParameters = array('q' => $this->buildMultiFieldQuery($searchText, array_merge($queryFields, $extraFieldsToSearch)), 'qt' => 'standard'); } break; case 'simplestandard': // not to do much, searching is against the default aggregated field // only highlightfields $highLightFields = array('ezf_df_text'); $handlerParameters = array('q' => $searchText, 'qt' => 'standard', 'hl.usePhraseHighlighter' => 'true', 'hl.highlightMultiTerm' => 'true'); break; case 'ezpublish': // the dismax based handler, just keywordss input, most useful for ordinary queries by users // need to build: Solr q, qf, dismax specific parameters // the dismax based handler, just keywordss input, most useful for ordinary queries by users // need to build: Solr q, qf, dismax specific parameters default: // ezpublish of course, this to not break BC and is the most "general" // if another value is specified, it is supposed to be a dismax like handler // with possible other tuning variables then the stock provided 'ezpublish' in solrconfi.xml // remark it should be lowercase in solrconfig.xml! $boostQueryString = $this->boostQuery(); $rawBoostQueries = $eZFindIni->variable('QueryBoost', 'RawBoostQueries'); if (is_array($rawBoostQueries) && !empty($rawBoostQueries)) { $boostQueryString .= ' ' . implode(' ', $rawBoostQueries); } $handlerParameters = array('q' => $searchText, 'bq' => $boostQueryString, 'qf' => implode(' ', array_merge($queryFields, $extraFieldsToSearch)), 'qt' => $queryHandler); } // Handle boost functions : $boostFunctionsParamList = $this->buildBoostFunctions($boostFunctions, $handlerParameters); // special handling of filters in the case of distributed search filters // incorporate distributed search filters if defined with an OR expression, and AND-ing all others // need to do this as multiple fq elements are otherwise AND-ed by the Solr backend // when using this to search across a dedicated set of languages, it will still be valid with the ezp permission // scheme if (!empty($shardFilterQuery)) { $fqString = '((' . implode(') AND (', $filterQuery) . ')) OR ((' . implode(') OR (', $shardFilterQuery) . '))'; // modify the filterQuery array with this single string as the only element $filterQuery = array($fqString); } // Document transformer fields since eZ Find 5.4 $docTransformerFields = array('[elevated]'); $fieldsToReturnString = eZSolr::getMetaFieldName('guid') . ' ' . eZSolr::getMetaFieldName('installation_id') . ' ' . eZSolr::getMetaFieldName('main_url_alias') . ' ' . eZSolr::getMetaFieldName('installation_url') . ' ' . eZSolr::getMetaFieldName('id') . ' ' . eZSolr::getMetaFieldName('main_node_id') . ' ' . eZSolr::getMetaFieldName('language_code') . ' ' . eZSolr::getMetaFieldName('name') . ' score ' . eZSolr::getMetaFieldName('published') . ' ' . eZSolr::getMetaFieldName('path_string') . ' ' . eZSolr::getMetaFieldName('main_path_string') . ' ' . eZSolr::getMetaFieldName('is_invisible') . ' ' . implode(' ', $docTransformerFields) . ' ' . implode(' ', $extraFieldsToReturn); if (!$asObjects) { if (empty($fieldsToReturn)) { // @todo: needs to be refined with Solr supporting globbing in fl argument, otherwise requests will be to heavy for large fields as for example binary file content $fieldsToReturnString = 'score, *'; } else { $fieldsToReturnString .= ' ' . implode(',', $fieldsToReturn); } } $searchResultClusterParamList = array('clustering' => 'true'); $searchResultClusterParamList = $this->buildSearchResultClusterQuery($searchResultClusterParams); eZDebugSetting::writeDebug('extension-ezfind-query', $searchResultClusterParamList, 'Cluster params'); $queryParams = array_merge($handlerParameters, array('start' => $offset, 'rows' => $limit, 'sort' => $sortParameter, 'indent' => 'on', 'version' => '2.2', 'fl' => $fieldsToReturnString, 'fq' => $filterQuery, 'hl' => $eZFindIni->variable('HighLighting', 'Enabled'), 'hl.fl' => implode(' ', $highLightFields), 'hl.snippets' => $eZFindIni->variable('HighLighting', 'SnippetsPerField'), 'hl.fragsize' => $eZFindIni->variable('HighLighting', 'FragmentSize'), 'hl.requireFieldMatch' => $eZFindIni->variable('HighLighting', 'RequireFieldMatch'), 'hl.simple.pre' => $eZFindIni->variable('HighLighting', 'SimplePre'), 'hl.simple.post' => $eZFindIni->variable('HighLighting', 'SimplePost'), 'wt' => 'php'), $facetQueryParamList, $spellCheckParamList, $boostFunctionsParamList, $elevateParamList, $searchResultClusterParamList); if (isset($extendedAttributeFilter['id']) && isset($extendedAttributeFilter['params'])) { //single filter $extendedAttributeFilter = array($extendedAttributeFilter); } foreach ($extendedAttributeFilter as $filterDefinition) { if (isset($filterDefinition['id'])) { $filter = eZFindExtendedAttributeFilterFactory::getInstance($filterDefinition['id']); if ($filter) { $filterParams = isset($filterDefinition['params']) ? $filterDefinition['params'] : array(); $queryParams = $filter->filterQueryParams($queryParams, $filterParams); } } } return $queryParams; }
/** * Generates an RSS feed document with type $type and returns it as a string. * * It uses the Feed component from eZ Components. * * Supported types: 'rss1', 'rss2', 'atom'. * * @since 4.2 * @param string $type One of 'rss1', 'rss2' and 'atom' * @return string XML document as a string */ function generateFeed( $type ) { $locale = eZLocale::instance(); // Get URL Translation settings. $config = eZINI::instance(); if ( $config->variable( 'URLTranslator', 'Translation' ) == 'enabled' ) { $useURLAlias = true; } else { $useURLAlias = false; } if ( $this->attribute( 'url' ) == '' ) { $baseItemURL = ''; eZURI::transformURI( $baseItemURL, false, 'full' ); $baseItemURL .= '/'; } else { $baseItemURL = $this->attribute( 'url' ) . '/'; //.$this->attribute( 'site_access' ).'/'; } $feed = new ezcFeed(); $feed->title = $this->attribute( 'title' ); $link = $feed->add( 'link' ); $link->href = $baseItemURL; $feed->description = $this->attribute( 'description' ); $feed->language = $locale->httpLocaleCode(); // to add the <atom:link> element needed for RSS2 $feed->id = $baseItemURL . 'rss/feed/' . $this->attribute( 'access_url' ); // required for ATOM $feed->updated = time(); $author = $feed->add( 'author' ); $author->email = $config->variable( 'MailSettings', 'AdminEmail' ); $creatorObject = eZContentObject::fetch( $this->attribute( 'creator_id' ) ); if ( $creatorObject instanceof eZContentObject ) { $author->name = $creatorObject->attribute('name'); } $imageURL = $this->fetchImageURL(); if ( $imageURL !== false ) { $image = $feed->add( 'image' ); // Required for RSS1 $image->about = $imageURL; $image->url = $imageURL; $image->title = $this->attribute( 'title' ); $image->link = $baseItemURL; } $cond = array( 'rssexport_id' => $this->ID, 'status' => $this->Status ); $rssSources = eZRSSExportItem::fetchFilteredList( $cond ); $nodeArray = eZRSSExportItem::fetchNodeList( $rssSources, $this->getObjectListFilter() ); if ( is_array( $nodeArray ) && count( $nodeArray ) ) { $attributeMappings = eZRSSExportItem::getAttributeMappings( $rssSources ); foreach ( $nodeArray as $node ) { if ( $node->attribute('is_hidden') && !eZContentObjectTreeNode::showInvisibleNodes() ) { // if the node is hidden skip past it and don't add it to the RSS export continue; } $object = $node->attribute( 'object' ); $dataMap = $object->dataMap(); if ( $useURLAlias === true ) { $nodeURL = $this->urlEncodePath( $baseItemURL . $node->urlAlias() ); } else { $nodeURL = $baseItemURL . 'content/view/full/' . $node->attribute( 'node_id' ); } // keep track if there's any match $doesMatch = false; // start mapping the class attribute to the respective RSS field foreach ( $attributeMappings as $attributeMapping ) { // search for correct mapping by path if ( $attributeMapping[0]->attribute( 'class_id' ) == $object->attribute( 'contentclass_id' ) and in_array( $attributeMapping[0]->attribute( 'source_node_id' ), $node->attribute( 'path_array' ) ) ) { // found it $doesMatch = true; // now fetch the attributes $title = $dataMap[$attributeMapping[0]->attribute( 'title' )]; // description is optional $descAttributeIdentifier = $attributeMapping[0]->attribute( 'description' ); $description = $descAttributeIdentifier ? $dataMap[$descAttributeIdentifier] : false; // category is optional $catAttributeIdentifier = $attributeMapping[0]->attribute( 'category' ); $category = $catAttributeIdentifier ? $dataMap[$catAttributeIdentifier] : false; // enclosure is optional $enclosureAttributeIdentifier = $attributeMapping[0]->attribute( 'enclosure' ); $enclosure = $enclosureAttributeIdentifier ? $dataMap[$enclosureAttributeIdentifier] : false; break; } } if( !$doesMatch ) { // no match eZDebug::writeError( 'Cannot find matching RSS attributes for datamap on node: ' . $node->attribute( 'node_id' ), __METHOD__ ); return null; } // title RSS element with respective class attribute content $titleContent = $title->attribute( 'content' ); if ( $titleContent instanceof eZXMLText ) { $outputHandler = $titleContent->attribute( 'output' ); $itemTitleText = $outputHandler->attribute( 'output_text' ); } else { $itemTitleText = $titleContent; } $item = $feed->add( 'item' ); $item->title = $itemTitleText; $link = $item->add( 'link' ); $link->href = $nodeURL; switch ( $type ) { case 'rss2': $item->id = $object->attribute( 'remote_id' ); $item->id->isPermaLink = false; break; default: $item->id = $nodeURL; } $itemCreatorObject = $node->attribute('creator'); if ( $itemCreatorObject instanceof eZContentObject ) { $author = $item->add( 'author' ); $author->name = $itemCreatorObject->attribute('name'); $author->email = $config->variable( 'MailSettings', 'AdminEmail' ); } // description RSS element with respective class attribute content if ( $description ) { $descContent = $description->attribute( 'content' ); if ( $descContent instanceof eZXMLText ) { $outputHandler = $descContent->attribute( 'output' ); $itemDescriptionText = str_replace( ' ', '&nbsp;', $outputHandler->attribute( 'output_text' ) ); } else if ( $descContent instanceof eZImageAliasHandler ) { $itemImage = $descContent->hasAttribute( 'rssitem' ) ? $descContent->attribute( 'rssitem' ) : $descContent->attribute( 'rss' ); $origImage = $descContent->attribute( 'original' ); eZURI::transformURI( $itemImage['full_path'], true, 'full' ); eZURI::transformURI( $origImage['full_path'], true, 'full' ); $itemDescriptionText = '<a href="' . htmlspecialchars( $origImage['full_path'] ) . '"><img alt="' . htmlspecialchars( $descContent->attribute( 'alternative_text' ) ) . '" src="' . htmlspecialchars( $itemImage['full_path'] ) . '" width="' . $itemImage['width'] . '" height="' . $itemImage['height'] . '" /></a>'; } else { $itemDescriptionText = $descContent; } $item->description = $itemDescriptionText; } // category RSS element with respective class attribute content if ( $category ) { $categoryContent = $category->attribute( 'content' ); if ( $categoryContent instanceof eZXMLText ) { $outputHandler = $categoryContent->attribute( 'output' ); $itemCategoryText = $outputHandler->attribute( 'output_text' ); } elseif ( $categoryContent instanceof eZKeyword ) { $itemCategoryText = $categoryContent->keywordString(); } else { $itemCategoryText = $categoryContent; } if ( $itemCategoryText ) { $cat = $item->add( 'category' ); $cat->term = $itemCategoryText; } } // enclosure RSS element with respective class attribute content if ( $enclosure ) { $encItemURL = false; $enclosureContent = $enclosure->attribute( 'content' ); if ( $enclosureContent instanceof eZMedia ) { $enc = $item->add( 'enclosure' ); $enc->length = $enclosureContent->attribute('filesize'); $enc->type = $enclosureContent->attribute('mime_type'); $encItemURL = 'content/download/' . $enclosure->attribute('contentobject_id') . '/' . $enclosureContent->attribute( 'contentobject_attribute_id' ) . '/' . urlencode( $enclosureContent->attribute( 'original_filename' ) ); eZURI::transformURI( $encItemURL, false, 'full' ); } else if ( $enclosureContent instanceof eZBinaryFile ) { $enc = $item->add( 'enclosure' ); $enc->length = $enclosureContent->attribute('filesize'); $enc->type = $enclosureContent->attribute('mime_type'); $encItemURL = 'content/download/' . $enclosure->attribute('contentobject_id') . '/' . $enclosureContent->attribute( 'contentobject_attribute_id' ) . '/version/' . $enclosureContent->attribute( 'version' ) . '/file/' . urlencode( $enclosureContent->attribute( 'original_filename' ) ); eZURI::transformURI( $encItemURL, false, 'full' ); } else if ( $enclosureContent instanceof eZImageAliasHandler ) { $enc = $item->add( 'enclosure' ); $origImage = $enclosureContent->attribute( 'original' ); $enc->length = $origImage['filesize']; $enc->type = $origImage['mime_type']; $encItemURL = $origImage['full_path']; eZURI::transformURI( $encItemURL, true, 'full' ); } if ( $encItemURL ) { $enc->url = $encItemURL; } } $item->published = $object->attribute( 'published' ); $item->updated = $object->attribute( 'published' ); } } return $feed->generate( $type ); }
/** * Generate convent view data * * @see contentViewRetrieve() * * @param string|false $file File in which the result will be cached * @param array $args Hash containing arguments, the used ones are: * - NodeID * - Module * - tpl * - LanguageCode * - ViewMode * - Offset * - viewParameters * - collectionAttributes * - validation * - noCache (optional) * * @return array */ public static function contentViewGenerate($file, $args) { extract($args); $node = eZContentObjectTreeNode::fetch($NodeID); if (!$node instanceof eZContentObjectTreeNode) { if (!eZDB::instance()->isConnected()) { return self::contentViewGenerateError($Module, eZError::KERNEL_NO_DB_CONNECTION, false); } return self::contentViewGenerateError($Module, eZError::KERNEL_NOT_AVAILABLE); } $object = $node->attribute('object'); if (!$object instanceof eZContentObject) { return self::contentViewGenerateError($Module, eZError::KERNEL_NOT_AVAILABLE); } if ($node->attribute('is_invisible') && !eZContentObjectTreeNode::showInvisibleNodes()) { return self::contentViewGenerateError($Module, eZError::KERNEL_ACCESS_DENIED); } if (!$node->canRead()) { return self::contentViewGenerateError($Module, eZError::KERNEL_ACCESS_DENIED, true, array('AccessList' => $node->checkAccess('read', false, false, true))); } $result = self::generateNodeViewData($tpl, $node, $object, $LanguageCode, $ViewMode, $Offset, $viewParameters, $collectionAttributes, $validation); // 'store' depends on noCache: if $noCache is set, this means that retrieve // returned it, and the noCache fake cache file is already stored // and should not be stored again $retval = array('content' => $result, 'scope' => 'viewcache', 'store' => !(isset($noCache) and $noCache)); if ($file !== false && $retval['store']) { $retval['binarydata'] = serialize($result); } return $retval; }
static function createShowInvisibleSQLString($useSettings, $fetchHidden = true) { $showInvisibleNodesCond = ''; $showInvisible = $fetchHidden; if ($useSettings) { $showInvisible = eZContentObjectTreeNode::showInvisibleNodes(); } if (!$showInvisible) { $showInvisibleNodesCond = 'AND ezcontentobject_tree.is_invisible = 0'; } return $showInvisibleNodesCond; }
static function contentViewGenerate($file, $args) { extract($args); $node = eZContentObjectTreeNode::fetch($NodeID); if (!is_object($node)) { if (!eZDB::instance()->isConnected()) { return array('content' => $Module->handleError(eZError::KERNEL_NO_DB_CONNECTION, 'kernel'), 'store' => false); } else { return array('content' => $Module->handleError(eZError::KERNEL_NOT_AVAILABLE, 'kernel'), 'store' => false); } } $object = $node->attribute('object'); if (!is_object($object)) { return array('content' => $Module->handleError(eZError::KERNEL_NOT_AVAILABLE, 'kernel'), 'store' => false); } if (!$object instanceof eZContentObject) { return array('content' => $Module->handleError(eZError::KERNEL_NOT_AVAILABLE, 'kernel'), 'store' => false); } if ($node === null) { return array('content' => $Module->handleError(eZError::KERNEL_NOT_AVAILABLE, 'kernel'), 'store' => false); } if ($object === null) { return array('content' => $Module->handleError(eZError::KERNEL_ACCESS_DENIED, 'kernel'), 'store' => false); } // HACK! Ignore showInvisibleNodes policy for the 'detail' view mode in ez_sbase. We do policy // checking in the template. if ($ViewMode != 'detail') { if ($node->attribute('is_invisible') && !eZContentObjectTreeNode::showInvisibleNodes()) { return array('content' => $Module->handleError(eZError::KERNEL_ACCESS_DENIED, 'kernel'), 'store' => false); } } if (!$object->canRead()) { return array('content' => $Module->handleError(eZError::KERNEL_ACCESS_DENIED, 'kernel', array('AccessList' => $object->accessList('read'))), 'store' => false); } $Result = eZNodeviewfunctions::generateNodeViewData($tpl, $node, $object, $LanguageCode, $ViewMode, $Offset, $viewParameters, $collectionAttributes, $validation); // 'store' depends on noCache: if $noCache is set, this means that retrieve // returned it, and the noCache fake cache file is already stored // and should not be stored again $retval = array('content' => $Result, 'scope' => 'viewcache', 'store' => !(isset($noCache) and $noCache)); if ($file !== false && $retval['store']) { $retval['binarydata'] = serialize($Result); } return $retval; }
/** * Returns the relative NodeID for a given search result, * depending on whether a subtree filter was applied or not and limitations by user policy limitations. * * Policy limitations (subtree/node) are aggregated by a logic OR (same for subtree filters). * Subtree filters and policy limitations are aggregated together with a logic AND, * so that valid locations must comply subtree filters (if any) AND subtree/node policy limitations (if any) * * @param array $doc The search result, directly received from Solr. * @return int The NodeID corresponding the search result */ protected function getNodeID($doc) { $docPathStrings = $doc[ezfSolrDocumentFieldBase::generateMetaFieldName('path_string')]; $docVisibilities = $doc[ezfSolrDocumentFieldBase::generateMetaFieldName('is_invisible')]; if (count($docPathStrings) > 1) { // reordering the path strings and the associated visibilities so // that the main node path string and the main node visibility are // in the first position. $mainNodeIdx = array_search($doc[ezfSolrDocumentFieldBase::generateMetaFieldName('main_path_string')], $docPathStrings); if ($mainNodeIdx != 0) { array_unshift($docVisibilities, $docVisibilities[$mainNodeIdx]); array_unshift($docPathStrings, $docPathStrings[$mainNodeIdx]); unset($docVisibilities[$mainNodeIdx], $docPathStrings[$mainNodeIdx]); } } $locationFilter = isset($this->postSearchProcessingData['subtree_array']) ? $this->postSearchProcessingData['subtree_array'] : array(); $subtreeLimitations = isset($this->postSearchProcessingData['subtree_limitations']) ? $this->postSearchProcessingData['subtree_limitations'] : array(); $validSubtreeArray = $this->getValidPathStringsByLimitation($docPathStrings, $locationFilter); $validSubtreeLimitations = $this->getValidPathStringsByLimitation($docPathStrings, $subtreeLimitations); $ignoreVisibility = eZContentObjectTreeNode::showInvisibleNodes(); if (isset($this->postSearchProcessingData['ignore_visibility'])) { $ignoreVisibility = $this->postSearchProcessingData['ignore_visibility']; } // Intersect between $validSubtreeArray (search location filter) and $validSubtreeLimitations (user policy limitations) // indicates valid locations for $doc in current search query // If this intersect is not empty, we take the first node id that // matches the visibility requirement $validSubtrees = array_flip(array_intersect($validSubtreeArray, $validSubtreeLimitations)); if (!empty($validSubtrees)) { foreach ($docPathStrings as $k => $path) { if (isset($validSubtrees[$path])) { if ($ignoreVisibility || !$docVisibilities[$k]) { $nodeArray = explode('/', rtrim($path, '/')); return (int) array_pop($nodeArray); } } } eZDebug::writeError("Could not find a visible location for content " . "#{$doc[ezfSolrDocumentFieldBase::generateMetaFieldName('id')]} " . "that current user has read access on. The Solr index is probably outdated", __METHOD__); } else { $contentId = $doc[ezfSolrDocumentFieldBase::generateMetaFieldName('id')]; $content = eZContentObject::fetch($contentId); if ($content instanceof eZContentObject && !$content->canRead()) { eZDebug::writeError("Could not find valid/granted locations for content #{$contentId}. Broken sync between eZPublish and Solr ?\n\n" . "Location filter : " . print_r($locationFilter, true) . "Subtree limitations for user : " . print_r($subtreeLimitations, true), __METHOD__); } foreach ($docPathStrings as $k => $path) { if ($ignoreVisibility || !$docVisibilities[$k]) { $nodeArray = explode('/', rtrim($path, '/')); return (int) array_pop($nodeArray); } } } return (int) $doc[ezfSolrDocumentFieldBase::generateMetaFieldName('main_node_id')]; }