diff --git a/doc/bc/5.90/relation_indexing.md b/doc/bc/5.90/relation_indexing.md new file mode 100644 index 00000000000..d42e091ff8c --- /dev/null +++ b/doc/bc/5.90/relation_indexing.md @@ -0,0 +1,15 @@ +# Relation search indexing changes + +For the 2018.06 release, eZ Publish changed the way relations are indexed. Previously the relation metadata was loaded recursively, meaning that relations of relations etc. were also included. This behavior was changed to only include Objects one level deep so only direct relations are taken into account. + +The change was done to avoid various recursion problems when relations are circular. Also, the new behavior allows for better (more relevant) search results. + +The affected kernel Datatypes are eZObjectRelationType and eZObjectRelationListType. + +If you have your custom Datatype that stores relations to other Objects, you can make it behave similarly. Just add the following to your Datatype class: +```php + public function isRelationType() + { + return true; + } +``` diff --git a/kernel/classes/datatypes/ezobjectrelation/ezobjectrelationtype.php b/kernel/classes/datatypes/ezobjectrelation/ezobjectrelationtype.php index 59c07823f4b..87aa1655ad6 100644 --- a/kernel/classes/datatypes/ezobjectrelation/ezobjectrelationtype.php +++ b/kernel/classes/datatypes/ezobjectrelation/ezobjectrelationtype.php @@ -25,6 +25,11 @@ public function __construct() array( 'serialize_supported' => true ) ); } + public function isRelationType() + { + return true; + } + /*! Initializes the class attribute with some data. */ @@ -639,24 +644,17 @@ function metaData( $contentObjectAttribute ) $object = $this->objectAttributeContent( $contentObjectAttribute ); if ( $object ) { - if ( eZContentObject::recursionProtect( $object->attribute( 'id' ) ) ) + // Does the related object exist in the same language as the current content attribute ? + if ( in_array( $contentObjectAttribute->attribute( 'language_code' ), $object->attribute( 'current' )->translationList( false, false ) ) ) { - // Does the related object exist in the same language as the current content attribute ? - if ( in_array( $contentObjectAttribute->attribute( 'language_code' ), $object->attribute( 'current' )->translationList( false, false ) ) ) - { - $attributes = $object->attribute( 'current' )->contentObjectAttributes( $contentObjectAttribute->attribute( 'language_code' ) ); - } - else - { - $attributes = $object->contentObjectAttributes(); - } - - return eZContentObjectAttribute::metaDataArray( $attributes ); + $attributes = $object->attribute( 'current' )->contentObjectAttributes( $contentObjectAttribute->attribute( 'language_code' ) ); } else { - return array(); + $attributes = $object->contentObjectAttributes(); } + + return eZContentObjectAttribute::metaDataArray( $attributes, true ); } return false; } diff --git a/kernel/classes/datatypes/ezobjectrelationlist/ezobjectrelationlisttype.php b/kernel/classes/datatypes/ezobjectrelationlist/ezobjectrelationlisttype.php index dc7cf8d240a..f43a9e11bc2 100644 --- a/kernel/classes/datatypes/ezobjectrelationlist/ezobjectrelationlisttype.php +++ b/kernel/classes/datatypes/ezobjectrelationlist/ezobjectrelationlisttype.php @@ -32,6 +32,11 @@ public function __construct() array( 'serialize_supported' => true ) ); } + public function isRelationType() + { + return true; + } + /*! Validates the input and returns true if the input was valid for this datatype. @@ -1616,17 +1621,14 @@ function metaData( $contentObjectAttribute ) $subObjectVersionNum = $subCurrentVersionObject->attribute( 'version' ); } - if ( eZContentObject::recursionProtect( $subObjectID ) ) + if ( !$subObject ) { - if ( !$subObject ) - { - continue; - } - $attributes = $subObject->contentObjectAttributes( true, $subObjectVersionNum, $language ); + continue; } + $attributes = $subObject->contentObjectAttributes( true, $subObjectVersionNum, $language ); } - $attributeMetaDataArray = eZContentObjectAttribute::metaDataArray( $attributes ); + $attributeMetaDataArray = eZContentObjectAttribute::metaDataArray( $attributes, true ); $metaDataArray = array_merge( $metaDataArray, $attributeMetaDataArray ); } diff --git a/kernel/classes/ezcontentobjectattribute.php b/kernel/classes/ezcontentobjectattribute.php index a226c458acd..8f63c429280 100644 --- a/kernel/classes/ezcontentobjectattribute.php +++ b/kernel/classes/ezcontentobjectattribute.php @@ -1168,7 +1168,7 @@ function fromString( $string ) Goes trough all attributes and fetches metadata for the ones that is searchable. \return an array with metadata information. */ - static function metaDataArray( &$attributes ) + static function metaDataArray( &$attributes, $skipRelationAttributes = false ) { $metaDataArray = array(); if ( !is_array( $attributes ) ) @@ -1176,18 +1176,26 @@ static function metaDataArray( &$attributes ) foreach( $attributes as $attribute ) { $classAttribute = $attribute->contentClassAttribute(); - if ( $classAttribute->attribute( 'is_searchable' ) ) + if ( !$classAttribute->attribute( 'is_searchable' ) ) { - $attributeMetaData = $attribute->metaData(); - if ( $attributeMetaData !== false ) + continue; + } + + $datatype = $attribute->dataType(); + if ( $skipRelationAttributes && $datatype->isRelationType() ) + { + continue; + } + + $attributeMetaData = $datatype->metaData($attribute); + if ( $attributeMetaData !== false ) + { + if ( !is_array( $attributeMetaData ) ) { - if ( !is_array( $attributeMetaData ) ) - { - $attributeMetaData = array( array( 'id' => '', - 'text' => $attributeMetaData ) ); - } - $metaDataArray = array_merge( $metaDataArray, $attributeMetaData ); + $attributeMetaData = array( array( 'id' => '', + 'text' => $attributeMetaData ) ); } + $metaDataArray = array_merge( $metaDataArray, $attributeMetaData ); } } return $metaDataArray; diff --git a/kernel/classes/ezdatatype.php b/kernel/classes/ezdatatype.php index b0d10bcba2a..c21d54de77b 100644 --- a/kernel/classes/ezdatatype.php +++ b/kernel/classes/ezdatatype.php @@ -288,6 +288,16 @@ function isSimpleStringInsertionSupported() return false; } + /** + * Indicates if the datatype handles relations + * + * @return bool + */ + public function isRelationType() + { + return false; + } + /*! \virtual Inserts the HTTP file \a $httpFile to the content object attribute \a $objectAttribute.