* @package tao */ class JsonLdExport implements \JsonSerializable { /** * @var \core_kernel_classes_ContainerCollection */ private $triples; /** * @var \core_kernel_classes_Class[] */ private $types; /** @var string */ private $uri; /** * List of uris to exclude during export: * * @var array */ private $blackList = [OntologyRdf::RDF_TYPE]; private $encoders = []; /** * Gets a list of properties to exclude * * @return array() */ protected function getBlackList() { return $this->blackList; } /** * Blacklist a property * * @param string $propertyUri */ public function blackList($propertyUri) { $this->blackList[] = $propertyUri; } /** * Create an Exported for the specified resurce * * @param core_kernel_classes_Resource $resource */ public function __construct(core_kernel_classes_Resource $resource = null) { if (!is_null($resource)) { $this->setTriples($resource->getRdfTriples()); $this->setTypes($resource->getTypes()); $this->setUri($resource->getUri()); } } /** * @param \core_kernel_classes_ContainerCollection $triples */ public function setTriples(\core_kernel_classes_ContainerCollection $triples) { $this->triples = $triples; } /** * @param array $types */ public function setTypes($types) { $this->types = $types; } /** * @param string $uri */ public function setUri($uri) { $this->uri = $uri; } /** * (non-PHPdoc) * @see JsonSerializable::jsonSerialize() */ public function jsonSerialize() { $data = [ '@context' => [], '@id' => $this->uri, ]; $types = $this->types; if (!empty($types)) { $data['@type'] = $this->transfromArray($types); } if (!$this->triples instanceof \core_kernel_classes_ContainerCollection) { return $data; } $triples = $this->triples->toArray(); $map = []; foreach ($triples as $key => $triple) { if (in_array($triple->predicate, $this->blackList)) { continue; } if (!isset($map[$triple->predicate])) { $id = $this->generateId($triple->predicate); if (in_array($id, $map)) { $nr = 0; while (in_array($id . '_' . $nr, $map)) { $nr++; } $id = $id . '_' . $nr; } $map[$triple->predicate] = $id; $data['@context'][$id] = $triple->predicate; } $key = $map[$triple->predicate]; if (isset($data[$key])) { if (!is_array($data[$key])) { $data[$key] = [$data[$key]]; } $data[$key][] = $this->encodeValue($triple->object, $triple->predicate); } else { $data[$key] = $this->encodeValue($triple->object, $triple->predicate); } } // Enforce serialization to object if context is empty $data['@context'] = (object) $data['@context']; return $data; } public function registerEncoder($propertyUri, callable $encoder) { $this->encoders[$propertyUri] = $encoder; } public function getEncoders() { return $this->encoders; } /** * Encode a values array * * @param array $values * @return mixed */ private function transfromArray($values) { if (count($values) > 1) { $encoded = []; foreach ($values as $value) { $encoded[] = $this->encodeValue($value); } return $encoded; } else { return $this->encodeValue(reset($values)); } } /** * Encode the value in a json-ld compatible way * * @param mixed $value * @param string $propertyUri (optional) The URI of the property the $value is related to. * @return string */ protected function encodeValue($value, $propertyUri = '') { $value = $this->applyEncoder($value, $propertyUri); return is_string($value) ? $value : ((is_object($value) && $value instanceof \core_kernel_classes_Resource) ? $value->getUri() : (string) $value ); } /** * Generate a key for the property to use during export * * @param string $uri * @return string */ protected function generateId($uri) { $property = new \core_kernel_classes_Property($uri); $label = strtolower(trim($property->getLabel())); $label = preg_replace(['/\s/', '[^a-z\-]'], ['-', ''], $label); return empty($label) ? 'key' : $label; } /** * Attempt to apply a specific value encoder. * * @param mixed $value * @param string (optional) The URI of the property the $value belongs to. * @return mixed */ protected function applyEncoder($value, $propertyUri = '') { if (empty($propertyUri) === false) { $encoders = $this->getEncoders(); if (isset($encoders[$propertyUri]) === true) { $encodedValue = call_user_func($encoders[$propertyUri], $value); return $encodedValue; } } return $value; } }