Файловый менеджер - Редактировать - /var/www/html/json-ld.zip
Ðазад
PK ! �U>�J J README.mdnu �[��� JsonLD [](https://github.com/lanthaler/JsonLD/actions/workflows/ci.yaml) ============== JsonLD is a fully conforming [JSON-LD](http://www.w3.org/TR/json-ld/) processor written in PHP. It is extensively tested and passes the [official JSON-LD test suite](https://github.com/json-ld/tests). There's an [online playground](http://www.markus-lanthaler.com/jsonld/playground/) where you can evaluate the processor's basic functionality. Additionally to the features defined by the [JSON-LD API specification](http://www.w3.org/TR/json-ld-api/), JsonLD supports [framing](http://json-ld.org/spec/latest/json-ld-framing/) (including [value matching](https://github.com/json-ld/json-ld.org/issues/110), [deep-filtering](https://github.com/json-ld/json-ld.org/issues/110), [aggressive re-embedding](https://github.com/json-ld/json-ld.org/issues/119), and [named graphs](https://github.com/json-ld/json-ld.org/issues/118)) and an experimental [object-oriented interface for JSON-LD documents](https://github.com/lanthaler/JsonLD/issues/15). Installation ------------ The easiest way to install `JsonLD` is by requiring it with [Composer](https://getcomposer.org/). ``` composer require ml/json-ld ``` ... and including Composer's autoloader to your project ```php require('vendor/autoload.php'); ``` Of course, you can also download JsonLD as [ZIP archive](https://github.com/lanthaler/JsonLD/releases) from Github. JsonLD requires PHP 5.3 or later. Usage ------------ The library supports the official [JSON-LD API](http://www.w3.org/TR/json-ld-api/) as well as a object-oriented interface for JSON-LD documents (not fully implemented yet, see [issue #15](https://github.com/lanthaler/JsonLD/issues/15) for details). All classes are extensively documented. Please have a look at the source code. ```php // Official JSON-LD API $expanded = JsonLD::expand('document.jsonld'); $compacted = JsonLD::compact('document.jsonld', 'context.jsonld'); $framed = JsonLD::frame('document.jsonld', 'frame.jsonld'); $flattened = JsonLD::flatten('document.jsonld'); $quads = JsonLD::toRdf('document.jsonld'); // Output the expanded document (pretty print) print JsonLD::toString($expanded, true); // Serialize the quads as N-Quads $nquads = new NQuads(); $serialized = $nquads->serialize($quads); print $serialized; // And parse them again to a JSON-LD document $quads = $nquads->parse($serialized); $document = JsonLD::fromRdf($quads); print JsonLD::toString($document, true); // Node-centric API $doc = JsonLD::getDocument('document.jsonld'); // get the default graph $graph = $doc->getGraph(); // get all nodes in the graph $nodes = $graph->getNodes(); // retrieve a node by ID $node = $graph->getNode('http://example.com/node1'); // get a property $node->getProperty('http://example.com/vocab/name'); // add a new blank node to the graph $newNode = $graph->createNode(); // link the new blank node to the existing node $node->addPropertyValue('http://example.com/vocab/link', $newNode); // even reverse properties are supported; this returns $newNode $node->getReverseProperty('http://example.com/vocab/link'); // serialize the graph and convert it to a string $serialized = JsonLD::toString($graph->toJsonLd()); ``` Commercial Support ------------ Commercial support is available on request. PK ! S?��3 �3 Node.phpnu �[��� <?php /* * (c) Markus Lanthaler <mail@markus-lanthaler.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace ML\JsonLD; use stdClass as JsonObject; /** * A Node represents a node in a JSON-LD graph. * * @author Markus Lanthaler <mail@markus-lanthaler.com> */ class Node implements NodeInterface, JsonLdSerializable { /** The @type constant. */ const TYPE = '@type'; /** * @var GraphInterface The graph the node belongs to. */ private $graph; /** * @var string The ID of the node */ private $id; /** * @var array An associative array holding all properties of the node except it's ID */ private $properties = array(); /** * An associative array holding all reverse properties of this node, i.e., * a pointers to all nodes that link to this node. * * @var array */ private $revProperties = array(); /** * Constructor * * @param GraphInterface $graph The graph the node belongs to. * @param null|string $id The ID of the node. */ public function __construct(GraphInterface $graph, $id = null) { $this->graph = $graph; $this->id = $id; } /** * {@inheritdoc} */ public function getId() { return $this->id; } /** * {@inheritdoc} */ public function setType($type) { if ((null !== $type) && !($type instanceof NodeInterface)) { if (is_array($type)) { foreach ($type as $val) { if ((null !== $val) && !($val instanceof NodeInterface)) { throw new \InvalidArgumentException('type must be null, a Node, or an array of Nodes'); } } } else { throw new \InvalidArgumentException('type must be null, a Node, or an array of Nodes'); } } $this->setProperty(self::TYPE, $type); return $this; } /** * {@inheritdoc} */ public function addType(NodeInterface $type) { $this->addPropertyValue(self::TYPE, $type); return $this; } /** * {@inheritdoc} */ public function removeType(NodeInterface $type) { $this->removePropertyValue(self::TYPE, $type); return $this; } /** * {@inheritdoc} */ public function getType() { return $this->getProperty(self::TYPE); } /** * {@inheritdoc} */ public function getNodesWithThisType() { if (null === ($nodes = $this->getReverseProperty(self::TYPE))) { return array(); } return (is_array($nodes)) ? $nodes : array($nodes); } /** * {@inheritdoc} */ public function getGraph() { return $this->graph; } /** * {@inheritdoc} */ public function removeFromGraph() { // Remove other node's properties and reverse properties pointing to // this node foreach ($this->revProperties as $property => $nodes) { foreach ($nodes as $node) { $node->removePropertyValue($property, $this); } } foreach ($this->properties as $property => $values) { if (!is_array($values)) { $values = array($values); } foreach ($values as $value) { if ($value instanceof NodeInterface) { $this->removePropertyValue($property, $value); } } } $g = $this->graph; $this->graph = null; $g->removeNode($this); return $this; } /** * {@inheritdoc} */ public function isBlankNode() { return ((null === $this->id) || ('_:' === substr($this->id, 0, 2))); } /** * {@inheritdoc} */ public function setProperty($property, $value) { if (null === $value) { $this->removeProperty($property); } else { $this->doMergeIntoProperty((string) $property, array(), $value); } return $this; } /** * {@inheritdoc} */ public function addPropertyValue($property, $value) { $existing = (isset($this->properties[(string) $property])) ? $this->properties[(string) $property] : array(); if (!is_array($existing)) { $existing = array($existing); } $this->doMergeIntoProperty((string) $property, $existing, $value); return $this; } /** * Merge a value into a set of existing values. * * @param string $property The name of the property. * @param array $existingValues The existing values. * @param mixed $value The value to merge into the existing * values. This MUST NOT be an array. * * @throws \InvalidArgumentException If value is an array or an object * which is neither a language-tagged * string nor a typed value or a node. */ private function doMergeIntoProperty($property, $existingValues, $value) { // TODO: Handle lists! if (null === $value) { return; } if (!$this->isValidPropertyValue($value)) { throw new \InvalidArgumentException( 'value must be a scalar, a node, a language-tagged string, or a typed value' ); } $normalizedValue = $this->normalizePropertyValue($value); foreach ($existingValues as $existing) { if ($this->equalValues($existing, $normalizedValue)) { return; } } $existingValues[] = $normalizedValue; if (1 === count($existingValues)) { $existingValues = $existingValues[0]; } $this->properties[$property] = $existingValues; if ($normalizedValue instanceof NodeInterface) { $value->addReverseProperty($property, $this); } } /** * {@inheritdoc} */ public function removeProperty($property) { if (!isset($this->properties[(string) $property])) { return $this; } $values = is_array($this->properties[(string) $property]) ? $this->properties[(string) $property] : array($this->properties[(string) $property]); foreach ($values as $value) { if ($value instanceof NodeInterface) { $value->removeReverseProperty((string) $property, $this); } } unset($this->properties[(string) $property]); return $this; } /** * {@inheritdoc} */ public function removePropertyValue($property, $value) { if (!$this->isValidPropertyValue($value) || !isset($this->properties[(string) $property])) { return $this; } $normalizedValue = $this->normalizePropertyValue($value); $values =& $this->properties[(string) $property]; if (!is_array($this->properties[(string) $property])) { $values = array($values); } for ($i = 0, $length = count($values); $i < $length; $i++) { if ($this->equalValues($values[$i], $normalizedValue)) { if ($normalizedValue instanceof NodeInterface) { $normalizedValue->removeReverseProperty((string) $property, $this); } unset($values[$i]); break; } } if (0 === count($values)) { unset($this->properties[(string) $property]); return $this; } $this->properties[(string) $property] = array_values($values); // re-index the array if (1 === count($this->properties[(string) $property])) { $this->properties[(string) $property] = $this->properties[(string) $property][0]; } } /** * {@inheritdoc} */ public function getProperties() { return $this->properties; } /** * {@inheritdoc} */ public function getProperty($property) { return (isset($this->properties[(string) $property])) ? $this->properties[(string) $property] : null; } /** * {@inheritdoc} */ public function getReverseProperties() { $result = array(); foreach ($this->revProperties as $key => $nodes) { $result[$key] = array_values($nodes); } return $result; } /** * {@inheritdoc} */ public function getReverseProperty($property) { if (!isset($this->revProperties[(string) $property])) { return null; } $result = array_values($this->revProperties[(string) $property]); return (1 === count($result)) ? $result[0] : $result; } /** * {@inheritdoc} */ public function equals(NodeInterface $other) { return $this === $other; } /** * {@inheritdoc} */ public function toJsonLd($useNativeTypes = true) { $node = new \stdClass(); // Only label blank nodes if other nodes point to it if ((false === $this->isBlankNode()) || (count($this->getReverseProperties()) > 0)) { $node->{'@id'} = $this->getId(); } $properties = $this->getProperties(); foreach ($properties as $prop => $values) { if (false === is_array($values)) { $values = array($values); } if (self::TYPE === $prop) { $node->{'@type'} = array(); foreach ($values as $val) { $node->{'@type'}[] = $val->getId(); } continue; } $node->{$prop} = array(); foreach ($values as $value) { if ($value instanceof NodeInterface) { $ref = new \stdClass(); $ref->{'@id'} = $value->getId(); $node->{$prop}[] = $ref; } elseif (is_object($value)) { // language-tagged string or typed value $node->{$prop}[] = $value->toJsonLd($useNativeTypes); } else { $val = new JsonObject(); $val->{'@value'} = $value; $node->{$prop}[] = $val; } } } return $node; } /** * Add a reverse property. * * @param string $property The name of the property. * @param NodeInterface $node The node which has a property pointing * to this node instance. */ protected function addReverseProperty($property, NodeInterface $node) { $this->revProperties[$property][$node->getId()] = $node; } /** * Remove a reverse property. * * @param string $property The name of the property. * @param NodeInterface $node The node which has a property pointing * to this node instance. */ protected function removeReverseProperty($property, NodeInterface $node) { unset($this->revProperties[$property][$node->getId()]); if (0 === count($this->revProperties[$property])) { unset($this->revProperties[$property]); } } /** * Checks whether a value is a valid property value. * * @param mixed $value The value to check. * * @return bool Returns true if the value is a valid property value; * false otherwise. */ protected function isValidPropertyValue($value) { return (is_scalar($value) || (is_object($value) && ((($value instanceof NodeInterface) && ($value->getGraph() === $this->graph)) || ($value instanceof Value)))); } /** * Normalizes a property value by converting scalars to Value objects. * * @param mixed $value The value to normalize. * * @return NodeInterface|Value The normalized value. */ protected function normalizePropertyValue($value) { if (false === is_scalar($value)) { return $value; } return Value::fromJsonLd((object) array('@value' => $value)); } /** * Checks whether the two specified values are the same. * * Scalars and nodes are checked for identity, value objects for * equality. * * @param mixed $value1 Value 1. * @param mixed $value2 Value 2. * * @return bool Returns true if the two values are equals; otherwise false. */ protected function equalValues($value1, $value2) { if (gettype($value1) !== gettype($value2)) { return false; } if (is_object($value1) && ($value1 instanceof Value)) { return $value1->equals($value2); } return ($value1 === $value2); } } PK ! H�gK� � DocumentLoaderInterface.phpnu �[��� <?php /* * (c) Markus Lanthaler <mail@markus-lanthaler.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace ML\JsonLD; use ML\JsonLD\Exception\JsonLdException; /** * Interface for (remote) document loaders * * @author Markus Lanthaler <mail@markus-lanthaler.com> */ interface DocumentLoaderInterface { /** * Load a (remote) document or context * * @param string $url The URL or path of the document to load. * * @return RemoteDocument The loaded document. * * @throws JsonLdException */ public function loadDocument($url); } PK ! �G�� NQuads.phpnu �[��� <?php /* * (c) Markus Lanthaler <mail@markus-lanthaler.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace ML\JsonLD; use ML\JsonLD\Exception\InvalidQuadException; use ML\IRI\IRI; /** * NQuads serializes quads to the NQuads format * * @author Markus Lanthaler <mail@markus-lanthaler.com> */ class NQuads implements QuadSerializerInterface, QuadParserInterface { /** * {@inheritdoc} */ public function serialize(array $quads) { $result = ''; foreach ($quads as $quad) { $result .= ('_' === $quad->getSubject()->getScheme()) ? $quad->getSubject() : '<' . $quad->getSubject() . '>'; $result .= ' '; $result .= ('_' === $quad->getProperty()->getScheme()) ? $quad->getProperty() : '<' . $quad->getProperty() . '>'; $result .= ' '; if ($quad->getObject() instanceof IRI) { $result .= ('_' === $quad->getObject()->getScheme()) ? $quad->getObject() : '<' . $quad->getObject() . '>'; } else { $result .= '"' . str_replace( array("\n", '"'), array('\n', '\"'), $quad->getObject()->getValue()) . '"'; $result .= ($quad->getObject() instanceof TypedValue) ? (RdfConstants::XSD_STRING === $quad->getObject()->getType()) ? '' : '^^<' . $quad->getObject()->getType() . '>' : '@' . $quad->getObject()->getLanguage(); } $result .= ' '; if ($quad->getGraph()) { $result .= ('_' === $quad->getGraph()->getScheme()) ? $quad->getGraph() : '<' . $quad->getGraph() . '>'; $result .= ' '; } $result .= ".\n"; } return $result; } /** * {@inheritdoc} * * This method is heavily based on DigitalBazaar's implementation used * in their {@link https://github.com/digitalbazaar/php-json-ld php-json-ld}. * * @throws InvalidQuadException If an invalid quad that can't be parsed is * encountered. */ public function parse($input) { // define partial regexes $iri = '(?:<([^>]*)>)'; // blank node labels based on https://www.w3.org/TR/n-quads/#BNodes $bnode = '(_:(?:[A-Za-z0-9_]|[A-Za-z0-9_][A-Za-z0-9_\-.]*[A-Za-z0-9_\-]))'; $plain = '"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"'; $datatype = "\\^\\^$iri"; $language = '(?:@([a-z]+(?:-[a-z0-9]+)*))'; $literal = "(?:$plain(?:$datatype|$language)?)"; $ws = '[ \\t]'; $comment = "#.*"; $subject = "(?:$iri|$bnode)$ws+"; $property = "$iri$ws+"; $object = "(?:$iri|$bnode|$literal)"; $graph = "$ws+(?:$iri|$bnode)"; // full regexes $eoln = '/(?:(\r\n)|[\n\r])/'; $quadRegex = "/^$ws*$subject$property$object$graph?$ws*.$ws*$/"; $ignoreRegex = "/^$ws*(?:$comment)?$/"; // build RDF statements $statements = array(); // split N-Quad input into lines $lines = preg_split($eoln, $input); $line_number = 0; foreach ($lines as $line) { $line_number++; // skip empty lines if (preg_match($ignoreRegex, $line)) { continue; } // parse quad if (!preg_match($quadRegex, $line, $match)) { throw new InvalidQuadException( sprintf( 'Error while parsing N-Quads. Invalid quad in line %d: %s', $line_number, $line ), $line ); } // get subject if ($match[1] !== '') { $subject = new IRI($match[1]); } else { $subject = new IRI($match[2]); } // get property $property = new IRI($match[3]); // get object if ($match[4] !== '') { $object = new IRI($match[4]); // IRI } elseif ($match[5] !== '') { $object = new IRI($match[5]); // bnode } else { $unescaped = str_replace( array('\"', '\t', '\n', '\r', '\\\\'), array('"', "\t", "\n", "\r", '\\'), $match[6] ); if (isset($match[7]) && $match[7] !== '') { $object = new TypedValue($unescaped, $match[7]); } elseif (isset($match[8]) && $match[8] !== '') { $object = new LanguageTaggedString($unescaped, $match[8]); } else { $object = new TypedValue($unescaped, RdfConstants::XSD_STRING); } } // get graph $graph = null; if (isset($match[9]) && $match[9] !== '') { $graph = new IRI($match[9]); } elseif (isset($match[10]) && $match[10] !== '') { $graph = new IRI($match[10]); } $quad = new Quad($subject, $property, $object, $graph); // TODO Make sure that quads are unique?? $statements[] = $quad; } return $statements; } } PK ! �{ߘ � JsonLdSerializable.phpnu �[��� <?php /* * (c) Markus Lanthaler <mail@markus-lanthaler.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace ML\JsonLD; /** * The JsonLdSerializable interface * * Objects implementing JsonLdSerializable can be serialized to JSON-LD. * * @author Markus Lanthaler <mail@markus-lanthaler.com> */ interface JsonLdSerializable { /** * Convert to expanded and flattened JSON-LD * * The result can then be serialized to JSON-LD by {@see JsonLD::toString()}. * * @param boolean $useNativeTypes If set to true, native types are used * for xsd:integer, xsd:double, and * xsd:boolean, otherwise typed strings * will be used instead. * * @return mixed Returns data which can be serialized by * {@see JsonLD::toString()} (which is a value of any type * other than a resource) to expanded JSON-LD. * * @see JsonLD::toString() */ public function toJsonLd($useNativeTypes = true); } PK ! �d��� � TypedValue.phpnu �[��� <?php /* * (c) Markus Lanthaler <mail@markus-lanthaler.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace ML\JsonLD; use stdClass as JsonObject; /** * A typed value represents a value with an associated type. * * @author Markus Lanthaler <mail@markus-lanthaler.com> */ final class TypedValue extends Value { /** * The type of the value in the form of an IRI. * * @var string */ private $type; /** * Constructor * * @param string $value The value. * @param string $type The type. */ public function __construct($value, $type) { $this->setValue($value); $this->setType($type); } /** * Set the type * * For the sake of simplicity, the type is currently just a Node * identifier in the form of a string and not a Node reference. * This might be changed in the future. * * @param string $type The type. * * @return self * * @throws \InvalidArgumentException If the type is not a string. No * further checks are currently done. */ public function setType($type) { if (!is_string($type)) { throw new \InvalidArgumentException('type must be a string.'); } $this->type = $type; return $this; } /** * Get the type * * For the sake of simplicity, the type is currently just a Node * identifier in the form of a string and not a Node reference. * This might be changed in the future. * * @return string The type. */ public function getType() { return $this->type; } /** * {@inheritdoc} */ public function toJsonLd($useNativeTypes = true) { $result = new JsonObject(); if (RdfConstants::XSD_STRING === $this->type) { $result->{'@value'} = $this->value; return $result; } if (true === $useNativeTypes) { if (RdfConstants::XSD_BOOLEAN === $this->type) { if ('true' === $this->value) { $result->{'@value'} = true; return $result; } elseif ('false' === $this->value) { $result->{'@value'} = false; return $result; } } elseif (RdfConstants::XSD_INTEGER === $this->type) { if (preg_match('/^[\+|-]?\d+$/', trim($this->value))) { $result->{'@value'} = intval($this->value); return $result; } } elseif (RdfConstants::XSD_DOUBLE === $this->type) { // TODO Need to handle +/-INF and NaN as well? if (preg_match('/^[\+|-]?\d+(?:\.\d*)?(?:[eE][\+|-]?\d+)?$/', trim($this->value))) { $result->{'@value'} = floatval($this->value); return $result; } // TODO Need to preserve doubles without fraction for round-tripping?? } } $result->{'@value'} = $this->value; $result->{'@type'} = $this->type; return $result; } /** * {@inheritdoc} */ public function equals($other) { if (get_class($this) !== get_class($other)) { return false; } return ($this->value === $other->value) && ($this->type === $other->type); } } PK ! ��� � GraphInterface.phpnu �[��� <?php /* * (c) Markus Lanthaler <mail@markus-lanthaler.com> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace ML\JsonLD; /** * JSON-LD graph interface * * @author Markus Lanthaler <mail@markus-lanthaler.com> */ interface GraphInterface { /** * Creates a new node which is linked to this document * * If a blank node identifier or an invalid ID is passed, the ID will be * ignored and a new blank node identifier unique to the document is * created for the node. * * If there exists already a node with the passed ID in the document, * that node will be returned instead of creating a new one. * * @param null|string $id The ID of the node. * @param bool $preserveBnodeId If set to false, blank nodes are * relabeled to avoid collisions; * otherwise the blank node identifier * is preserved. * * @return Node The newly created node. */ public function createNode($id = null, $preserveBnodeId = false); /** * Removes a node from the document * * This will also eliminate all references to the node within the * document. * * @param NodeInterface $node The node to remove from the document. * * @return self */ public function removeNode(NodeInterface $node); /** * Get all nodes * * @return Node[] Returns an array containing all nodes defined in the * document. */ public function getNodes(); /** * Get a node by ID * * @param string $id The ID of the node to retrieve. * * @return Node|null Returns the node if found; null otherwise. */ public function getNode($id); /** * Get nodes by type * * @param string|Node $type The type * * @return Node[] Returns an array containing all nodes of the specified * type in the document. */ public function getNodesByType($type); /** * Check whether the document already contains a node with the * specified ID * * @param string|Node $id The node ID to check. Blank node identifiers * will always return false except a node instance * which is part of the document will be passed * instead of a string. * * @return bool Returns true if the document contains a node with the * specified ID; false otherwise. */ public function containsNode($id); /** * Get the document the node belongs to * * @return null|DocumentInterface Returns the document the node belongs * to or null if the node doesn't belong * to any document. */ public function getDocument(); /** * Removes the graph from the document * * @return self */ public function removeFromDocument(); /** * Merges the specified graph into the current graph * * @param GraphInterface $graph The graph that should be merged into the * current graph. * * @return self */ public function merge(GraphInterface $graph); } PK ! &q�`� � "