mirror of
https://github.com/RSS-Bridge/rss-bridge.git
synced 2024-11-24 02:16:08 +03:00
436 lines
12 KiB
PHP
436 lines
12 KiB
PHP
|
<?php
|
||
|
class BadDragonBridge extends BridgeAbstract {
|
||
|
const NAME = 'Bad Dragon Bridge';
|
||
|
const URI = 'https://bad-dragon.com/';
|
||
|
const CACHE_TIMEOUT = 300; // 5min
|
||
|
const DESCRIPTION = 'Returns sales or new clearance items';
|
||
|
const MAINTAINER = 'Roliga';
|
||
|
const PARAMETERS = array(
|
||
|
'Sales' => array(
|
||
|
),
|
||
|
'Clearance' => array(
|
||
|
'ready_made' => array(
|
||
|
'name' => 'Ready Made',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'flop' => array(
|
||
|
'name' => 'Flops',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'skus' => array(
|
||
|
'name' => 'Products',
|
||
|
'exampleValue' => 'chanceflared, crackers',
|
||
|
'title' => 'Comma separated list of product SKUs'
|
||
|
),
|
||
|
'onesize' => array(
|
||
|
'name' => 'One-Size',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'mini' => array(
|
||
|
'name' => 'Mini',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'small' => array(
|
||
|
'name' => 'Small',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'medium' => array(
|
||
|
'name' => 'Medium',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'large' => array(
|
||
|
'name' => 'Large',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'extralarge' => array(
|
||
|
'name' => 'Extra Large',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'category' => array(
|
||
|
'name' => 'Category',
|
||
|
'type' => 'list',
|
||
|
'values' => array(
|
||
|
'All' => 'all',
|
||
|
'Accessories' => 'accessories',
|
||
|
'Merchandise' => 'merchandise',
|
||
|
'Dildos' => 'insertable',
|
||
|
'Masturbators' => 'penetrable',
|
||
|
'Packers' => 'packer',
|
||
|
'Lil\' Squirts' => 'shooter',
|
||
|
'Lil\' Vibes' => 'vibrator',
|
||
|
'Wearables' => 'wearable'
|
||
|
),
|
||
|
'defaultValue' => 'all',
|
||
|
),
|
||
|
'soft' => array(
|
||
|
'name' => 'Soft Firmness',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'med_firm' => array(
|
||
|
'name' => 'Medium Firmness',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'firm' => array(
|
||
|
'name' => 'Firm',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'split' => array(
|
||
|
'name' => 'Split Firmness',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'maxprice' => array(
|
||
|
'name' => 'Max Price',
|
||
|
'type' => 'number',
|
||
|
'required' => true,
|
||
|
'defaultValue' => 300
|
||
|
),
|
||
|
'minprice' => array(
|
||
|
'name' => 'Min Price',
|
||
|
'type' => 'number',
|
||
|
'defaultValue' => 0
|
||
|
),
|
||
|
'cumtube' => array(
|
||
|
'name' => 'Cumtube',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'suctionCup' => array(
|
||
|
'name' => 'Suction Cup',
|
||
|
'type' => 'checkbox'
|
||
|
),
|
||
|
'noAccessories' => array(
|
||
|
'name' => 'No Accessories',
|
||
|
'type' => 'checkbox'
|
||
|
)
|
||
|
)
|
||
|
);
|
||
|
|
||
|
/*
|
||
|
* This sets index $strFrom (or $strTo if set) in $outArr to 'on' if
|
||
|
* $inArr[$param] contains $strFrom.
|
||
|
* It is used for translating BD's shop filter URLs into something we can use.
|
||
|
*
|
||
|
* For the query '?type[]=ready_made&type[]=flop' we would have an array like:
|
||
|
* Array (
|
||
|
* [type] => Array (
|
||
|
* [0] => ready_made
|
||
|
* [1] => flop
|
||
|
* )
|
||
|
* )
|
||
|
* which could be translated into:
|
||
|
* Array (
|
||
|
* [ready_made] => on
|
||
|
* [flop] => on
|
||
|
* )
|
||
|
* */
|
||
|
private function setParam($inArr, &$outArr, $param, $strFrom, $strTo = null) {
|
||
|
if(isset($inArr[$param]) && in_array($strFrom, $inArr[$param])) {
|
||
|
$outArr[($strTo ?: $strFrom)] = 'on';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function detectParameters($url) {
|
||
|
$params = array();
|
||
|
|
||
|
// Sale
|
||
|
$regex = '/^(https?:\/\/)?bad-dragon\.com\/sales/';
|
||
|
if(preg_match($regex, $url, $matches) > 0) {
|
||
|
return $params;
|
||
|
}
|
||
|
|
||
|
// Clearance
|
||
|
$regex = '/^(https?:\/\/)?bad-dragon\.com\/shop\/clearance/';
|
||
|
if(preg_match($regex, $url, $matches) > 0) {
|
||
|
parse_str(parse_url($url, PHP_URL_QUERY), $urlParams);
|
||
|
|
||
|
$this->setParam($urlParams, $params, 'type', 'ready_made');
|
||
|
$this->setParam($urlParams, $params, 'type', 'flop');
|
||
|
|
||
|
if(isset($urlParams['skus'])) {
|
||
|
$skus = array();
|
||
|
foreach($urlParams['skus'] as $sku) {
|
||
|
is_string($sku) && $skus[] = $sku;
|
||
|
is_array($sku) && $skus[] = $sku[0];
|
||
|
}
|
||
|
$params['skus'] = implode(',', $skus);
|
||
|
}
|
||
|
|
||
|
$this->setParam($urlParams, $params, 'sizes', 'onesize');
|
||
|
$this->setParam($urlParams, $params, 'sizes', 'mini');
|
||
|
$this->setParam($urlParams, $params, 'sizes', 'small');
|
||
|
$this->setParam($urlParams, $params, 'sizes', 'medium');
|
||
|
$this->setParam($urlParams, $params, 'sizes', 'large');
|
||
|
$this->setParam($urlParams, $params, 'sizes', 'extralarge');
|
||
|
|
||
|
if(isset($urlParams['category'])) {
|
||
|
$params['category'] = strtolower($urlParams['category']);
|
||
|
} else{
|
||
|
$params['category'] = 'all';
|
||
|
}
|
||
|
|
||
|
$this->setParam($urlParams, $params, 'firmnessValues', 'soft');
|
||
|
$this->setParam($urlParams, $params, 'firmnessValues', 'medium', 'med_firm');
|
||
|
$this->setParam($urlParams, $params, 'firmnessValues', 'firm');
|
||
|
$this->setParam($urlParams, $params, 'firmnessValues', 'split');
|
||
|
|
||
|
if(isset($urlParams['price'])) {
|
||
|
isset($urlParams['price']['max'])
|
||
|
&& $params['maxprice'] = $urlParams['price']['max'];
|
||
|
isset($urlParams['price']['min'])
|
||
|
&& $params['minprice'] = $urlParams['price']['min'];
|
||
|
}
|
||
|
|
||
|
isset($urlParams['cumtube'])
|
||
|
&& $urlParams['cumtube'] === '1'
|
||
|
&& $params['cumtube'] = 'on';
|
||
|
isset($urlParams['suctionCup'])
|
||
|
&& $urlParams['suctionCup'] === '1'
|
||
|
&& $params['suctionCup'] = 'on';
|
||
|
isset($urlParams['noAccessories'])
|
||
|
&& $urlParams['noAccessories'] === '1'
|
||
|
&& $params['noAccessories'] = 'on';
|
||
|
|
||
|
return $params;
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
public function getName() {
|
||
|
switch($this->queriedContext) {
|
||
|
case 'Sales':
|
||
|
return 'Bad Dragon Sales';
|
||
|
case 'Clearance':
|
||
|
return 'Bad Dragon Clearance Search';
|
||
|
default:
|
||
|
return parent::getName();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function getURI() {
|
||
|
switch($this->queriedContext) {
|
||
|
case 'Sales':
|
||
|
return self::URI . 'sales';
|
||
|
case 'Clearance':
|
||
|
return $this->inputToURL();
|
||
|
default:
|
||
|
return parent::getURI();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function collectData() {
|
||
|
switch($this->queriedContext) {
|
||
|
case 'Sales':
|
||
|
$sales = json_decode(getContents(self::URI . 'api/sales'))
|
||
|
or returnServerError('Failed to query BD API');
|
||
|
|
||
|
foreach($sales as $sale) {
|
||
|
$item = array();
|
||
|
|
||
|
$item['title'] = $sale->title;
|
||
|
$item['timestamp'] = strtotime($sale->startDate);
|
||
|
|
||
|
$item['uri'] = $this->getURI() . '/' . $sale->slug;
|
||
|
|
||
|
$contentHTML = '<p><img src="' . $sale->image->url . '"></p>';
|
||
|
if(isset($sale->endDate)) {
|
||
|
$contentHTML .= '<p><b>This promotion ends on '
|
||
|
. gmdate('M j, Y \a\t g:i A T', strtotime($sale->endDate))
|
||
|
. '</b></p>';
|
||
|
} else {
|
||
|
$contentHTML .= '<p><b>This promotion never ends</b></p>';
|
||
|
}
|
||
|
$ul = false;
|
||
|
$content = json_decode($sale->content);
|
||
|
foreach($content->blocks as $block) {
|
||
|
switch($block->type) {
|
||
|
case 'header-one':
|
||
|
$contentHTML .= '<h1>' . $block->text . '</h1>';
|
||
|
break;
|
||
|
case 'header-two':
|
||
|
$contentHTML .= '<h2>' . $block->text . '</h2>';
|
||
|
break;
|
||
|
case 'header-three':
|
||
|
$contentHTML .= '<h3>' . $block->text . '</h3>';
|
||
|
break;
|
||
|
case 'unordered-list-item':
|
||
|
if(!$ul) {
|
||
|
$contentHTML .= '<ul>';
|
||
|
$ul = true;
|
||
|
}
|
||
|
$contentHTML .= '<li>' . $block->text . '</li>';
|
||
|
break;
|
||
|
default:
|
||
|
if($ul) {
|
||
|
$contentHTML .= '</ul>';
|
||
|
$ul = false;
|
||
|
}
|
||
|
$contentHTML .= '<p>' . $block->text . '</p>';
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
$item['content'] = $contentHTML;
|
||
|
|
||
|
$this->items[] = $item;
|
||
|
}
|
||
|
break;
|
||
|
case 'Clearance':
|
||
|
$toyData = json_decode(getContents($this->inputToURL(true)))
|
||
|
or returnServerError('Failed to query BD API');
|
||
|
|
||
|
$productList = json_decode(getContents(self::URI
|
||
|
. 'api/inventory-toy/product-list'))
|
||
|
or returnServerError('Failed to query BD API');
|
||
|
|
||
|
foreach($toyData->toys as $toy) {
|
||
|
$item = array();
|
||
|
|
||
|
$item['uri'] = $this->getURI()
|
||
|
. '#'
|
||
|
. $toy->id;
|
||
|
$item['timestamp'] = strtotime($toy->created);
|
||
|
|
||
|
foreach($productList as $product) {
|
||
|
if($product->sku == $toy->sku) {
|
||
|
$item['title'] = $product->name;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// images
|
||
|
$content = '<p>';
|
||
|
foreach($toy->images as $image) {
|
||
|
$content .= '<a href="'
|
||
|
. $image->fullFilename
|
||
|
. '"><img src="'
|
||
|
. $image->thumbFilename
|
||
|
. '" /></a>';
|
||
|
}
|
||
|
// price
|
||
|
$content .= '</p><p><b>Price:</b> $'
|
||
|
. $toy->price
|
||
|
// size
|
||
|
. '<br /><b>Size:</b> '
|
||
|
. $toy->size
|
||
|
// color
|
||
|
. '<br /><b>Color:</b> '
|
||
|
. $toy->color
|
||
|
// features
|
||
|
. '<br /><b>Features:</b> '
|
||
|
. ($toy->suction_cup ? 'Suction cup' : '')
|
||
|
. ($toy->suction_cup && $toy->cumtube ? ', ' : '')
|
||
|
. ($toy->cumtube ? 'Cumtube' : '')
|
||
|
. ($toy->suction_cup || $toy->cumtube ? '' : 'None');
|
||
|
// firmness
|
||
|
$firmnessTexts = array(
|
||
|
'2' => 'Extra soft',
|
||
|
'3' => 'Soft',
|
||
|
'5' => 'Medium',
|
||
|
'8' => 'Firm'
|
||
|
);
|
||
|
$firmnesses = explode('/', $toy->firmness);
|
||
|
if(count($firmnesses) === 2) {
|
||
|
$content .= '<br /><b>Firmness:</b> '
|
||
|
. $firmnessTexts[$firmnesses[0]]
|
||
|
. ', '
|
||
|
. $firmnessTexts[$firmnesses[1]];
|
||
|
} else{
|
||
|
$content .= '<br /><b>Firmness:</b> '
|
||
|
. $firmnessTexts[$firmnesses[0]];
|
||
|
}
|
||
|
// flop
|
||
|
if($toy->type === 'flop') {
|
||
|
$content .= '<br /><b>Flop reason:</b> '
|
||
|
. $toy->flop_reason;
|
||
|
}
|
||
|
$content .= '</p>';
|
||
|
$item['content'] = $content;
|
||
|
|
||
|
$enclosures = array();
|
||
|
foreach($toy->images as $image) {
|
||
|
$enclosures[] = $image->fullFilename;
|
||
|
}
|
||
|
$item['enclosures'] = $enclosures;
|
||
|
|
||
|
$categories = array();
|
||
|
$categories[] = $toy->sku;
|
||
|
$categories[] = $toy->type;
|
||
|
$categories[] = $toy->size;
|
||
|
if($toy->cumtube) {
|
||
|
$categories[] = 'cumtube';
|
||
|
}
|
||
|
if($toy->suction_cup) {
|
||
|
$categories[] = 'suction_cup';
|
||
|
}
|
||
|
$item['categories'] = $categories;
|
||
|
|
||
|
$this->items[] = $item;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private function inputToURL($api = false) {
|
||
|
$url = self::URI;
|
||
|
$url .= ($api ? 'api/inventory-toys?' : 'shop/clearance?');
|
||
|
|
||
|
// Default parameters
|
||
|
$url .= 'limit=60';
|
||
|
$url .= '&page=1';
|
||
|
$url .= '&sort[field]=created';
|
||
|
$url .= '&sort[direction]=desc';
|
||
|
|
||
|
// Product types
|
||
|
$url .= ($this->getInput('ready_made') ? '&type[]=ready_made' : '');
|
||
|
$url .= ($this->getInput('flop') ? '&type[]=flop' : '');
|
||
|
|
||
|
// Product names
|
||
|
foreach(array_filter(explode(',', $this->getInput('skus'))) as $sku) {
|
||
|
$url .= '&skus[]=' . urlencode(trim($sku));
|
||
|
}
|
||
|
|
||
|
// Size
|
||
|
$url .= ($this->getInput('onesize') ? '&sizes[]=onesize' : '');
|
||
|
$url .= ($this->getInput('mini') ? '&sizes[]=mini' : '');
|
||
|
$url .= ($this->getInput('small') ? '&sizes[]=small' : '');
|
||
|
$url .= ($this->getInput('medium') ? '&sizes[]=medium' : '');
|
||
|
$url .= ($this->getInput('large') ? '&sizes[]=large' : '');
|
||
|
$url .= ($this->getInput('extralarge') ? '&sizes[]=extralarge' : '');
|
||
|
|
||
|
// Category
|
||
|
$url .= ($this->getInput('category') ? '&category='
|
||
|
. urlencode($this->getInput('category')) : '');
|
||
|
|
||
|
// Firmness
|
||
|
if($api) {
|
||
|
$url .= ($this->getInput('soft') ? '&firmnessValues[]=3' : '');
|
||
|
$url .= ($this->getInput('med_firm') ? '&firmnessValues[]=5' : '');
|
||
|
$url .= ($this->getInput('firm') ? '&firmnessValues[]=8' : '');
|
||
|
if($this->getInput('split')) {
|
||
|
$url .= '&firmnessValues[]=3/5';
|
||
|
$url .= '&firmnessValues[]=3/8';
|
||
|
$url .= '&firmnessValues[]=8/3';
|
||
|
$url .= '&firmnessValues[]=5/8';
|
||
|
$url .= '&firmnessValues[]=8/5';
|
||
|
}
|
||
|
} else{
|
||
|
$url .= ($this->getInput('soft') ? '&firmnessValues[]=soft' : '');
|
||
|
$url .= ($this->getInput('med_firm') ? '&firmnessValues[]=medium' : '');
|
||
|
$url .= ($this->getInput('firm') ? '&firmnessValues[]=firm' : '');
|
||
|
$url .= ($this->getInput('split') ? '&firmnessValues[]=split' : '');
|
||
|
}
|
||
|
|
||
|
// Price
|
||
|
$url .= ($this->getInput('maxprice') ? '&price[max]='
|
||
|
. $this->getInput('maxprice') : '&price[max]=300');
|
||
|
$url .= ($this->getInput('minprice') ? '&price[min]='
|
||
|
. $this->getInput('minprice') : '&price[min]=0');
|
||
|
|
||
|
// Features
|
||
|
$url .= ($this->getInput('cumtube') ? '&cumtube=1' : '');
|
||
|
$url .= ($this->getInput('suctionCup') ? '&suctionCup=1' : '');
|
||
|
$url .= ($this->getInput('noAccessories') ? '&noAccessories=1' : '');
|
||
|
|
||
|
return $url;
|
||
|
}
|
||
|
}
|