diff --git a/composer.json b/composer.json index b1c2ec5..09e7287 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,7 @@ }, "autoload": { "psr-4": { - "MensBeam\\Microformats\\": "lib/" + "MensBeam\\": "lib/" } }, "autoload-dev": { diff --git a/lib/Microformats.php b/lib/Microformats.php new file mode 100644 index 0000000..d2cc67f --- /dev/null +++ b/lib/Microformats.php @@ -0,0 +1,130 @@ +document->documentElement, $url, $options); + } + + /** Parses an HTML element for microformats + * + * @param \DOMElement $input The element to examine. Siblings and ancestors of this element will be ignored + * @param string $url The effective URL (after redirections) of the document if known + * @param array $options Options for the parser; please see the class documentetation for details + */ + public static function fromHTMLElement(\DOMElement $input, string $url, array $options = []): self { + return new static((new MfParser)->parseHTMLElement($input, $url, $options)); + } + + /** Imports a plain array into this wrapper class + * + * This is mainly useful for proper JSON serialization. + * + * @param array $data The complete Microformats associative array + */ + public function __construct(array $data) { + $this->data = $data; + } + + public function offsetExists(mixed $offset): bool { + return isset($this->data[$offset]); + } + + public function &offsetGet(mixed $offset): mixed { + return $this->data[$offset]; + } + + public function offsetSet(mixed $offset, mixed $value): void { + $this->data[$offset] = $value; + } + + public function offsetUnset(mixed $offset): void { + unset($this->data[$offset]); + } + + public function jsonSerialize(): mixed { + // In order for a Microformats structure to serialize to JSON correctly + // we must ensure empty hash tables serialize to objects rather than + // arrays as they otherwise would. This cannot cover all possible + // cases of manipulation, but does cover cases which normally occur + // with data in the wild. + $data = $this->data; + $walk = function(&$arr) { + foreach ($arr as $k => &$v) { + if (is_array($v)) { + if ($k === "properties" && !$v) { + $v = new \stdClass; + } else { + __FUNCTION__($v); + } + } + } + }; + if (!$data['rels']) { + $data['rels'] = new \stdClass; + } + if (!$data['rel-urls']) { + $data['rel-urls'] = new \stdClass; + } + $walk($data['items']); + return $data; + } +} \ No newline at end of file diff --git a/lib/Parser.php b/lib/Microformats/Parser.php similarity index 99% rename from lib/Parser.php rename to lib/Microformats/Parser.php index 17b8b52..aefbc6f 100644 --- a/lib/Parser.php +++ b/lib/Microformats/Parser.php @@ -16,11 +16,12 @@ use MensBeam\HTML\Parser\Serializer; * is optional. Where an $options array is a possible parameter, the following * keys are understood: * - * - `simpleTrim` (bool) Whether to use the traditional "simple" whitespace trimming algorithm rather than the default, more aggressive trimming algorithm * - `impliedTz` (bool) Whether to allow an implied datetime value to supply an implied timezone to datetimes without a timezone * - `lang` (bool) Whether to include language information in microformat and rich-text structures + * - `simpleTrim` (bool) Whether to use the traditional "simple" whitespace trimming algorithm rather than the default, more aggressive trimming algorithm * - * @internal */ + * @internal + */ class Parser { /** @var array A ranking of prefixes (with 1 being least preferred) to break ties when multiple properties of the same name exist on one element */ protected const PREFIX_RANK = [ diff --git a/lib/Url.php b/lib/Microformats/Url.php similarity index 100% rename from lib/Url.php rename to lib/Microformats/Url.php