rest_oai_pmh-8.x-1.0-beta1/src/Encoder/OaiDcEncoder.php
src/Encoder/OaiDcEncoder.php
<?php
namespace Drupal\rest_oai_pmh\Encoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
/**
* OAI XML encoder.
*/
class OaiDcEncoder extends XmlEncoder {
const ROOT_NODE_NAME = 'xml_root_node_name';
/**
* The formats that this Encoder supports.
*
* @var string
*/
protected $format = 'oai_dc';
/**
* {@inheritdoc}
*/
public function supportsEncoding(string $format) : bool {
return $format == $this->format;
}
/**
* {@inheritdoc}
*/
public function supportsDecoding(string $format) : bool {
return in_array($format, [$this->format, 'form']);
}
/**
* {@inheritdoc}
*/
public function decode(string $data, string $format, array $context = []) : mixed {
if ($format === 'xml') {
return parent::decode($data, $format, $context);
}
elseif ($format === 'form') {
return $data;
}
}
/**
* {@inheritdoc}
*
* @todo find better approach to represent XML nodes that are string values but contain @attributes with PHP arrays
*
* e.g.
* $response = [
* 'error' => [
* '@code' => 'badVerb',
* 'content' => 'STRING VALUE'
* ]
* ];
* Needs to be encoded as <error code="badVerb">STRING VALUE</error>
* But instead it's encoded as:
* <error code="badVerb">
* <content>STRING VALUE</content>
* </error>
*
* With Symfony's XML Encoder can not find any clear documentation
* whether this is possible or not.
* So here we're just looking for a node we specially keyed for this case
* and removing those nodes.
* Of course this is not ideal.
*/
public function encode($data, $format, array $context = []) : string {
$context[self::ROOT_NODE_NAME] = 'OAI-PMH';
$xml = parent::encode($data, $format, $context);
$search = [
'xmlns:mods',
'<oai_dc ',
'</oai_dc>',
'<metadata-xml><![CDATA[',
']]></metadata-xml>',
'<oai-dc-string>',
'</oai-dc-string>',
];
$replace = [
'xmlns',
'<oai_dc:dc ',
'</oai_dc:dc>',
'',
'',
'',
'',
];
return str_replace($search, $replace, $xml);
}
}
