diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index f1080743..922d9453 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -144,6 +144,7 @@
* [Niehztog](https://github.com/Niehztog)
* [NikNikYkt](https://github.com/NikNikYkt)
* [Nono-m0le](https://github.com/Nono-m0le)
+* [NotsoanoNimus](https://github.com/NotsoanoNimus)
* [obsiwitch](https://github.com/obsiwitch)
* [Ololbu](https://github.com/Ololbu)
* [ORelio](https://github.com/ORelio)
diff --git a/bridges/EBayBridge.php b/bridges/EBayBridge.php
index 87958164..11b90bf8 100644
--- a/bridges/EBayBridge.php
+++ b/bridges/EBayBridge.php
@@ -5,15 +5,21 @@ class EBayBridge extends BridgeAbstract
const NAME = 'eBay';
const DESCRIPTION = 'Returns the search results from the eBay auctioning platforms';
const URI = 'https://www.eBay.com';
- const MAINTAINER = 'wrobelda';
+ const MAINTAINER = 'NotsoanoNimus, wrobelda';
const PARAMETERS = [[
'url' => [
'name' => 'Search URL',
'title' => 'Copy the URL from your browser\'s address bar after searching for your items and paste it here',
- 'pattern' => '^(https:\/\/)?(www\.)?(befr\.|benl\.)?ebay\.(com|com\.au|at|be|ca|ch|cn|es|fr|de|com\.hk|ie|it|com\.my|nl|ph|pl|com\.sg|co\.uk).*$',
+ 'pattern' => '^(https:\/\/)?(www\.)?(befr\.|benl\.)?ebay\.(com|com\.au|at|be|ca|ch|cn|es|fr|de|com\.hk|ie|it|com\.my|nl|ph|pl|com\.sg|co\.uk)\/.*$',
'exampleValue' => 'https://www.ebay.com/sch/i.html?_nkw=atom+rss',
'required' => true,
- ]
+ ],
+ 'includesSearchLink' => [
+ 'name' => 'Include Original Search Link',
+ 'title' => 'Whether or not each feed item should include the original search query link to eBay which was used to find the given listing.',
+ 'type' => 'checkbox',
+ 'defaultValue' => false,
+ ],
]];
public function getURI()
@@ -23,6 +29,10 @@ class EBayBridge extends BridgeAbstract
$uri = trim(preg_replace('/([?&])_sop=[^&]+(&|$)/', '$1', $this->getInput('url')), '?&/');
$uri .= (parse_url($uri, PHP_URL_QUERY) ? '&' : '?') . '_sop=10';
+ // Ensure the List View is used instead of the Gallery View.
+ $uri = trim(preg_replace('/[?&]_dmd=[^&]+(&|$)/i', '$1', $uri), '?&/');
+ $uri .= '&_dmd=1';
+
return $uri;
} else {
return parent::getURI();
@@ -46,7 +56,7 @@ class EBayBridge extends BridgeAbstract
});
if ($searchQuery) {
- return $searchQuery[0];
+ return 'eBay - ' . $searchQuery[0];
}
return parent::getName();
@@ -61,44 +71,88 @@ class EBayBridge extends BridgeAbstract
$inexactMatches->remove();
}
+ // Remove "NEW LISTING" labels: we sort by the newest, so this is redundant.
+ foreach ($html->find('.LIGHT_HIGHLIGHT') as $new_listing_label) {
+ $new_listing_label->remove();
+ }
+
$results = $html->find('ul.srp-results > li.s-item');
foreach ($results as $listing) {
$item = [];
- // Remove "NEW LISTING" label, we sort by the newest, so this is redundant
- foreach ($listing->find('.LIGHT_HIGHLIGHT') as $new_listing_label) {
- $new_listing_label->remove();
+ // Define a closure to shorten the ugliness of querying the current listing.
+ $find = function ($query, $altText = '') use ($listing) {
+ return $listing->find($query, 0)->plaintext ?? $altText;
+ };
+
+ $item['title'] = $find('.s-item__title');
+ if (!$item['title']) {
+ // Skip entries where the title cannot be found (for w/e reason).
+ continue;
}
- $listingTitle = $listing->find('.s-item__title', 0);
- if ($listingTitle) {
- $item['title'] = $listingTitle->plaintext;
- }
-
- $subtitle = implode('', $listing->find('.s-item__subtitle'));
-
- $listingUrl = $listing->find('.s-item__link', 0);
- if ($listingUrl) {
- $item['uri'] = $listingUrl->href;
+ // It appears there may be more than a single 'subtitle' subclass in the listing. Collate them.
+ $subtitles = $listing->find('.s-item__subtitle');
+ if (is_array($subtitles)) {
+ $subtitle = trim(implode(' ', array_column($subtitles, 'plaintext')));
} else {
- $item['uri'] = null;
+ $subtitle = trim($subtitles->plaintext ?? '');
}
+ // Get the listing's link and uid.
+ $itemUri = $listing->find('.s-item__link', 0);
+ if ($itemUri) {
+ $item['uri'] = $itemUri->href;
+ }
if (preg_match('/.*\/itm\/(\d+).*/i', $item['uri'], $matches)) {
$item['uid'] = $matches[1];
}
- $priceDom = $listing->find('.s-item__details > .s-item__detail > .s-item__price', 0);
- $price = $priceDom->plaintext ?? 'N/A';
+ // Price should be fetched on its own so we can provide the alt text without complication.
+ $price = $find('.s-item__price', '[NO PRICE]');
- $shippingFree = $listing->find('.s-item__details > .s-item__detail > .s-item__freeXDays', 0)->plaintext ?? '';
- $localDelivery = $listing->find('.s-item__details > .s-item__detail > .s-item__localDelivery', 0)->plaintext ?? '';
- $logisticsCost = $listing->find('.s-item__details > .s-item__detail > .s-item__logisticsCost', 0)->plaintext ?? '';
+ // Map a list of dynamic variable names to their subclasses within the listing.
+ // This is just a bit of sugar to make this cleaner and more maintainable.
+ $propertyMappings = [
+ 'additionalPrice' => '.s-item__additional-price',
+ 'discount' => '.s-item__discount',
+ 'shippingFree' => '.s-item__freeXDays',
+ 'localDelivery' => '.s-item__localDelivery',
+ 'logisticsCost' => '.s-item__logisticsCost',
+ 'location' => '.s-item__location',
+ 'obo' => '.s-item__formatBestOfferEnabled',
+ 'sellerInfo' => '.s-item__seller-info-text',
+ 'bids' => '.s-item__bidCount',
+ 'timeLeft' => '.s-item__time-left',
+ 'timeEnd' => '.s-item__time-end',
+ ];
- $location = $listing->find('.s-item__details > .s-item__detail > .s-item__location', 0)->plaintext ?? '';
+ foreach ($propertyMappings as $k => $v) {
+ $$k = $find($v);
+ }
- $sellerInfo = $listing->find('.s-item__seller-info-text', 0)->plaintext ?? '';
+ // When an additional price detail or discount is defined, create the 'discountLine'.
+ if ($additionalPrice || $discount) {
+ $discountLine = '
('
+ . trim($additionalPrice ?? '')
+ . '; ' . trim($discount ?? '')
+ . ')';
+ }
+ // Prepend the time-left info with a comma if the right details were found.
+ $timeInfo = trim($timeLeft . ' ' . $timeEnd);
+ if ($timeInfo) {
+ $timeInfo = ', ' . $timeInfo;
+ }
+
+ // Set the listing type.
+ if ($bids) {
+ $listingTypeDetails = "Auction: {$bids}{$timeInfo}";
+ } else {
+ $listingTypeDetails = 'Buy It Now';
+ }
+
+ // Acquire the listing's primary image and atach it.
$image = $listing->find('.s-item__image-wrapper > img', 0);
if ($image) {
// Not quite sure why append fragment here
@@ -106,11 +160,21 @@ class EBayBridge extends BridgeAbstract
$item['enclosures'] = [$imageUrl];
}
+ // Include the original search link, if specified.
+ if ($this->getInput('includesSearchLink')) {
+ $searchLink = '
$price $shippingFree $localDelivery $logisticsCost
-$subtitle
+$price $obo ($listingTypeDetails)
+ $discountLine
+
$shippingFree $localDelivery $logisticsCost
{$subtitle}
+$searchLink CONTENT; + $this->items[] = $item; } }