Browse Source

Abandon use of ArrayAccess and JsonSerializable

master
J. King 11 months ago
parent
commit
2e622b205d
  1. 56
      lib/Microformats.php
  2. 2
      lib/Microformats/Parser.php
  3. 18
      tests/cases/StandardTest.php

56
lib/Microformats.php

@ -27,9 +27,7 @@ use MensBeam\Microformats\Parser as MfParser;
* Currently all input is assumed to be HTML, but processing of generic XML
* data may be supported in future.
*/
class Microformats implements \ArrayAccess, \JsonSerializable {
protected $data;
class Microformats {
/** Parses a file for microformats
*
* If reading the file fails `null` is returned.
@ -44,7 +42,7 @@ class Microformats implements \ArrayAccess, \JsonSerializable {
* @param string $url The effective URL (after redirections) of the file if known
* @param array $options Options for the parser; please see the class documentetation for details
*/
public static function fromFile(string $file, string $contentType, string $url, array $options = []): ?self {
public static function fromFile(string $file, string $contentType, string $url, array $options = []): ?array {
$string = file_get_contents($file);
if ($string === false) {
return null;
@ -59,7 +57,7 @@ class Microformats implements \ArrayAccess, \JsonSerializable {
* @param string $url The effective URL (after redirections) of the string if known
* @param array $options Options for the parser; please see the class documentetation for details
*/
public static function fromString(string $input, string $contentType, string $url, array $options = []): self {
public static function fromString(string $input, string $contentType, string $url, array $options = []): array {
$parsed = HTMLParser::parse($input, $contentType);
return static::fromHTMLElement($parsed->document->documentElement, $url, $options);
}
@ -70,50 +68,28 @@ class Microformats implements \ArrayAccess, \JsonSerializable {
* @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));
public static function fromHTMLElement(\DOMElement $input, string $url, array $options = []): array {
return (new MfParser)->parseHTMLElement($input, $url, $options);
}
/** Imports a plain array into this wrapper class
/** Serializes a Microformats structure to JSON.
*
* This is mainly useful for proper JSON serialization.
* This is necessary to serialize empty hash tables (JSON objects)
* correctly. It cannot cover all possible cases of manipulation, but
* does cover cases which normally occur with data in the wild.
*
* @param array $data The complete Microformats associative array
* @param array $data The Microformats structure to serialize
* @param int $flags [optional] Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT, JSON_UNESCAPED_UNICODE. JSON_THROW_ON_ERROR The behaviour of these constants is described on the JSON constants page
* @param int $depth [optional] Set the maximum depth. Must be greater than zero.
*/
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) {
public static function toJson(array $data, int $flags = 0, int $depth = 512): string {
$walk = function(&$arr) use(&$walk) {
foreach ($arr as $k => &$v) {
if (is_array($v)) {
if ($k === "properties" && !$v) {
$v = new \stdClass;
} else {
__FUNCTION__($v);
$walk($v);
}
}
}
@ -125,6 +101,6 @@ class Microformats implements \ArrayAccess, \JsonSerializable {
$data['rel-urls'] = new \stdClass;
}
$walk($data['items']);
return $data;
return json_encode($data, $flags, $depth);
}
}

2
lib/Microformats/Parser.php

@ -19,8 +19,6 @@ use MensBeam\HTML\Parser\Serializer;
* - `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
*/
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 */

18
tests/cases/StandardTest.php

@ -6,11 +6,13 @@
declare(strict_types=1);
namespace MensBeam\Microformats\TestCase;
use MensBeam\Microformats\Parser;
use MensBeam\Microformats;
use MensBeam\HTML\DOMParser;
use MensBeam\Microformats\Url;
/** @covers MensBeam\Microformats\Parser */
/**
* @covers MensBeam\Microformats
* @covers MensBeam\Microformats\Parser
*/
class StandardTest extends \PHPUnit\Framework\TestCase {
protected const SUPPRESSED = [
'microformats-v1/hcard/multiple' => "whether vcard keys are p- or u- is unclear",
@ -27,9 +29,8 @@ class StandardTest extends \PHPUnit\Framework\TestCase {
if (isset(self::SUPPRESSED[$name])) {
$this->markTestIncomplete(self::SUPPRESSED[$name]);
}
// read data
// read expectation data
$exp = json_decode(file_get_contents($path.".json"), true);
$html = file_get_contents($path.".html");
// fix up expectation where necessary
array_walk_recursive($exp, function(&$v) {
// URLs differ trivially from output of our normalization library
@ -46,10 +47,7 @@ class StandardTest extends \PHPUnit\Framework\TestCase {
// perform some further monkey-patching on specific tests
$exp = $this->fixTests($exp, $name);
// parse input
$dom = new DOMParser;
$parser = new Parser;
$doc = $dom->parseFromString($html, "text/html; charset=UTF-8");
$act = $parser->parseHTMLElement($doc->documentElement, "http://example.com", $options);
$act = Microformats::fromFile($path.".html", "text/html; charset=UTF-8", "http://example.com/", $options);
// sort both arrays
$this->ksort($exp);
$this->ksort($act);
@ -65,7 +63,7 @@ class StandardTest extends \PHPUnit\Framework\TestCase {
// the standard tests
yield from $this->provideTestList([\MensBeam\Microformats\BASE."vendor-bin/phpunit/vendor/mf2/tests/tests/"], ['simpleTrim' => true]);
// tests from php-mf2
yield from $this->provideTestList([\MensBeam\Microformats\BASE."tests/cases/third-party/"], null);
yield from $this->provideTestList([\MensBeam\Microformats\BASE."tests/cases/third-party/"], []);
}
protected function provideTestList(array $tests, ?array $options = null): \Generator {

Loading…
Cancel
Save