From 718338c90f8220c63a89683a6d2e13f510b00e54 Mon Sep 17 00:00:00 2001 From: Barnaby Walters Date: Sat, 5 Nov 2022 22:14:16 +0100 Subject: [PATCH] Added support for default options to be passed to the constructor * Default options are applied to calls to parse(), rels(), feeds() and process() * Default options are overridden by options passed to the respective function call on a property-by-property basis * Documented in README with example * Added basic test (only for parse() behaviour) * Also fixed a bug causing an error processing h-cards with no URL property --- README.md | 9 +++++++-- lib/XRay.php | 16 +++++++++++++++- lib/XRay/Formats/Mf2.php | 22 +++++++++++++--------- tests/LibraryTest.php | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 31f3064..5d2c20d 100644 --- a/README.md +++ b/README.md @@ -69,11 +69,16 @@ In both cases, you can add an additional parameter to configure various options Additional parameters are supported when making requests that use the Twitter or GitHub API. See the Authentication section below for details. +The XRay constructor can optionally be passed an array of default options, which will be applied in +addition to (and can be overridden by) the options passed to individual `parse()` calls. + ```php -$xray = new p3k\XRay(); +$xray = new p3k\XRay([ + 'timeout' => 30 // Time-out all requests which take longer than 30s +]); $parsed = $xray->parse('https://aaronparecki.com/2017/04/28/9/', [ - 'timeout' => 30 + 'timeout' => 40 // Override the default 30s timeout for this specific request ]); $parsed = $xray->parse('https://aaronparecki.com/2017/04/28/9/', $html, [ diff --git a/lib/XRay.php b/lib/XRay.php index 771bcdd..273e6fa 100644 --- a/lib/XRay.php +++ b/lib/XRay.php @@ -4,17 +4,26 @@ namespace p3k; class XRay { public $http; - public function __construct() { + private $defaultOptions = []; + + public function __construct($options=[]) { $this->http = new HTTP('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36 p3k/XRay'); + if (is_array($options)) { + $this->defaultOptions = $options; + } } public function rels($url, $opts=[]) { $rels = new XRay\Rels($this->http); + // Merge provided options with default options, allowing provided options to override defaults. + $opts = array_merge($this->defaultOptions, $opts); return $rels->parse($url, $opts); } public function feeds($url, $opts=[]) { $feeds = new XRay\Feeds($this->http); + // Merge provided options with default options, allowing provided options to override defaults. + $opts = array_merge($this->defaultOptions, $opts); return $feeds->find($url, $opts); } @@ -35,6 +44,9 @@ class XRay { } $parser = new XRay\Parser($this->http); + // Merge provided options with default options, allowing provided options to override defaults. + $opts = array_merge($this->defaultOptions, $opts); + $result = $parser->parse([ 'body' => $body, 'url' => $url, @@ -51,6 +63,8 @@ class XRay { public function process($url, $mf2json, $opts=[]) { $parser = new XRay\Parser($this->http); + // Merge provided options with default options, allowing provided options to override defaults. + $opts = array_merge($this->defaultOptions, $opts); $result = $parser->parse([ 'body' => $mf2json, 'url' => $url, diff --git a/lib/XRay/Formats/Mf2.php b/lib/XRay/Formats/Mf2.php index 6f0785b..b6f5e11 100644 --- a/lib/XRay/Formats/Mf2.php +++ b/lib/XRay/Formats/Mf2.php @@ -705,18 +705,22 @@ class Mf2 extends Format { if($p == 'url' && $authorURL) { // If there is a matching author URL, use that one $found = false; - foreach($item['properties']['url'] as $url) { - if(self::isURL($url)) { - $url = \p3k\XRay\normalize_url($url); - if($url == \p3k\XRay\normalize_url($authorURL)) { - $data['url'] = $url; - $found = true; + if (array_key_exists('url', $item['properties']) and is_array($item['properties']['url'])) { + foreach($item['properties']['url'] as $url) { + if(self::isURL($url)) { + $url = \p3k\XRay\normalize_url($url); + if($url == \p3k\XRay\normalize_url($authorURL)) { + $data['url'] = $url; + $found = true; + } } } + + if(!$found && self::isURL($item['properties']['url'][0])) { + $data['url'] = $item['properties']['url'][0]; + } } - if(!$found && self::isURL($item['properties']['url'][0])) { - $data['url'] = $item['properties']['url'][0]; - } + } else if(($v = self::getPlaintext($item, $p)) !== null) { // Make sure the URL property is actually a URL if($p == 'url' || $p == 'photo') { diff --git a/tests/LibraryTest.php b/tests/LibraryTest.php index 15f3883..2100807 100644 --- a/tests/LibraryTest.php +++ b/tests/LibraryTest.php @@ -71,4 +71,40 @@ class LibraryTest extends PHPUnit\Framework\TestCase $this->assertArrayNotHasKey('html', $data); } + public function testHandlesHCardWithoutURLProperty() + { + $url = 'http://example.com/'; + $html = '

The Mythical URLless Person

'; + $xray = new p3k\XRay(); + $data = $xray->parse($url, $html); + $this->assertEquals('card', $data['data']['type']); + } + + public function testDefaultOptionsAreUsed() + { + $url = 'http://example.com/'; + $html = '

A Person

'; + + $defaultOptionsXRay = new p3k\XRay(['include_original' => true]); + $normalXRay = new p3k\XRay(); + + // Make sure that the options we’re testing with actually result in different values first. + $this->assertNotEquals( + $defaultOptionsXRay->parse($url, $html), + $normalXRay->parse($url, $html) + ); + + // Make sure that the options are applied in the same way as they would have been if passed to parse() + $this->assertEquals( + $defaultOptionsXRay->parse($url, $html), + $normalXRay->parse($url, $html, ['include_original' => true]) + ); + + // Make sure that the options can be overridden (this doesn’t test on a property-by-property basis but should be good enough.) + $this->assertEquals( + $defaultOptionsXRay->parse($url, $html, ['include_original' => false]), + $normalXRay->parse($url, $html) + ); + } + }