Skip to content

Commit

Permalink
EZP-24800 Support allowed classes limitation for object relation fiel…
Browse files Browse the repository at this point in the history
…ds (#2022)

* EZP-24800 Support allowed classes limitation for object relation fields

* EZP-24800 code style fixes
  • Loading branch information
slaci authored and andrerom committed Jul 31, 2017
1 parent 745b87c commit dded74a
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 71 deletions.
Expand Up @@ -220,6 +220,8 @@
{% endif %}
</div>
</li>
{{ block( 'settings_selection_content_types' ) }}

{% set rootLocationId = settings.selectionRoot %}
{{ block( 'settings_selectionroot' ) }}
</ul>
Expand Down Expand Up @@ -247,21 +249,9 @@
{% endif %}
</div>
</li>
<li class="ez-fielddefinition-setting allowed-content-types">
<div class="ez-fielddefinition-setting-name">{{ 'fielddefinition.allowed-content-types.label'|trans|desc("Allowed content types:")}}</div>
<div class="ez-fielddefinition-setting-value">
{% if settings.selectionContentTypes %}
{# TODO display content type name #}
<ul>
{% for typeIdentifier in settings.selectionContentTypes %}
<li>{{ typeIdentifier }}</li>
{% endfor %}
</ul>
{% else %}
<em>{{ 'fielddefinition.allowed-content-types.any'|trans|desc("Any")}}</em>
{% endif %}
</div>
</li>

{{ block( 'settings_selection_content_types' ) }}

{% set rootLocationId = settings.selectionDefaultLocation %}
{{ block( 'settings_selectionroot' ) }}
</ul>
Expand Down Expand Up @@ -342,6 +332,24 @@
</li>
{% endblock %}

{% block settings_selection_content_types %}
<li class="ez-fielddefinition-setting allowed-content-types">
<div class="ez-fielddefinition-setting-name">{{ 'fielddefinition.allowed-content-types.label'|trans|desc("Allowed content types:")}}</div>
<div class="ez-fielddefinition-setting-value">
{% if settings.selectionContentTypes %}
{# TODO display content type name #}
<ul>
{% for typeIdentifier in settings.selectionContentTypes %}
<li>{{ typeIdentifier }}</li>
{% endfor %}
</ul>
{% else %}
<em>{{ 'fielddefinition.allowed-content-types.any'|trans|desc("Any")}}</em>
{% endif %}
</div>
</li>
{% endblock %}

{% block settings_defaultvalue %}
<li class="ez-fielddefinition-setting default-value">
<div class="ez-fielddefinition-setting-name">{{ 'fielddefinition.default-value.label'|trans|desc("Default value:")}}</div>
Expand Down
Expand Up @@ -80,16 +80,20 @@ public function getUpdateExpectedRelations(Content $content)
*/
public function getSettingsSchema()
{
return array(
'selectionMethod' => array(
return [
'selectionMethod' => [
'type' => 'int',
'default' => 0,
),
'selectionRoot' => array(
],
'selectionRoot' => [
'type' => 'string',
'default' => '',
),
);
'default' => null,
],
'selectionContentTypes' => [
'type' => 'array',
'default' => [],
],
];
}

/**
Expand All @@ -109,7 +113,11 @@ public function getValidatorSchema()
*/
public function getValidFieldSettings()
{
return array('selectionMethod' => 0, 'selectionRoot' => '1');
return [
'selectionMethod' => 0,
'selectionRoot' => '1',
'selectionContentTypes' => ['blog_post'],
];
}

/**
Expand All @@ -133,7 +141,12 @@ public function getValidValidatorConfiguration()
*/
public function getInvalidFieldSettings()
{
return array('selectionMethod' => 'a', 'selectionRoot' => true, 'unknownSetting' => false);
return [
'selectionMethod' => 'a',
'selectionRoot' => true,
'unknownSetting' => false,
'selectionContentTypes' => true,
];
}

/**
Expand Down
28 changes: 22 additions & 6 deletions eZ/Publish/Core/FieldType/Relation/Type.php
Expand Up @@ -29,16 +29,20 @@ class Type extends FieldType
const SELECTION_BROWSE = 0;
const SELECTION_DROPDOWN = 1;

protected $settingsSchema = array(
'selectionMethod' => array(
protected $settingsSchema = [
'selectionMethod' => [
'type' => 'int',
'default' => self::SELECTION_BROWSE,
),
'selectionRoot' => array(
],
'selectionRoot' => [
'type' => 'string',
'default' => null,
),
);
],
'selectionContentTypes' => [
'type' => 'array',
'default' => [],
],
];

/**
* @see \eZ\Publish\Core\FieldType\FieldType::validateFieldSettings()
Expand Down Expand Up @@ -91,6 +95,18 @@ public function validateFieldSettings($fieldSettings)
);
}
break;
case 'selectionContentTypes':
if (!is_array($value)) {
$validationErrors[] = new ValidationError(
"Setting '%setting%' value must be of array type",
null,
[
'%setting%' => $name,
],
"[$name]"
);
}
break;
}
}

Expand Down
16 changes: 10 additions & 6 deletions eZ/Publish/Core/FieldType/Tests/RelationTest.php
Expand Up @@ -52,16 +52,20 @@ protected function getValidatorConfigurationSchemaExpectation()
*/
protected function getSettingsSchemaExpectation()
{
return array(
'selectionMethod' => array(
return [
'selectionMethod' => [
'type' => 'int',
'default' => RelationType::SELECTION_BROWSE,
),
'selectionRoot' => array(
],
'selectionRoot' => [
'type' => 'string',
'default' => null,
),
);
],
'selectionContentTypes' => [
'type' => 'array',
'default' => [],
],
];
}

/**
Expand Down
Expand Up @@ -8,6 +8,7 @@
*/
namespace eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\Converter;

use DOMDocument;
use eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\Converter;
use eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldValue;
use eZ\Publish\SPI\Persistence\Content\FieldValue;
Expand Down Expand Up @@ -52,9 +53,9 @@ public function toStorageValue(FieldValue $value, StorageFieldValue $storageFiel
*/
public function toFieldValue(StorageFieldValue $value, FieldValue $fieldValue)
{
$fieldValue->data = array(
$fieldValue->data = [
'destinationContentId' => $value->dataInt ?: null,
);
];
$fieldValue->sortKey = (int)$value->sortKeyInt;
}

Expand All @@ -66,30 +67,103 @@ public function toFieldValue(StorageFieldValue $value, FieldValue $fieldValue)
*/
public function toStorageFieldDefinition(FieldDefinition $fieldDef, StorageFieldDefinition $storageDef)
{
// Selection method, 0 = browse, 1 = dropdown
$storageDef->dataInt1 = (int)$fieldDef->fieldTypeConstraints->fieldSettings['selectionMethod'];
$fieldSettings = $fieldDef->fieldTypeConstraints->fieldSettings;
$doc = new DOMDocument('1.0', 'utf-8');
$root = $doc->createElement('related-objects');
$doc->appendChild($root);

// Selection root, location ID
$storageDef->dataInt2 = (int)$fieldDef->fieldTypeConstraints->fieldSettings['selectionRoot'];
$constraints = $doc->createElement('constraints');
if (!empty($fieldSettings['selectionContentTypes'])) {
foreach ($fieldSettings['selectionContentTypes'] as $typeIdentifier) {
$allowedClass = $doc->createElement('allowed-class');
$allowedClass->setAttribute('contentclass-identifier', $typeIdentifier);
$constraints->appendChild($allowedClass);
unset($allowedClass);
}
}
$root->appendChild($constraints);

$selectionType = $doc->createElement('selection_type');
if (isset($fieldSettings['selectionMethod'])) {
$selectionType->setAttribute('value', (int)$fieldSettings['selectionMethod']);
} else {
$selectionType->setAttribute('value', 0);
}
$root->appendChild($selectionType);

$defaultLocation = $doc->createElement('contentobject-placement');
if (!empty($fieldSettings['selectionRoot'])) {
$defaultLocation->setAttribute('node-id', (int)$fieldSettings['selectionRoot']);
}
$root->appendChild($defaultLocation);

$doc->appendChild($root);
$storageDef->dataText5 = $doc->saveXML();
}

/**
* Converts field definition data in $storageDef into $fieldDef.
*
* @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldDefinition $storageDef
* <code>
* <?xml version="1.0" encoding="utf-8"?>
* <related-objects>
* <constraints>
* <allowed-class contentclass-identifier="blog_post"/>
* </constraints>
* <selection_type value="1"/>
* <contentobject-placement node-id="67"/>
* </related-objects>
*
* <?xml version="1.0" encoding="utf-8"?>
* <related-objects>
* <constraints/>
* <selection_type value="0"/>
* <contentobject-placement/>
* </related-objects>
* </code>
*
* @param \eZ\Publish\SPI\Persistence\Content\Type\FieldDefinition $fieldDef
* @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldDefinition $storageDef
*/
public function toFieldDefinition(StorageFieldDefinition $storageDef, FieldDefinition $fieldDef)
{
// Selection method, 0 = browse, 1 = dropdown
$fieldDef->fieldTypeConstraints->fieldSettings['selectionMethod'] = $storageDef->dataInt1;
// default settings
// use dataInt1 and dataInt2 fields as default for backward compatibility
$fieldDef->fieldTypeConstraints->fieldSettings = [
'selectionMethod' => $storageDef->dataInt1,
'selectionRoot' => $storageDef->dataInt2 === 0 ? '' : $storageDef->dataInt2,
'selectionContentTypes' => [],
];

if ($storageDef->dataText5 === null) {
return;
}

// read settings from storage
$fieldSettings = &$fieldDef->fieldTypeConstraints->fieldSettings;
$dom = new DOMDocument('1.0', 'utf-8');
if (empty($storageDef->dataText5) || $dom->loadXML($storageDef->dataText5) !== true) {
return;
}

if ($selectionType = $dom->getElementsByTagName('selection_type')) {
$fieldSettings['selectionMethod'] = (int)$selectionType->item(0)->getAttribute('value');
}

if (
($defaultLocation = $dom->getElementsByTagName('contentobject-placement')) &&
$defaultLocation->item(0)->hasAttribute('node-id')
) {
$fieldSettings['selectionRoot'] = (int)$defaultLocation->item(0)->getAttribute('node-id');
}

// Selection root, location ID
if (!($constraints = $dom->getElementsByTagName('constraints'))) {
return;
}

$fieldDef->fieldTypeConstraints->fieldSettings['selectionRoot'] =
$storageDef->dataInt2 === 0
? ''
: $storageDef->dataInt2;
foreach ($constraints->item(0)->getElementsByTagName('allowed-class') as $allowedClass) {
$fieldSettings['selectionContentTypes'][] = $allowedClass->getAttribute('contentclass-identifier');
}
}

/**
Expand All @@ -99,7 +173,7 @@ public function toFieldDefinition(StorageFieldDefinition $storageDef, FieldDefin
* "sort_key_int" or "sort_key_string". This column is then used for
* filtering and sorting for this type.
*
* @return false
* @return string
*/
public function getIndexColumn()
{
Expand Down
Expand Up @@ -161,25 +161,27 @@ public function toStorageFieldDefinition(FieldDefinition $fieldDef, StorageField
/**
* 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>
* <code>
* <?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>
* <?xml version="1.0" encoding="utf-8"?>
* <related-objects>
* <constraints/>
* <type value="2"/>
* <selection_type value="0"/>
* <object_class value=""/>
* <contentobject-placement/>
* </related-objects>
* </code>
*
* @param \eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldDefinition $storageDef
* @param \eZ\Publish\SPI\Persistence\Content\Type\FieldDefinition $fieldDef
Expand Down

0 comments on commit dded74a

Please sign in to comment.