Created
August 7, 2015 08:39
-
-
Save emodric/46c0fe8b17a081539e23 to your computer and use it in GitHub Desktop.
eZ Publish RelationList field type with location ID support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
parameters: | |
ezpublish.fieldType.ezobjectrelationlist.class: Netgen\Bundle\HelperBundle\Core\FieldType\RelationList\Type | |
ezpublish.fieldType.ezobjectrelationlist.converter.class: Netgen\Bundle\HelperBundle\Core\Persistence\Legacy\Content\FieldValue\Converter\RelationList |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Netgen\Bundle\HelperBundle\Core\Persistence\Legacy\Content\FieldValue\Converter; | |
use eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\Converter\RelationList as BaseRelationListConverter; | |
use eZ\Publish\SPI\Persistence\Content\Type\FieldDefinition; | |
use eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldDefinition; | |
use eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldValue; | |
use eZ\Publish\SPI\Persistence\Content\FieldValue; | |
use DOMDocument; | |
class RelationList extends BaseRelationListConverter | |
{ | |
/** | |
* @var \eZ\Publish\Core\Persistence\Database\DatabaseHandler | |
*/ | |
protected $db; | |
/** | |
* Converts data from $value to $storageFieldValue | |
* | |
* @param \eZ\Publish\SPI\Persistence\Content\FieldValue $value | |
* @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldValue $storageFieldValue | |
*/ | |
public function toStorageValue( FieldValue $value, StorageFieldValue $storageFieldValue ) | |
{ | |
$doc = new DOMDocument( '1.0', 'utf-8' ); | |
$root = $doc->createElement( 'related-objects' ); | |
$doc->appendChild( $root ); | |
$relationList = $doc->createElement( 'relation-list' ); | |
$data = $this->getRelationXmlHashFromDB( $value->data['destinationContentIds'] ); | |
$priority = 0; | |
foreach ( $value->data['destinationContentIds'] as $key => $id ) | |
{ | |
$row = $data[$id][0]; | |
$row["ezcontentobject_id"] = $id; | |
if ( !empty( $value->data['destinationLocationIds'][$key] ) ) | |
{ | |
$row["ezcontentobject_tree_node_id"] = $value->data['destinationLocationIds'][$key]; | |
} | |
$row["priority"] = ( $priority += 1 ); | |
$relationItem = $doc->createElement( 'relation-item' ); | |
foreach ( self::dbAttributeMap() as $domAttrKey => $propertyKey ) | |
{ | |
if ( !isset( $row[$propertyKey] ) ) | |
throw new \RuntimeException( "Missing relation-item external data property: $propertyKey" ); | |
$relationItem->setAttribute( $domAttrKey, $row[$propertyKey] ); | |
} | |
$relationList->appendChild( $relationItem ); | |
unset( $relationItem ); | |
} | |
$root->appendChild( $relationList ); | |
$doc->appendChild( $root ); | |
$storageFieldValue->dataText = $doc->saveXML(); | |
} | |
/** | |
* Converts data from $value to $fieldValue | |
* | |
* @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldValue $value | |
* @param \eZ\Publish\SPI\Persistence\Content\FieldValue $fieldValue | |
*/ | |
public function toFieldValue( StorageFieldValue $value, FieldValue $fieldValue ) | |
{ | |
$fieldValue->data = array( | |
'destinationContentIds' => array(), | |
'destinationLocationIds' => array() | |
); | |
if ( $value->dataText === null ) | |
return; | |
$priorityByContentId = array(); | |
$priorityByLocationId = array(); | |
$dom = new DOMDocument( '1.0', 'utf-8' ); | |
if ( $dom->loadXML( $value->dataText ) === true ) | |
{ | |
foreach ( $dom->getElementsByTagName( 'relation-item' ) as $relationItem ) | |
{ | |
/** @var \DOMElement $relationItem */ | |
$priorityByContentId[$relationItem->getAttribute( 'contentobject-id' )] = | |
$relationItem->getAttribute( 'priority' ); | |
$priorityByLocationId[$relationItem->getAttribute( 'node-id' )] = | |
$relationItem->getAttribute( 'priority' ); | |
} | |
} | |
asort( $priorityByContentId, SORT_NUMERIC ); | |
asort( $priorityByLocationId, SORT_NUMERIC ); | |
$fieldValue->data['destinationContentIds'] = array_keys( $priorityByContentId ); | |
$fieldValue->data['destinationLocationIds'] = array_keys( $priorityByLocationId ); | |
} | |
/** | |
* Converts field definition data in $storageDef into $fieldDef | |
* | |
* <?xml version="1.0" encoding="utf-8"?> | |
* <related-objects> | |
* <constraints> | |
* <allowed-class contentclass-identifier="blog_post"/> | |
* </constraints> | |
* <type value="2"/> | |
* <selection_type value="1"/> | |
* <object_class value=""/> | |
* <contentobject-placement node-id="67"/> | |
* </related-objects> | |
* | |
* <?xml version="1.0" encoding="utf-8"?> | |
* <related-objects> | |
* <constraints/> | |
* <type value="2"/> | |
* <selection_type value="0"/> | |
* <object_class value=""/> | |
* <contentobject-placement/> | |
* </related-objects> | |
* | |
* @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldDefinition $storageDef | |
* @param \eZ\Publish\SPI\Persistence\Content\Type\FieldDefinition $fieldDef | |
*/ | |
public function toFieldDefinition( StorageFieldDefinition $storageDef, FieldDefinition $fieldDef ) | |
{ | |
parent::toFieldDefinition( $storageDef, $fieldDef ); | |
$fieldDef->defaultValue->data['destinationLocationIds'] = array(); | |
} | |
/** | |
* @return array | |
*/ | |
static private function dbAttributeMap() | |
{ | |
return array( | |
// 'identifier' => 'identifier',// not used | |
'priority' => 'priority', | |
// 'in-trash' => 'in_trash',// false by default and implies | |
'contentobject-id' => 'ezcontentobject_id', | |
'contentobject-version' => 'ezcontentobject_current_version', | |
'node-id' => 'ezcontentobject_tree_node_id', | |
'parent-node-id' => 'ezcontentobject_tree_parent_node_id', | |
'contentclass-id' => 'ezcontentobject_contentclass_id', | |
'contentclass-identifier' => 'ezcontentclass_identifier', | |
// 'is-modified' => 'is_modified',// deprecated and not used | |
'contentobject-remote-id' => 'ezcontentobject_remote_id' | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Netgen\Bundle\HelperBundle\Core\FieldType\RelationList; | |
use eZ\Publish\Core\FieldType\RelationList\Type as BaseRelationListType; | |
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentType; | |
use eZ\Publish\SPI\FieldType\Value as SPIValue; | |
use eZ\Publish\Core\FieldType\Value as BaseValue; | |
class Type extends BaseRelationListType | |
{ | |
/** | |
* Returns the fallback default value of field type when no such default | |
* value is provided in the field definition in content types. | |
* | |
* @return \Netgen\Bundle\HelperBundle\Core\FieldType\RelationList\Value | |
*/ | |
public function getEmptyValue() | |
{ | |
return new Value(); | |
} | |
/** | |
* Inspects given $inputValue and potentially converts it into a dedicated value object. | |
* | |
* @param int|string|array|\eZ\Publish\API\Repository\Values\Content\ContentInfo|\eZ\Publish\Core\FieldType\RelationList\Value $inputValue | |
* | |
* @return \Netgen\Bundle\HelperBundle\Core\FieldType\RelationList\Value The potentially converted and structurally plausible value. | |
*/ | |
protected function createValueFromInput( $inputValue ) | |
{ | |
if ( is_array( $inputValue ) && isset( $inputValue['relation_list'] ) ) | |
{ | |
$relationList = $inputValue['relation_list']; | |
if ( !is_array( $relationList ) ) | |
{ | |
return $inputValue; | |
} | |
$destinationContentIds = array(); | |
$destinationLocationIds = array(); | |
foreach ( $relationList as $relationListItem ) | |
{ | |
if ( !isset( $relationListItem['content_id'] ) || !isset( $relationListItem['location_id'] ) ) | |
{ | |
return $inputValue; | |
} | |
if ( is_integer( $relationListItem['content_id'] ) || is_string( $relationListItem['content_id'] ) ) | |
{ | |
return $inputValue; | |
} | |
if ( is_integer( $relationListItem['location_id'] ) || is_string( $relationListItem['location_id'] ) ) | |
{ | |
return $inputValue; | |
} | |
$destinationContentIds[] = $relationListItem['content_id']; | |
$destinationLocationIds[] = $relationListItem['location_id']; | |
} | |
return new Value( $destinationContentIds, $destinationLocationIds ); | |
} | |
return parent::createValueFromInput( $inputValue ); | |
} | |
/** | |
* Throws an exception if value structure is not of expected format. | |
* | |
* @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException If the value does not match the expected structure. | |
* | |
* @param \Netgen\Bundle\HelperBundle\Core\FieldType\RelationList\Value $value | |
*/ | |
protected function checkValueStructure( BaseValue $value ) | |
{ | |
parent::checkValueStructure( $value ); | |
if ( !is_array( $value->destinationLocationIds ) ) | |
{ | |
throw new InvalidArgumentType( | |
"\$value->destinationLocationIds", | |
'array', | |
$value->destinationLocationIds | |
); | |
} | |
foreach ( $value->destinationLocationIds as $key => $destinationLocationId ) | |
{ | |
if ( !is_integer( $destinationLocationId ) && !is_string( $destinationLocationId ) ) | |
{ | |
throw new InvalidArgumentType( | |
"\$value->destinationLocationIds[$key]", | |
'string|int', | |
$destinationLocationId | |
); | |
} | |
} | |
} | |
/** | |
* Converts an $hash to the Value defined by the field type | |
* | |
* @param mixed $hash | |
* | |
* @return \Netgen\Bundle\HelperBundle\Core\FieldType\RelationList\Value $value | |
*/ | |
public function fromHash( $hash ) | |
{ | |
return new Value( $hash['destinationContentIds'], $hash['destinationLocationIds'] ); | |
} | |
/** | |
* Converts a $Value to a hash | |
* | |
* @param \Netgen\Bundle\HelperBundle\Core\FieldType\RelationList\Value $value | |
* | |
* @return mixed | |
*/ | |
public function toHash( SPIValue $value ) | |
{ | |
return array( | |
'destinationContentIds' => $value->destinationContentIds, | |
'destinationLocationIds' => $value->destinationLocationIds | |
); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Netgen\Bundle\HelperBundle\Core\FieldType\RelationList; | |
use eZ\Publish\Core\FieldType\RelationList\Value as BaseRelationListValue; | |
/** | |
* Value for RelationList field type | |
*/ | |
class Value extends BaseRelationListValue | |
{ | |
/** | |
* Related location IDs | |
* | |
* @var mixed[] | |
*/ | |
public $destinationLocationIds; | |
/** | |
* Construct a new Value object and initialize it $text | |
* | |
* @param mixed[] $destinationContentIds | |
* @param mixed[] $destinationLocationIds | |
*/ | |
public function __construct( array $destinationContentIds = array(), array $destinationLocationIds = array() ) | |
{ | |
parent::__construct( $destinationContentIds ); | |
$this->destinationLocationIds = $destinationLocationIds; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment