diff --git a/README.md b/README.md index fe19ac2..779b056 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,16 @@ -mugoobjectrelations -=================== +# mugoobjectrelations -The Mugo Object Relations extension is meant to allow using cross reference metadata on your ezpublish object relations. \ No newline at end of file +The Mugo Object Relations extension is meant to allow using +cross reference metadata on your ezpublish object relations. + +## Installation +Works as provided: +1. Extract the contents under the extension/ directory of your + eZ Publish installation and activate it for all siteaccesses. +2. Regenerate the autoloads array and clear the cache + +## TODO +- Add a "searchable" flag to the extra fields (both relation-level and attribute-level) +- javascript in dedicated file +- re-use parent PHP code in MugoObjectRelationListType +- replace any template 'section' operations to 'if/foreach' diff --git a/classes/mugosolrdocumentfieldobjectrelation.php b/classes/mugosolrdocumentfieldobjectrelation.php index 38e0570..665bbd9 100644 --- a/classes/mugosolrdocumentfieldobjectrelation.php +++ b/classes/mugosolrdocumentfieldobjectrelation.php @@ -85,4 +85,3 @@ public function getData() } } -?> diff --git a/datatypes/mugoobjectrelationlist/mugoobjectrelationlisttype.php b/datatypes/mugoobjectrelationlist/mugoobjectrelationlisttype.php index f1a0001..8da1f9f 100755 --- a/datatypes/mugoobjectrelationlist/mugoobjectrelationlisttype.php +++ b/datatypes/mugoobjectrelationlist/mugoobjectrelationlisttype.php @@ -8,7 +8,7 @@ \brief A content datatype which handles object relations with the addition of cross-reference data on the object relation itself */ -class MugoObjectRelationListType extends eZDataType +class MugoObjectRelationListType extends eZObjectRelationListType { const DATA_TYPE_STRING = "mugoobjectrelationlist"; const FIELDSEPARATOR = "|"; @@ -16,12 +16,12 @@ class MugoObjectRelationListType extends eZDataType const RELATIONSEPARATOR = "&"; const EXTRAFIELDSSEPARATOR = "-"; - /*! - Initializes with a string id and a description. - */ - function MugoObjectRelationListType() + /** + * MugoObjectRelationListType constructor. + * Initializes with a string id and a description. + */ + function __construct() { - //eZDebug::writeDebug('MugoObjectRelationListType'); $this->eZDataType( self::DATA_TYPE_STRING, "Mugo object relations", array( 'serialize_supported' => true, 'object_serialize_map' => array( 'data_text' => 'text' ) ) ); @@ -130,40 +130,12 @@ function validateObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute return $status; } - /*! - Validates the input and returns true if the input was - valid for this datatype. - */ - function fixupObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute ) - { - //eZDebug::writeDebug('fixupObjectAttributeHTTPInput'); - $content = $contentObjectAttribute->content(); - for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) - { - $relationItem = $content['relation_list'][$i]; - if ( $relationItem['is_modified'] ) - { - $subObjectID = $relationItem['contentobject_id']; - $attributeBase = $base . '_ezorl_edit_object_' . $subObjectID; - $object = $content['temp'][$subObjectID]['object']; - $requireFixup = $content['temp'][$subObjectID]['require-fixup']; - if ( $object and - $requireFixup ) - { - $attributes = $content['temp'][$subObjectID]['attributes']; - $object->fixupInput( $attributes, $attributeBase ); - } - } - } - } /*! Fetches the http post var string input and stores it in the data instance. */ function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute ) { - //eZDebug::writeDebug('fetchObjectAttributeHTTPInput'); - $content = $contentObjectAttribute->content(); // new object creation $newObjectPostVariableName = "attribute_" . $contentObjectAttribute->attribute( "id" ) . "_new_object_name"; @@ -286,322 +258,6 @@ function fetchObjectAttributeHTTPInput( $http, $base, $contentObjectAttribute ) return true; } - function createNewObject( $contentObjectAttribute, $name ) - { - //eZDebug::writeDebug('createNewObject'); - $classAttribute = $contentObjectAttribute->attribute( 'contentclass_attribute' ); - $classContent = $classAttribute->content(); - $classID = $classContent['object_class']; - if ( !isset( $classID ) or !is_numeric( $classID ) ) - return false; - - $defaultPlacementNode = ( is_array( $classContent['default_placement'] ) and isset( $classContent['default_placement']['node_id'] ) ) ? $classContent['default_placement']['node_id'] : false; - if ( !$defaultPlacementNode ) - { - eZDebug::writeError( 'Default placement is missing', 'MugoObjectRelationListType::createNewObject' ); - return false; - } - - $node = eZContentObjectTreeNode::fetch( $defaultPlacementNode ); - // Check if current user can create a new node as child of this node. - if ( !$node or !$node->canCreate() ) - { - eZDebug::writeError( 'Default placement is wrong or the current user can\'t create a new node as child of this node.', 'MugoObjectRelationListType::createNewObject' ); - return false; - } - - $classList = $node->canCreateClassList( false ); - $canCreate = false; - // Check if current user can create object of class (with $classID) - foreach ( $classList as $class ) - { - if ( $class['id'] == $classID ) - { - $canCreate = true; - break; - } - } - if ( !$canCreate ) - { - eZDebug::writeError( 'The current user is not allowed to create objects of class (ID=' . $classID . ')', 'MugoObjectRelationListType::createNewObject' ); - return false; - } - - $class = eZContentClass::fetch( $classID ); - if ( !$class ) - return false; - - $currentObject = $contentObjectAttribute->attribute( 'object' ); - $sectionID = $currentObject->attribute( 'section_id' ); - //instantiate object, same section, currentuser as owner (i.e. provide false as param) - $newObjectInstance = $class->instantiate( false, $sectionID ); - $nodeassignment = $newObjectInstance->createNodeAssignment( $defaultPlacementNode, true ); - $nodeassignment->store(); - $newObjectInstance->sync(); - $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $newObjectInstance->attribute( 'id' ), 'version' => 1 ) ); - // so it updates the attributes - $newObjectInstance->rename( $name ); - - return $newObjectInstance->attribute( 'id' ); - } - - function storeObjectAttribute( $attribute ) - { - //eZDebug::writeDebug('storeObjectAttribute START'); - $content = $attribute->content(); - if ( isset( $content['new_object'] ) ) - { - $newID = $this->createNewObject( $attribute, $content['new_object'] ); - // if this is a single element selection mode (radio or dropdown), then the newly created item is the only one selected - if ( $newID ) - { - if ( isset( $content['singleselect'] ) ) - $content['relation_list'] = array(); - $content['relation_list'][] = $this->appendObject( $newID, 0, $attribute ); - } - unset( $content['new_object'] ); - $attribute->setContent( $content ); - } - - $contentClassAttributeID = $attribute->ContentClassAttributeID; - $contentObjectID = $attribute->ContentObjectID; - $contentObjectVersion = $attribute->Version; - - $obj = $attribute->object(); - //get eZContentObjectVersion - $currVerobj = $obj->version( $contentObjectVersion ); - - // create translation List - // $translationList will contain for example eng-GB, ita-IT etc. - $translationList = $currVerobj->translations( false ); - - // get current language_code - $langCode = $attribute->attribute( 'language_code' ); - // get count of LanguageCode in translationList - $countTsl = count( $translationList ); - // order by asc - sort( $translationList ); - - if ( ( $countTsl == 1 ) or ( $countTsl > 1 and $translationList[0] == $langCode ) ) - { - eZContentObject::fetch( $contentObjectID )->removeContentObjectRelation( false, $contentObjectVersion, $contentClassAttributeID, eZContentObject::RELATION_ATTRIBUTE ); - } - - foreach( $content['relation_list'] as $relationItem ) - { - // Installing content object, postUnserialize is not called yet, - // so object's ID is unknown. - if ( !$relationItem['contentobject_id'] || !isset( $relationItem['contentobject_id'] ) ) - continue; - - $subObjectID = $relationItem['contentobject_id']; - $subObjectVersion = $relationItem['contentobject_version']; - - eZContentObject::fetch( $contentObjectID )->addContentObjectRelation( $subObjectID, $contentObjectVersion, $contentClassAttributeID, eZContentObject::RELATION_ATTRIBUTE ); - - if ( $relationItem['is_modified'] && isset( $content['temp'][$subObjectID]['object' ] ) ) - { - // handling sub-objects - $object = $content['temp'][$subObjectID]['object']; - if ( $object ) - { - $attributes = $content['temp'][$subObjectID]['attributes']; - $attributeInputMap = $content['temp'][$subObjectID]['attribute-input-map']; - $object->storeInput( $attributes, - $attributeInputMap ); - $version = eZContentObjectVersion::fetchVersion( $subObjectVersion, $subObjectID ); - if ( $version ) - { - $version->setAttribute( 'modified', time() ); - $version->setAttribute( 'status', eZContentObjectVersion::STATUS_DRAFT ); - $version->store(); - } - - $object->setAttribute( 'status', eZContentObject::STATUS_DRAFT ); - $object->store(); - } - } - } - //eZDebug::writeDebug('storeObjectAttribute END'); - return MugoObjectRelationListType::storeObjectAttributeContent( $attribute, $content ); - } - - function onPublish( $contentObjectAttribute, $contentObject, $publishedNodes ) - { - //eZDebug::writeDebug('onPublish START'); - $content = $contentObjectAttribute->content(); - foreach( $content['relation_list'] as $key => $relationItem ) - { - if ( $relationItem['is_modified'] ) - { - $subObjectID = $relationItem['contentobject_id']; - $subObjectVersion = $relationItem['contentobject_version']; - $object = eZContentObject::fetch( $subObjectID ); - - if ( $object ) - { - $class = $object->contentClass(); - $time = time(); - - // Make the previous version archived - $currentVersion = $object->currentVersion(); - $currentVersion->setAttribute( 'status', eZContentObjectVersion::STATUS_ARCHIVED ); - $currentVersion->setAttribute( 'modified', $time ); - $currentVersion->store(); - - $version = eZContentObjectVersion::fetchVersion( $subObjectVersion, $subObjectID ); - $version->setAttribute( 'modified', $time ); - $version->setAttribute( 'status', eZContentObjectVersion::STATUS_PUBLISHED ); - $version->store(); - $object->setAttribute( 'status', eZContentObject::STATUS_PUBLISHED ); - if ( !$object->attribute( 'published' ) ) - $object->setAttribute( 'published', $time ); - $object->setAttribute( 'modified', $time ); - $object->setAttribute( 'current_version', $version->attribute( 'version' ) ); - $object->setAttribute( 'is_published', true ); - $objectName = $class->contentObjectName( $object, $version->attribute( 'version' ) ); - $object->setName( $objectName, $version->attribute( 'version' ) ); - $object->store(); - } - if ( $relationItem['parent_node_id'] > 0 ) - { - if ( !eZNodeAssignment::fetch( $object->attribute( 'id' ), $object->attribute( 'current_version' ), $relationItem['parent_node_id'], false ) ) - { - $nodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $object->attribute( 'id' ), - 'contentobject_version' => $object->attribute( 'current_version' ), - 'parent_node' => $relationItem['parent_node_id'], - 'sort_field' => eZContentObjectTreeNode::SORT_FIELD_PUBLISHED, - 'sort_order' => eZContentObjectTreeNode::SORT_ORDER_DESC, - 'is_main' => 1 ) ); - $nodeAssignment->store(); - } - $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id' => $object->attribute( 'id' ), - 'version' => $object->attribute( 'current_version' ) ) ); - $objectNodeID = $object->attribute( 'main_node_id' ); - $content['relation_list'][$key]['node_id'] = $objectNodeID; - } - else - { - if ( !eZNodeAssignment::fetch( $object->attribute( 'id' ), $object->attribute( 'current_version' ), $contentObject->attribute( 'main_node_id' ), false ) ) - { - $nodeAssignment = eZNodeAssignment::create( array( 'contentobject_id' => $object->attribute( 'id' ), - 'contentobject_version' => $object->attribute( 'current_version' ), - 'parent_node' => $contentObject->attribute( 'main_node_id' ), - 'sort_field' => eZContentObjectTreeNode::SORT_FIELD_PUBLISHED, - 'sort_order' => eZContentObjectTreeNode::SORT_ORDER_DESC, - 'is_main' => 1 ) ); - $nodeAssignment->store(); - } - } - $content['relation_list'][$key]['is_modified'] = false; - } - } - MugoObjectRelationListType::storeObjectAttributeContent( $contentObjectAttribute, $content ); - $contentObjectAttribute->setContent( $content ); - $contentObjectAttribute->store(); - //eZDebug::writeDebug('onPublish END'); - } - - function initializeObjectAttribute( $contentObjectAttribute, $currentVersion, $originalContentObjectAttribute ) - { - //eZDebug::writeDebug('initializeObjectAttribute'); - static $copiedRelatedAccordance; - if ( !isset( $copiedRelatedAccordance ) ) - $copiedRelatedAccordance = array(); - - if ( $currentVersion != false ) - { - $dataText = $originalContentObjectAttribute->attribute( 'data_text' ); - $contentObjectAttribute->setAttribute( 'data_text', $dataText ); - $contentObjectID = $contentObjectAttribute->attribute( 'contentobject_id' ); - $originalContentObjectID = $originalContentObjectAttribute->attribute( 'contentobject_id' ); - - if ( $contentObjectID != $originalContentObjectID ) - { - $classContent = MugoObjectRelationListType::defaultClassAttributeContent(); - if ( !$classContent['default_placement'] ) - { - $content = $originalContentObjectAttribute->content(); - $contentModified = false; - - foreach ( $content['relation_list'] as $key => $relationItem ) - { - // create related object copies only if they are subobjects - $object = eZContentObject::fetch( $relationItem['contentobject_id'] ); - if ( !$object instanceof eZContentObject ) - { - unset( $content['relation_list'][$key] ); - $contentModified = true; - continue; - } - - $mainNode = $object->attribute( 'main_node' ); - if ( $mainNode instanceof eZContentObjectTreeNode ) - { - $node = ( is_numeric( $relationItem['node_id'] ) and $relationItem['node_id'] ) ? - eZContentObjectTreeNode::fetch( $relationItem['node_id'] ) : null; - - if ( !$node or $node->attribute( 'contentobject_id' ) != $relationItem['contentobject_id'] ) - { - $content['relation_list'][$key]['node_id'] = $mainNode->attribute( 'node_id' ); - $node = $mainNode; - $contentModified = true; - } - - if ( $node instanceof eZContentObjectTreeNode ) - $parentNodeID = $node->attribute( 'parent_node_id' ); - else - $parentNodeID = -1; - - if ( $relationItem['parent_node_id'] != $parentNodeID ) - { - $content['relation_list'][$key]['parent_node_id'] = $parentNodeID; - $contentModified = true; - } - } - else - { - if ( !isset( $copiedRelatedAccordance[ $relationItem['contentobject_id'] ] ) ) - $copiedRelatedAccordance[ $relationItem['contentobject_id'] ] = array(); - - if ( isset( $copiedRelatedAccordance[ $relationItem['contentobject_id'] ] ) and - isset( $copiedRelatedAccordance[ $relationItem['contentobject_id'] ][ $contentObjectID ] ) ) - { - $newObjectID = $copiedRelatedAccordance[ $relationItem['contentobject_id'] ][ $contentObjectID ][ 'to' ]; - } - else - { - $newObject = $object->copy( true ); - $newObjectID = $newObject->attribute( 'id' ); - $copiedRelatedAccordance[ $relationItem['contentobject_id'] ][ $contentObjectID ] = array( 'to' => $newObjectID, - 'from' => $originalContentObjectID ); - } - $content['relation_list'][$key]['contentobject_id'] = $newObjectID; - $contentModified = true; - } - } - - if ( $contentModified ) - { - $contentObjectAttribute->setContent( $content ); - $contentObjectAttribute->store(); - } - } - } - } - } - - function validateClassAttributeHTTPInput( $http, $base, $classAttribute ) - { - //eZDebug::writeDebug('validateClassAttributeHTTPInput'); - return eZInputValidator::STATE_ACCEPTED; - } - - function fixupClassAttributeHTTPInput( $http, $base, $classAttribute ) - { - //eZDebug::writeDebug('fixupClassAttributeHTTPInput'); - } - function fetchClassAttributeHTTPInput( $http, $base, $classAttribute ) { //eZDebug::writeDebug('fetchClassAttributeHTTPInput: Read http variables '); @@ -742,93 +398,6 @@ function fetchClassAttributeHTTPInput( $http, $base, $classAttribute ) return true; } - function initializeClassAttribute( $classAttribute ) - { - //eZDebug::writeDebug('initializeClassAttribute'); - $xmlText = $classAttribute->attribute( 'data_text5' ); - if ( trim( $xmlText ) == '' ) - { - $content = MugoObjectRelationListType::defaultClassAttributeContent(); - return MugoObjectRelationListType::storeClassAttributeContent( $classAttribute, $content ); - } - } - - function preStoreClassAttribute( $classAttribute, $version ) - { - //eZDebug::writeDebug('preStoreClassAttribute'); - $content = $classAttribute->content(); - return MugoObjectRelationListType::storeClassAttributeContent( $classAttribute, $content ); - } - - function storeClassAttributeContent( $classAttribute, $content ) - { - //eZDebug::writeDebug('storeClassAttributeContent'); - if ( is_array( $content ) ) - { - $doc = MugoObjectRelationListType::createClassDOMDocument( $content ); - MugoObjectRelationListType::storeClassDOMDocument( $doc, $classAttribute ); - return true; - } - return false; - } - - function storeObjectAttributeContent( $objectAttribute, $content ) - { - //eZDebug::writeDebug('storeObjectAttributeContent'); -// //eZDebug::writeDebug(var_export($content, true)); -// //eZDebug::writeDebug(var_export($objectAttribute, true)); - if ( is_array( $content ) ) - { - $doc = MugoObjectRelationListType::createObjectDOMDocument( $content ); - MugoObjectRelationListType::storeObjectDOMDocument( $doc, $objectAttribute ); - return true; - } - return false; - } - - static function storeClassDOMDocument( $doc, $classAttribute ) - { - //eZDebug::writeDebug('storeClassDOMDocument'); - $docText = MugoObjectRelationListType::domString( $doc ); - $classAttribute->setAttribute( 'data_text5', $docText ); - } - - static function storeObjectDOMDocument( $doc, $objectAttribute ) - { - //eZDebug::writeDebug('storeObjectDOMDocument START'); - $docText = MugoObjectRelationListType::domString( $doc ); - $objectAttribute->setAttribute( 'data_text', $docText ); - //eZDebug::writeDebug('storeObjectDOMDocument END'); - } - - /*! - \static - \return the XML structure in \a $domDocument as text. - It will take of care of the necessary charset conversions - for content storage. - */ - static function domString( $domDocument ) - { - //eZDebug::writeDebug('domString START'); - $ini = eZINI::instance(); - $xmlCharset = $ini->variable( 'RegionalSettings', 'ContentXMLCharset' ); - if ( $xmlCharset == 'enabled' ) - { - $charset = eZTextCodec::internalCharset(); - } - else if ( $xmlCharset == 'disabled' ) - $charset = true; - else - $charset = $xmlCharset; - if ( $charset !== true ) - { - $charset = eZCharsetInfo::realCharsetCode( $charset ); - } - $domString = $domDocument->saveXML(); - //eZDebug::writeDebug('domString END'); - return $domString; - } - static function createClassDOMDocument( $content ) { //eZDebug::writeDebug('createClassDOMDocument: Store the array as XML START'); @@ -1044,382 +613,6 @@ static function contentObjectArrayXMLMap() ); } - function deleteStoredObjectAttribute( $objectAttribute, $version = null ) - { - //eZDebug::writeDebug('deleteStoredObjectAttribute'); - $content = $objectAttribute->content(); - if ( is_array( $content ) and - is_array( $content['relation_list'] ) ) - { - $db = eZDB::instance(); - $db->begin(); - foreach ( $content['relation_list'] as $deletionItem ) - { - MugoObjectRelationListType::removeRelationObject( $objectAttribute, $deletionItem ); - } - $db->commit(); - } - } - - function customObjectAttributeHTTPAction( $http, $action, $contentObjectAttribute, $parameters ) - { - //eZDebug::writeDebug('customObjectAttributeHTTPAction'); - $contentobjectID = false; - if ( eZDataType::fetchActionValue( $action, 'new_class', $classID ) or - $action == 'new_class' ) - { - if ( $action == 'new_class' ) - { - $base = $parameters['base_name']; - $classVariableName = $base . '_new_class'; - if ( $http->hasPostVariable( $classVariableName ) ) - { - $classVariable = $http->postVariable( $classVariableName ); - $classID = $classVariable[$contentObjectAttribute->attribute( 'id' )]; - $class = eZContentClass::fetch( $classID ); - } - else - return false; - } - else - $class = eZContentClass::fetch( $classID ); - if ( $class ) - { - $classAttribute = $contentObjectAttribute->attribute( 'contentclass_attribute' ); - $class_content = $classAttribute->content(); - $content = $contentObjectAttribute->content(); - $priority = 0; - for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) - { - if ( $content['relation_list'][$i]['priority'] > $priority ) - $priority = $content['relation_list'][$i]['priority']; - } - - $base = $parameters['base_name']; - $nodePlacement = false; - $nodePlacementName = $base . '_object_initial_node_placement'; - if ( $http->hasPostVariable( $nodePlacementName ) ) - { - $nodePlacementMap = $http->postVariable( $nodePlacementName ); - if ( isset( $nodePlacementMap[$contentObjectAttribute->attribute( 'id' )] ) ) - $nodePlacement = $nodePlacementMap[$contentObjectAttribute->attribute( 'id' )]; - } - $relationItem = MugoObjectRelationListType::createInstance( $class, - $priority + 1, - $contentObjectAttribute, - $nodePlacement ); - if ( $class_content['default_placement'] ) - { - $relationItem['parent_node_id'] = $class_content['default_placement']['node_id']; - } - - $content['relation_list'][] = $relationItem; - - $hasAttributeInput = false; - $attributeInputVariable = $base . '_has_attribute_input'; - if ( $http->hasPostVariable( $attributeInputVariable ) ) - { - $attributeInputMap = $http->postVariable( $attributeInputVariable ); - if ( isset( $attributeInputMap[$contentObjectAttribute->attribute( 'id' )] ) ) - $hasAttributeInput = $attributeInputMap[$contentObjectAttribute->attribute( 'id' )]; - } - - if ( $hasAttributeInput ) - { - $object = $relationItem['object']; - $attributes = $object->contentObjectAttributes(); - foreach ( $attributes as $attribute ) - { - $attributeBase = $base . '_ezorl_init_class_' . $object->attribute( 'contentclass_id' ) . '_attr_' . $attribute->attribute( 'contentclassattribute_id' ); - $oldAttributeID = $attribute->attribute( 'id' ); - $attribute->setAttribute( 'id', false ); - if ( $attribute->fetchInput( $http, $attributeBase ) ) - { - $attribute->setAttribute( 'id', $oldAttributeID ); - $attribute->store(); - } - } - } - - $contentObjectAttribute->setContent( $content ); - $contentObjectAttribute->store(); - } - else - - eZDebug::writeError( "Unknown class ID $classID, cannot instantiate object", - 'MugoObjectRelationListType::customObjectAttributeHTTPAction' ); - } - else if ( eZDataType::fetchActionValue( $action, 'edit_objects', $contentobjectID ) or - $action == 'edit_objects' or - $action == 'remove_objects' ) - { - $base = $parameters['base_name']; - $selectionBase = $base . '_selection'; - $selections = array(); - $http = eZHTTPTool::instance(); - if ( $http->hasPostVariable( $selectionBase ) ) - { - $selectionMap = $http->postVariable( $selectionBase ); - $selections = $selectionMap[$contentObjectAttribute->attribute( 'id' )]; - } - if ( $contentobjectID !== false ) - $selections[] = $contentobjectID; - if ( $action == 'edit_objects' or - eZDataType::fetchActionValue( $action, 'edit_objects', $contentobjectID ) ) - { - $content = $contentObjectAttribute->content(); - foreach ( $content['relation_list'] as $key => $relationItem ) - { - if ( !$relationItem['is_modified'] and - in_array( $relationItem['contentobject_id'], $selections ) ) - { - $object = eZContentObject::fetch( $relationItem['contentobject_id'] ); - if ( $object->attribute( 'can_edit' ) ) - { - $content['relation_list'][$key]['is_modified'] = true; - $version = $object->createNewVersion(); - $content['relation_list'][$key]['contentobject_version'] = $version->attribute( 'version' ); - } - } - } - $contentObjectAttribute->setContent( $content ); - $contentObjectAttribute->store(); - } - else if ( $action == 'remove_objects' ) - { - $content = $contentObjectAttribute->content(); - $relationList = $content['relation_list']; - $newRelationList = array(); - foreach( $relationList as $relationItem ) - { - if ( in_array( $relationItem['contentobject_id'], $selections ) ) - { - MugoObjectRelationListType::removeRelationObject( $contentObjectAttribute, $relationItem ); - } - else - { - $newRelationList[] = $relationItem; - } - } - $content['relation_list'] = $newRelationList; - $contentObjectAttribute->setContent( $content ); - $contentObjectAttribute->store(); - } - } - else if ( $action == 'browse_objects' ) - { - $module = $parameters['module']; - $redirectionURI = $parameters['current-redirection-uri']; - - $ini = eZINI::instance( 'content.ini' ); - $browseType = 'AddRelatedObjectListToDataType'; - $browseTypeINIVariable = $ini->variable( 'ObjectRelationDataTypeSettings', 'ClassAttributeStartNode' ); - foreach ( $browseTypeINIVariable as $value ) - { - list( $classAttributeID, $type ) = explode( ';',$value ); - if ( is_numeric( $classAttributeID ) and - $classAttributeID == $contentObjectAttribute->attribute( 'contentclassattribute_id' ) and - strlen( $type ) > 0 ) - { - $browseType = $type; - break; - } - } - - // Fetch the list of "allowed" classes . - // A user can select objects of only those allowed classes when browsing. - $classAttribute = $contentObjectAttribute->attribute( 'contentclass_attribute' ); - $classContent = $classAttribute->content(); - if ( isset( $classContent['class_constraint_list'] ) ) - { - $classConstraintList = $classContent['class_constraint_list']; - } - else - { - $classConstraintList = array(); - } - - $browseParameters = array( 'action_name' => 'AddRelatedObject_' . $contentObjectAttribute->attribute( 'id' ), - 'type' => $browseType, - 'browse_custom_action' => array( 'name' => 'CustomActionButton[' . $contentObjectAttribute->attribute( 'id' ) . '_set_object_relation_list]', - 'value' => $contentObjectAttribute->attribute( 'id' ) ), - 'persistent_data' => array( 'HasObjectInput' => 0 ), - 'from_page' => $redirectionURI ); - $base = $parameters['base_name']; - $nodePlacementName = $base . '_browse_for_object_start_node'; - if ( $http->hasPostVariable( $nodePlacementName ) ) - { - $nodePlacement = $http->postVariable( $nodePlacementName ); - if ( isset( $nodePlacement[$contentObjectAttribute->attribute( 'id' )] ) ) - $browseParameters['start_node'] = eZContentBrowse::nodeAliasID( $nodePlacement[$contentObjectAttribute->attribute( 'id' )] ); - } - if ( count($classConstraintList) > 0 ) - $browseParameters['class_array'] = $classConstraintList; - - eZContentBrowse::browse( $browseParameters, - $module ); - } - else if ( $action == 'set_object_relation_list' ) - { - if ( !$http->hasPostVariable( 'BrowseCancelButton' ) ) - { - $selectedObjectIDArray = $http->postVariable( "SelectedObjectIDArray" ); - $content = $contentObjectAttribute->content(); - $priority = 0; - for ( $i = 0; $i < count( $content['relation_list'] ); ++$i ) - { - if ( $content['relation_list'][$i]['priority'] > $priority ) - $priority = $content['relation_list'][$i]['priority']; - } - - foreach ( $selectedObjectIDArray as $objectID ) - { - // Check if the given object ID has a numeric value, if not go to the next object. - if ( !is_numeric( $objectID ) ) - { - eZDebug::writeError( "Related object ID (objectID): '$objectID', is not a numeric value.", - "MugoObjectRelationListType::customObjectAttributeHTTPAction" ); - - continue; - } - - /* Here we check if current object is already in the related objects list. - * If so, we don't add it again. - * FIXME: Stupid linear search. Maybe there's some better way? - */ - $found = false; - foreach ( $content['relation_list'] as $i ) - { - if ( $i['contentobject_id'] == $objectID ) - { - $found = true; - break; - } - } - if ( $found ) - continue; - - ++$priority; - $content['relation_list'][] = $this->appendObject( $objectID, $priority, $contentObjectAttribute ); - $contentObjectAttribute->setContent( $content ); - $contentObjectAttribute->store(); - } - } - } - else - { - eZDebug::writeError( "Unknown custom HTTP action: " . $action, - 'MugoObjectRelationListType' ); - } - } - - function handleCustomObjectHTTPActions( $http, $attributeDataBaseName, - $customActionAttributeArray, $customActionParameters ) - { - //eZDebug::writeDebug('handleCustomObjectHTTPActions'); - $contentObjectAttribute = $customActionParameters['contentobject_attribute']; - $content = $contentObjectAttribute->content(); - foreach( $content['relation_list'] as $relationItem ) - { - if ( $relationItem['is_modified'] ) - { - $subObjectID = $relationItem['contentobject_id']; - $subObjectVersion = $relationItem['contentobject_version']; - - $attributeBase = $attributeDataBaseName . '_ezorl_edit_object_' . $subObjectID; - if ( eZContentObject::recursionProtect( $subObjectID ) ) - { - if ( isset ( $content['temp'] ) ) - $object = $content['temp'][$subObjectID]['object']; - else - $object = eZContentObject::fetch( $subObjectID ); - if ( $object ) - $object->handleAllCustomHTTPActions( $attributeBase, - $customActionAttributeArray, - $customActionParameters, - $subObjectVersion ); - } - } - } - } - - /*! - \static - \return \c true if the relation item \a $relationItem exist in the content tree. - */ - static function isItemPublished( $relationItem ) - { - //eZDebug::writeDebug('isItemPublished'); - return is_numeric( $relationItem['node_id'] ) and $relationItem['node_id'] > 0; - } - - /*! - \private - Removes the relation object \a $deletionItem if the item is owned solely by this - version and is not published in the content tree. - */ - function removeRelationObject( $contentObjectAttribute, $deletionItem ) - { - //eZDebug::writeDebug('removeRelationObject'); - if ( self::isItemPublished( $deletionItem ) ) - { - return; - } - - $hostObject = $contentObjectAttribute->attribute( 'object' ); - $hostObjectVersions = $hostObject->versions(); - $isDeletionAllowed = true; - - // check if the relation item to be deleted is unique in the domain of all host-object versions - foreach ( $hostObjectVersions as $version ) - { - if ( $isDeletionAllowed and - $version->attribute( 'version' ) != $contentObjectAttribute->attribute( 'version' ) ) - { - $relationAttribute = eZPersistentObject::fetchObjectList( eZContentObjectAttribute::definition(), - null, - array( 'version' => $version->attribute( 'version' ), - 'contentobject_id' => $hostObject->attribute( 'id' ), - 'contentclassattribute_id' => $contentObjectAttribute->attribute( 'contentclassattribute_id' ) ) ); - - if ( count( $relationAttribute ) > 0 ) - { - $relationContent = $relationAttribute[0]->content(); - if ( is_array( $relationContent ) and - is_array( $relationContent['relation_list'] ) ) - { - foreach( $relationContent['relation_list'] as $relationItem ) - { - if ( $deletionItem['contentobject_id'] == $relationItem['contentobject_id'] && - $deletionItem['contentobject_version'] == $relationItem['contentobject_version'] ) - { - $isDeletionAllowed = false; - break 2; - } - } - } - } - } - } - - if ( $isDeletionAllowed ) - { - $subObjectVersion = eZContentObjectVersion::fetchVersion( $deletionItem['contentobject_version'], - $deletionItem['contentobject_id'] ); - if ( $subObjectVersion instanceof eZContentObjectVersion ) - { - $subObjectVersion->removeThis(); - } - else - { - eZDebug::writeError( 'Cleanup of subobject-version failed. Could not fetch object from relation list.\n' . - 'Requested subobject id: ' . $deletionItem['contentobject_id'] . '\n' . - 'Requested Subobject version: ' . $deletionItem['contentobject_version'], - 'MugoObjectRelationListType::removeRelationObject' ); - } - } - } - function createInstance( $class, $priority, $contentObjectAttribute, $nodePlacement = false ) { //eZDebug::writeDebug('createInstance'); @@ -1472,7 +665,6 @@ function appendObject( $objectID, $priority, $contentObjectAttribute, $extra_fie return $relationItem; } - function fixRelatedObjectItem ( $contentObjectAttribute, $objectID, $mode ) { //eZDebug::writeDebug('fixRelatedObjectItem'); @@ -1689,26 +881,6 @@ function getContentClassFieldOptionName( $contentObjectAttribute, $fieldIdentifi } } - function classAttributeContent( $classAttribute ) - { - //eZDebug::writeDebug('classAttributeContent'); - $xmlText = $classAttribute->attribute( 'data_text5' ); - if ( trim( $xmlText ) == '' ) - { - return MugoObjectRelationListType::defaultClassAttributeContent(); - } - $doc = MugoObjectRelationListType::parseXML( $xmlText ); - return MugoObjectRelationListType::createClassContentStructure( $doc ); - } - - static function parseXML( $xmlText ) - { - //eZDebug::writeDebug('parseXML'); - $dom = new DOMDocument( '1.0', 'utf-8' ); - $dom->loadXML( $xmlText ); - return $dom; - } - function defaultClassAttributeContent() { //eZDebug::writeDebug('defaultClassAttributeContent'); @@ -1721,12 +893,6 @@ function defaultClassAttributeContent() ); } - function defaultObjectAttributeContent() - { - //eZDebug::writeDebug('defaultObjectAttributeContent START-END'); - return array( 'relation_list' => array() ); - } - /** * takes a DOMDocument from a class definition and parses it into a content array */ @@ -1901,50 +1067,6 @@ function createObjectContentStructure( $doc ) return $content; } - function customClassAttributeHTTPAction( $http, $action, $classAttribute ) - { - //eZDebug::writeDebug('customClassAttributeHTTPAction'); - switch ( $action ) - { - case 'browse_for_placement': - { - $module = $classAttribute->currentModule(); - $customActionName = 'CustomActionButton[' . $classAttribute->attribute( 'id' ) . '_browsed_for_placement]'; - eZContentBrowse::browse( array( 'action_name' => 'SelectObjectRelationListNode', - 'content' => array( 'contentclass_id' => $classAttribute->attribute( 'contentclass_id' ), - 'contentclass_attribute_id' => $classAttribute->attribute( 'id' ), - 'contentclass_version' => $classAttribute->attribute( 'version' ), - 'contentclass_attribute_identifier' => $classAttribute->attribute( 'identifier' ) ), - 'persistent_data' => array( $customActionName => '', - 'ContentClassHasInput' => false ), - 'description_template' => 'design:class/datatype/browse_objectrelationlist_placement.tpl', - 'from_page' => $module->currentRedirectionURI() ), - $module ); - } break; - case 'browsed_for_placement': - { - $nodeSelection = eZContentBrowse::result( 'SelectObjectRelationListNode' ); - if ( $nodeSelection and count( $nodeSelection ) > 0 ) - { - $nodeID = $nodeSelection[0]; - $content = $classAttribute->content(); - $content['default_placement'] = array( 'node_id' => $nodeID ); - $classAttribute->setContent( $content ); - } - } break; - case 'disable_placement': - { - $content = $classAttribute->content(); - $content['default_placement'] = false; - $classAttribute->setContent( $content ); - } break; - default: - { - eZDebug::writeError( "Unknown objectrelationlist action '$action'", 'eZContentObjectRelationListType::customClassAttributeHTTPAction' ); - } break; - } - } - /*! \return string representation of a content object attribute data for simplified export @@ -2125,43 +1247,6 @@ function fromString( $contentObjectAttribute, $string ) return true; } - - - - function hasObjectAttributeContent( $contentObjectAttribute ) - { - //eZDebug::writeDebug('hasObjectAttributeContent'); - $content = $contentObjectAttribute->content(); - return count( $content['relation_list'] ) > 0; - } - - function isIndexable() - { - //eZDebug::writeDebug('isIndexable'); - return true; - } - - /*! - Returns the content of the string for use as a title, - for simplicity this is the name of the first object referenced or false. - */ - function title( $contentObjectAttribute, $name = null ) - { - //eZDebug::writeDebug('title'); - $objectAttributeContent = $this->objectAttributeContent( $contentObjectAttribute ); - - if ( count( $objectAttributeContent['relation_list'] ) > 0 ) - { - $target = $objectAttributeContent['relation_list'][0]; - $targetObject = eZContentObject::fetch( $target['contentobject_id'], false ); - return $targetObject['name']; - } - else - { - return false; - } - } - function serializeContentClassAttribute( $classAttribute, $attributeNode, $attributeParametersNode ) { //eZDebug::writeDebug("serializeContentClassAttribute"); @@ -2243,170 +1328,8 @@ function unserializeContentClassAttribute( $classAttribute, $attributeNode, $att $this->storeClassAttributeContent( $classAttribute, $content ); } - /*! - For each relation export its priority and content object remote_id, like this: - - - - - - To do this we fetch content XML and strip all the relation attributes except of "priority" from there, - and add "contentobject-remote-id" attribute. - */ - function serializeContentObjectAttribute( $package, $objectAttribute ) - { - //eZDebug::writeDebug('serializeContentObjectAttribute'); - - $node = $this->createContentObjectAttributeDOMNode( $objectAttribute ); - - //eZDebug::writeDebug( $objectAttribute->attribute( 'data_text' ), 'xml string from data_text field' ); - if ( $objectAttribute->attribute( 'data_text' ) === null ) - { - $content = array( 'relation_list' => array() ); - $dom = MugoObjectRelationListType::createObjectDOMDocument( $content ); - } - else - { - $dom = new DOMDocument( '1.0', 'utf-8' ); - $success = $dom->loadXML( $objectAttribute->attribute( 'data_text' ) ); - } - $rootNode = $dom->documentElement; - $relationList = $rootNode->getElementsByTagName( 'relation-list' )->item( 0 ); - if ( $relationList ) - { - $relationItems = $relationList->getElementsByTagName( 'relation-item' ); - for ( $i = 0; $i < $relationItems->length; $i++ ) - { - $relationItem = $relationItems->item( $i ); - // Add related object remote id as attribute to the relation item. - $relatedObjectID = $relationItem->getAttribute( 'contentobject-id' ); - $relatedObject = eZContentObject::fetch( $relatedObjectID ); - $relatedObjectRemoteID = $relatedObject->attribute( 'remote_id' ); - $relationItem->setAttribute( 'contentobject-remote-id', $relatedObjectRemoteID ); - - $attributes = $relationItem->attributes; - // Remove all other relation item attributes except of "priority". - // This loop intentionally starts with the last attribute, otherwise you will get unexpected results - for ( $j = $attributes->length - 1; $j >= 0; $j-- ) - { - $attribute = $attributes->item( $j ); - $attrName = $attribute->localName; - - //eZDebug::writeDebug( $attrName ); - if ( $attrName != 'priority' && $attrName != 'contentobject-remote-id' ) - { - $success = $relationItem->removeAttribute( $attribute->localName ); - if ( !$success ) - { - eZDebug::writeError( 'failed removing attribute ' . $attrName . ' from relation-item element' ); - } - } - } - } - } - - //eZDebug::writeDebug( $dom->saveXML(), 'old xml doc' ); - - $importedRootNode = $node->ownerDocument->importNode( $rootNode, true ); - $node->appendChild( $importedRootNode ); - - return $node; - } - - function unserializeContentObjectAttribute( $package, $objectAttribute, $attributeNode ) - { - //eZDebug::writeDebug('unserializeContentObjectAttribute'); - $rootNode = $attributeNode->getElementsByTagName( 'related-objects' )->item( 0 ); - $xmlString = $rootNode ? $rootNode->ownerDocument->saveXML( $rootNode ) : ''; - $objectAttribute->setAttribute( 'data_text', $xmlString ); - } - - function postUnserializeContentObjectAttribute( $package, $objectAttribute ) - { - //eZDebug::writeDebug('postUnserializeContentObjectAttribute'); - - $xmlString = $objectAttribute->attribute( 'data_text' ); - $doc = $this->parseXML( $xmlString ); - $rootNode = $doc->documentElement; - - $relationList = $rootNode->getElementsByTagName( 'relation-list' )->item( 0 ); - if ( !$relationList ) - return false; - - $relationItems = $relationList->getElementsByTagName( 'relation-item' ); - for ( $i = $relationItems->length - 1; $i >= 0; $i-- ) - { - $relationItem = $relationItems->item( $i ); - $relatedObjectRemoteID = $relationItem->getAttribute( 'contentobject-remote-id' ); - $object = eZContentObject::fetchByRemoteID( $relatedObjectRemoteID ); - - if ( $object === null ) - { - eZDebug::writeWarning( "Object with remote id '$relatedObjectRemoteID' not found: removing the link.", - 'MugoObjectRelationListType::unserializeContentObjectAttribute()' ); - $relationItem->parentNode->removeChild( $relationItem ); - continue; - } - - $relationItem->setAttribute( 'contentobject-id', $object->attribute( 'id' ) ); - $relationItem->setAttribute( 'contentobject-version', $object->attribute( 'current_version' ) ); - $relationItem->setAttribute( 'node-id', $object->attribute( 'main_node_id' ) ); - $relationItem->setAttribute( 'parent-node-id', $object->attribute( 'main_parent_node_id' ) ); - $relationItem->setAttribute( 'contentclass-id', $object->attribute( 'contentclass_id' ) ); - $relationItem->setAttribute( 'contentclass-identifier', $object->attribute( 'class_identifier' ) ); - } - - $newXmlString = $doc->saveXML( $rootNode ); - - $objectAttribute->setAttribute( 'data_text', $newXmlString ); - return true; - } - - /*! - Removes objects with given ID from the relations list - */ - function removeRelatedObjectItem( $contentObjectAttribute, $objectID ) - { - //eZDebug::writeDebug('removeRelatedObjectItem'); - - $xmlText = $contentObjectAttribute->attribute( 'data_text' ); - if ( trim( $xmlText ) == '' ) return; - - $doc = MugoObjectRelationListType::parseXML( $xmlText ); - - $return = false; - $root = $doc->documentElement; - $relationList = $root->getElementsByTagName( 'relation-list' )->item( 0 ); - if ( $relationList ) - { - $relationItems = $relationList->getElementsByTagName( 'relation-item' ); - if ( !empty( $relationItems ) ) - { - foreach( $relationItems as $relationItem ) - { - if ( $relationItem->getAttribute( 'contentobject-id' ) == $objectID ) - { - $relationList->removeChild( $relationItem ); - $return = true; - } - } - } - } - MugoObjectRelationListType::storeObjectDOMDocument( $doc, $contentObjectAttribute ); - return $return; - } - - function supportsBatchInitializeObjectAttribute() - { - //eZDebug::writeDebug('supportsBatchInitializeObjectAttribute'); - return true; - } - /// \privatesection } eZDataType::register( MugoObjectRelationListType::DATA_TYPE_STRING, "MugoObjectRelationListType" ); -?> diff --git a/doc/README b/doc/README deleted file mode 100755 index aa18126..0000000 --- a/doc/README +++ /dev/null @@ -1,13 +0,0 @@ -################################# -Mugo Object Relations version 1.0 -################################# - -1) Description - The Mugo Object Relations extension is meant to allow using -"Cross reference data" on object relations. - -2) Installation - Works as provided: - 1) Extract the contents under the extension/ directory of your - eZ Publish installation and activate it for all siteaccesses. - 2) Regenerate the autoloads array \ No newline at end of file diff --git a/doc/TODO b/doc/TODO deleted file mode 100755 index d26fdd1..0000000 --- a/doc/TODO +++ /dev/null @@ -1 +0,0 @@ -- Add a "searchable" flag to the extra fields (both relation-level and attribute-level) \ No newline at end of file diff --git a/ezinfo.php b/ezinfo.php index e56d166..a721526 100755 --- a/ezinfo.php +++ b/ezinfo.php @@ -10,4 +10,3 @@ static function info() ); } } -?> \ No newline at end of file diff --git a/settings/content.ini.append.php b/settings/content.ini.append.php index 3fd40ca..6b7ed26 100755 --- a/settings/content.ini.append.php +++ b/settings/content.ini.append.php @@ -5,4 +5,4 @@ AvailableDataTypes[]=mugoobjectrelationlist -*/ ?> \ No newline at end of file +*/ \ No newline at end of file diff --git a/settings/design.ini.append.php b/settings/design.ini.append.php index 548ddf7..82800bb 100755 --- a/settings/design.ini.append.php +++ b/settings/design.ini.append.php @@ -2,4 +2,4 @@ [ExtensionSettings] DesignExtensions[]=mugoobjectrelations -*/ ?> \ No newline at end of file +*/ \ No newline at end of file diff --git a/settings/ezfind.ini.append.php b/settings/ezfind.ini.append.php index ff666fa..92454f2 100644 --- a/settings/ezfind.ini.append.php +++ b/settings/ezfind.ini.append.php @@ -3,4 +3,4 @@ [SolrFieldMapSettings] CustomMap[mugoobjectrelationlist]=mugoSolrDocumentFieldObjectRelation -/* ?> \ No newline at end of file +*/ \ No newline at end of file