1
0
mirror of https://github.com/RSS-Bridge/rss-bridge.git synced 2025-08-24 09:02:59 +02:00

Compare commits

..

16 Commits

Author SHA1 Message Date
logmanoriginal
ae2c35c18a [Configuration] Bump version to 2019-03-17 2019-03-17 20:28:55 +01:00
logmanoriginal
5b80bcaa04 [README] Update list of contributors
The list acutally didn't change, but it's sorted properly now
(thanks to em92 for the suggestion)
2019-03-17 20:28:15 +01:00
fulmeek
5ea985164e [OneFortuneADayBridge] use date in UTC for seed (#1059) 2019-03-14 19:44:36 +01:00
fulmeek
696afa96d3 [BakaUpdatesMangaReleasesBridge] filter title and groups (#1058)
Baka-Updates Manga uses an asterisk (*) to denote series information have
been updated within the last 24 hours. This is not helpful in a feed.
2019-03-14 19:43:00 +01:00
Roliga
326a707739 [SoundcloudBridge] Update API key (#1062) 2019-03-12 13:29:11 +01:00
LogMANOriginal
1ac66b3fdc [README] Add sqlite3 as requirement for SQLiteCache 2019-03-02 19:42:40 +01:00
logmanoriginal
f450b2e118 [SQLiteCache] Check sqlite3 extension in __construct
Checks if the sqlite3 extension is loaded and throws an error
if it's missing.
2019-03-02 19:33:44 +01:00
sysadminstory
688c950916 [DealabsBridge] Patch unparsable Deal date (#1053)
In case of a unparsable date, the text to DateTime object failed, and
this resulted to a Fatal error while using this DateTime object . To
prvent this fatal error, if the date parsing failse, then a DateTime
object is created with the actual date.
2019-03-02 19:10:57 +01:00
fulmeek
9d85b951f7 [BakaUpdatesMangaReleasesBridge] rework to parse new layout (#1052)
* rework to parse new layout
* skip incomplete rows

The last row could have fewer columns if there are less rows than the items limit. This usually should not happen, though.

* use constant for skipping
2019-03-02 19:09:16 +01:00
somini
dac685b887 [ComboiosDePortugalBridge] Add new bridge (#1049) 2019-03-02 19:05:23 +01:00
ORelio
d37f0c14a0 [LeMondeInformatique] Handle special articles (#1039)
Fix content extraction for special article compiling previous articles
2019-03-02 19:03:29 +01:00
Ryan Liptak
b96c25a3af [BandcampBridge] Update to use newer POST API (#1045)
Bandcamp tags pages have a new layout and now use a POST API endpoint to view each page of releases.

Output of this bridge should be almost the same as before, with a few small improvements:
- Small album image in 'content', larger album image in 'enclosures'
- RSS item titles/authors are appended with the releaser in parentheses if the artist name and the releaser are different (i.e. Record Label's Bandcamp releases an album called Bar by the band named Foo, it would get the title 'Foo - Bar (Record Label)' and the author 'Foo (Record Label)')
2019-02-24 12:08:34 +01:00
fulmeek
dc1b1b13cc [SQLiteCache] Implement cache based on SQLite 3 (#1035) 2019-02-24 12:04:27 +01:00
logmanoriginal
e3588f62bd [Cache] Fix cache types ending on 'cache' are not detected correctly
References #1000
2019-02-24 11:56:43 +01:00
fulmeek
958ba815c7 [OneFortuneADayBridge] Add lucky number feature (#1038) 2019-02-24 11:49:17 +01:00
somini
3d24596a52 [AsahiShimbunAJW] Add new Bridge (#1036) 2019-02-24 11:47:29 +01:00
13 changed files with 325 additions and 91 deletions

View File

@@ -66,6 +66,7 @@ RSS-Bridge requires PHP 5.6 or higher with following extensions enabled:
- [`simplexml`](https://secure.php.net/manual/en/book.simplexml.php)
- [`curl`](https://secure.php.net/manual/en/book.curl.php)
- [`json`](https://secure.php.net/manual/en/book.json.php)
- [`sqlite3`](http://php.net/manual/en/book.sqlite3.php) (only when using SQLiteCache)
Find more information on our [Wiki](https://github.com/rss-bridge/rss-bridge/wiki)
@@ -111,41 +112,16 @@ https://gist.github.com/LogMANOriginal/da00cd1e5f0ca31cef8e193509b17fd8
-->
* [16mhz](https://github.com/16mhz)
* [adamchainz](https://github.com/adamchainz)
* [Ahiles3005](https://github.com/Ahiles3005)
* [Albirew](https://github.com/Albirew)
* [aledeg](https://github.com/aledeg)
* [alexAubin](https://github.com/alexAubin)
* [AmauryCarrade](https://github.com/AmauryCarrade)
* [AntoineTurmel](https://github.com/AntoineTurmel)
* [ArthurHoaro](https://github.com/ArthurHoaro)
* [Astalaseven](https://github.com/Astalaseven)
* [Astyan-42](https://github.com/Astyan-42)
* [Daiyousei](https://github.com/Daiyousei)
* [Djuuu](https://github.com/Djuuu)
* [Draeli](https://github.com/Draeli)
* [EtienneM](https://github.com/EtienneM)
* [Frenzie](https://github.com/Frenzie)
* [Ginko-Aloe](https://github.com/Ginko-Aloe)
* [Glandos](https://github.com/Glandos)
* [GregThib](https://github.com/GregThib)
* [Grummfy](https://github.com/Grummfy)
* [JackNUMBER](https://github.com/JackNUMBER)
* [JeremyRand](https://github.com/JeremyRand)
* [Jocker666z](https://github.com/Jocker666z)
* [LogMANOriginal](https://github.com/LogMANOriginal)
* [MonsieurPoutounours](https://github.com/MonsieurPoutounours)
* [Nono-m0le](https://github.com/Nono-m0le)
* [ORelio](https://github.com/ORelio)
* [PaulVayssiere](https://github.com/PaulVayssiere)
* [Piranhaplant](https://github.com/Piranhaplant)
* [Riduidel](https://github.com/Riduidel)
* [Roliga](https://github.com/Roliga)
* [Strubbl](https://github.com/Strubbl)
* [TheRadialActive](https://github.com/TheRadialActive)
* [TwizzyDizzy](https://github.com/TwizzyDizzy)
* [WalterBarrett](https://github.com/WalterBarrett)
* [ZeNairolf](https://github.com/ZeNairolf)
* [adamchainz](https://github.com/adamchainz)
* [aledeg](https://github.com/aledeg)
* [alexAubin](https://github.com/alexAubin)
* [az5he6ch](https://github.com/az5he6ch)
* [b1nj](https://github.com/b1nj)
* [benasse](https://github.com/benasse)
@@ -156,23 +132,37 @@ https://gist.github.com/LogMANOriginal/da00cd1e5f0ca31cef8e193509b17fd8
* [corenting](https://github.com/corenting)
* [couraudt](https://github.com/couraudt)
* [da2x](https://github.com/da2x)
* [Daiyousei](https://github.com/Daiyousei)
* [disk0x](https://github.com/disk0x)
* [eMerzh](https://github.com/eMerzh)
* [Djuuu](https://github.com/Djuuu)
* [Draeli](https://github.com/Draeli)
* [em92](https://github.com/em92)
* [eMerzh](https://github.com/eMerzh)
* [EtienneM](https://github.com/EtienneM)
* [fluffy-critter](https://github.com/fluffy-critter)
* [Frenzie](https://github.com/Frenzie)
* [fulmeek](https://github.com/fulmeek)
* [Ginko-Aloe](https://github.com/Ginko-Aloe)
* [Glandos](https://github.com/Glandos)
* [GregThib](https://github.com/GregThib)
* [griffaurel](https://github.com/griffaurel)
* [Grummfy](https://github.com/Grummfy)
* [hunhejj](https://github.com/hunhejj)
* [j0k3r](https://github.com/j0k3r)
* [JackNUMBER](https://github.com/JackNUMBER)
* [jdigilio](https://github.com/jdigilio)
* [JeremyRand](https://github.com/JeremyRand)
* [Jocker666z](https://github.com/Jocker666z)
* [klimplant](https://github.com/klimplant)
* [kranack](https://github.com/kranack)
* [kraoc](https://github.com/kraoc)
* [l1n](https://github.com/l1n)
* [laBecasse](https://github.com/laBecasse)
* [lagaisse](https://github.com/lagaisse)
* [lalannev](https://github.com/lalannev)
* [ldidry](https://github.com/ldidry)
* [Limero](https://github.com/Limero)
* [LogMANOriginal](https://github.com/LogMANOriginal)
* [lorenzos](https://github.com/lorenzos)
* [m0zes](https://github.com/m0zes)
* [matthewseal](https://github.com/matthewseal)
@@ -182,29 +172,40 @@ https://gist.github.com/LogMANOriginal/da00cd1e5f0ca31cef8e193509b17fd8
* [metaMMA](https://github.com/metaMMA)
* [mickael-bertrand](https://github.com/mickael-bertrand)
* [mitsukarenai](https://github.com/mitsukarenai)
* [MonsieurPoutounours](https://github.com/MonsieurPoutounours)
* [mr-flibble](https://github.com/mr-flibble)
* [mro](https://github.com/mro)
* [mxmehl](https://github.com/mxmehl)
* [nel50n](https://github.com/nel50n)
* [niawag](https://github.com/niawag)
* [Nova](https://github.com/l1n)
* [Nono-m0le](https://github.com/Nono-m0le)
* [ORelio](https://github.com/ORelio)
* [PaulVayssiere](https://github.com/PaulVayssiere)
* [pellaeon](https://github.com/pellaeon)
* [Piranhaplant](https://github.com/Piranhaplant)
* [pit-fgfjiudghdf](https://github.com/pit-fgfjiudghdf)
* [pitchoule](https://github.com/pitchoule)
* [pmaziere](https://github.com/pmaziere)
* [prysme01](https://github.com/prysme01)
* [quentinus95](https://github.com/quentinus95)
* [qwertygc](https://github.com/qwertygc)
* [regisenguehard](https://github.com/regisenguehard)
* [Riduidel](https://github.com/Riduidel)
* [rogerdc](https://github.com/rogerdc)
* [Roliga](https://github.com/Roliga)
* [sebsauvage](https://github.com/sebsauvage)
* [somini](https://github.com/somini)
* [squeek502](https://github.com/squeek502)
* [Strubbl](https://github.com/Strubbl)
* [sublimz](https://github.com/sublimz)
* [sysadminstory](https://github.com/sysadminstory)
* [tameroski](https://github.com/tameroski)
* [teromene](https://github.com/teromene)
* [TheRadialActive](https://github.com/TheRadialActive)
* [triatic](https://github.com/triatic)
* [WalterBarrett](https://github.com/WalterBarrett)
* [wtuuju](https://github.com/wtuuju)
* [yardenac](https://github.com/yardenac)
* [ZeNairolf](https://github.com/ZeNairolf)
Licenses
===

View File

@@ -0,0 +1,72 @@
<?php
class AsahiShimbunAJWBridge extends BridgeAbstract {
const NAME = 'Asahi Shimbun AJW';
const BASE_URI = 'http://www.asahi.com';
const URI = self::BASE_URI . '/ajw/';
const DESCRIPTION = 'Asahi Shimbun - Asia & Japan Watch';
const MAINTAINER = 'somini';
const PARAMETERS = array(
array(
'section' => array(
'type' => 'list',
'name' => 'Section',
'values' => array(
'Japan » Social Affairs' => 'japan/social',
'Japan » People' => 'japan/people',
'Japan » 3/11 Disaster' => 'japan/0311disaster',
'Japan » Sci & Tech' => 'japan/sci_tech',
'Politics' => 'politics',
'Business' => 'business',
'Culture » Style' => 'culture/style',
'Culture » Movies' => 'culture/movies',
'Culture » Manga & Anime' => 'culture/manga_anime',
'Asia » China' => 'asia/china',
'Asia » Korean Peninsula' => 'asia/korean_peninsula',
'Asia » Around Asia' => 'asia/around_asia',
'Opinion » Editorial' => 'opinion/editorial',
'Opinion » Vox Populi' => 'opinion/vox',
),
'defaultValue' => 'Politics',
)
)
);
private function getSectionURI($section) {
return self::getURI() . $section . '/';
}
public function collectData() {
$html = getSimpleHTMLDOM($this->getSectionURI($this->getInput('section')))
or returnServerError('Could not load content');
foreach($html->find('#MainInner li a') as $element) {
if ($element->parent()->class == 'HeadlineTopImage-S') {
Debug::log('Skip Headline, it is repeated below');
continue;
}
$item = array();
$item['uri'] = self::BASE_URI . $element->href;
$e_lead = $element->find('span.Lead', 0);
if ($e_lead) {
$item['content'] = $e_lead->innertext;
$e_lead->outertext = '';
} else {
$item['content'] = $element->innertext;
}
$e_date = $element->find('span.EnDate', 0);
if ($e_date) {
$item['timestamp'] = strtotime($e_date->innertext);
$e_date->outertext = '';
}
$e_video = $element->find('span.EnVideo', 0);
if ($e_video) {
$e_video->outertext = '';
$element->innertext = "VIDEO: $element->innertext";
}
$item['title'] = $element->innertext;
$this->items[] = $item;
}
}
}

View File

@@ -12,6 +12,7 @@ class BakaUpdatesMangaReleasesBridge extends BridgeAbstract {
'exampleValue' => '12345'
)
));
const LIMIT_COLS = 5;
const LIMIT_ITEMS = 10;
private $feedName = '';
@@ -20,21 +21,21 @@ class BakaUpdatesMangaReleasesBridge extends BridgeAbstract {
$html = getSimpleHTMLDOM($this->getURI())
or returnServerError('Series not found');
$objTitle = $html->find('td[class="text pad"]', 1);
if ($objTitle)
$this->feedName = $objTitle->plaintext;
$itemlist = $html->find('td#main_content table table table tr');
if (!$itemlist)
// content is an unstructured pile of divs, ugly to parse
$cols = $html->find('div#main_content div.row > div.text');
if (!$cols)
returnServerError('No releases');
$limit = self::LIMIT_ITEMS;
foreach($itemlist as $element) {
$cols = $element->find('td[class="text pad"]');
if (!$cols)
continue;
if ($limit <= 0)
break;
$rows = array_slice(
array_chunk($cols, self::LIMIT_COLS), 0, self::LIMIT_ITEMS
);
if (isset($rows[0][1])) {
$this->feedName = $this->filterHTML($rows[0][1]->plaintext);
}
foreach($rows as $cols) {
if (count($cols) < self::LIMIT_COLS) continue;
$item = array();
$title = array();
@@ -47,8 +48,8 @@ class BakaUpdatesMangaReleasesBridge extends BridgeAbstract {
$objTitle = $cols[1];
if ($objTitle) {
$title[] = html_entity_decode($objTitle->plaintext);
$item['content'] .= '<p>Series: ' . $objTitle->innertext . '</p>';
$title[] = $this->filterHTML($objTitle->plaintext);
$item['content'] .= '<p>Series: ' . $this->filterText($objTitle->innertext) . '</p>';
}
$objVolume = $cols[2];
@@ -61,18 +62,15 @@ class BakaUpdatesMangaReleasesBridge extends BridgeAbstract {
$objAuthor = $cols[4];
if ($objAuthor && !empty($objAuthor->plaintext)) {
$item['author'] = html_entity_decode($objAuthor->plaintext);
$item['content'] .= '<p>Groups: ' . $objAuthor->innertext . '</p>';
$item['author'] = $this->filterHTML($objAuthor->plaintext);
$item['content'] .= '<p>Groups: ' . $this->filterText($objAuthor->innertext) . '</p>';
}
$item['title'] = implode(' ', $title);
$item['uri'] = $this->getURI() . '#' . hash('sha1', $item['title']);
$item['title'] = implode(' ', $title);
$item['uri'] = $this->getURI();
$item['uid'] = hash('sha1', $item['title']);
$this->items[] = $item;
if(count($this->items) >= $limit) {
break;
}
}
}
@@ -90,4 +88,12 @@ class BakaUpdatesMangaReleasesBridge extends BridgeAbstract {
}
return parent::getName();
}
private function filterText($text) {
return rtrim($text, '*');
}
private function filterHTML($text) {
return $this->filterText(html_entity_decode($text));
}
}

View File

@@ -13,48 +13,72 @@ class BandcampBridge extends BridgeAbstract {
'required' => true
)
));
const IMGURI = 'https://f4.bcbits.com/';
const IMGSIZE_300PX = 23;
const IMGSIZE_700PX = 16;
public function getIcon() {
return 'https://s4.bcbits.com/img/bc_favicon.ico';
}
public function collectData(){
$html = getSimpleHTMLDOM($this->getURI())
or returnServerError('No results for this query.');
$url = self::URI . 'api/hub/1/dig_deeper';
$data = $this->buildRequestJson();
$header = array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data)
);
$opts = array(
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => $data
);
$content = getContents($url, $header, $opts)
or returnServerError('Could not complete request to: ' . $url);
foreach($html->find('li.item') as $release) {
$script = $release->find('div.art', 0)->getAttribute('onclick');
$uri = ltrim($script, "return 'url(");
$uri = rtrim($uri, "')");
$json = json_decode($content);
$item = array();
$item['author'] = $release->find('div.itemsubtext', 0)->plaintext
. ' - '
. $release->find('div.itemtext', 0)->plaintext;
if ($json->ok !== true) {
returnServerError('Invalid response');
}
$item['title'] = $release->find('div.itemsubtext', 0)->plaintext
. ' - '
. $release->find('div.itemtext', 0)->plaintext;
foreach ($json->items as $entry) {
$url = $entry->tralbum_url;
$artist = $entry->artist;
$title = $entry->title;
// e.g. record label is the releaser, but not the artist
$releaser = $entry->band_name !== $entry->artist ? $entry->band_name : null;
$item['content'] = '<img src="'
. $uri
. '"/><br/>'
. $release->find('div.itemsubtext', 0)->plaintext
. ' - '
. $release->find('div.itemtext', 0)->plaintext;
$full_title = $artist . ' - ' . $title;
$full_artist = $artist;
if (isset($releaser)) {
$full_title .= ' (' . $releaser . ')';
$full_artist .= ' (' . $releaser . ')';
}
$small_img = $this->getImageUrl($entry->art_id, self::IMGSIZE_300PX);
$img = $this->getImageUrl($entry->art_id, self::IMGSIZE_700PX);
$item['id'] = $release->find('a', 0)->getAttribute('href');
$item['uri'] = $release->find('a', 0)->getAttribute('href');
$item = array(
'uri' => $url,
'author' => $full_artist,
'title' => $full_title
);
$item['content'] = "<img src='$small_img' /><br/>$full_title";
$item['enclosures'] = array($img);
$this->items[] = $item;
}
}
public function getURI(){
if(!is_null($this->getInput('tag'))) {
return self::URI . 'tag/' . urlencode($this->getInput('tag')) . '?sort_field=date';
}
private function buildRequestJson(){
$requestJson = array(
'tag' => $this->getInput('tag'),
'page' => 1,
'sort' => 'date'
);
return json_encode($requestJson);
}
return parent::getURI();
private function getImageUrl($id, $size){
return self::IMGURI . 'img/a' . $id . '_' . $size . '.jpg';
}
public function getName(){

View File

@@ -0,0 +1,22 @@
<?php
class ComboiosDePortugalBridge extends BridgeAbstract {
const NAME = 'CP | Avisos';
const BASE_URI = 'https://www.cp.pt';
const URI = self::BASE_URI . '/passageiros/pt';
const DESCRIPTION = 'Comboios de Portugal | Avisos';
const MAINTAINER = 'somini';
public function collectData() {
$html = getSimpleHTMLDOM($this->getURI() . '/consultar-horarios/avisos')
or returnServerError('Could not load content');
foreach($html->find('.warnings-table a') as $element) {
$item = array();
$item['title'] = $element->innertext;
$item['uri'] = self::BASE_URI . $element->href;
$this->items[] = $item;
}
}
}

View File

@@ -1376,8 +1376,11 @@ class PepperBridgeAbstract extends BridgeAbstract {
// Add the Hour and minutes
$date_str .= ' 00:00';
$date = DateTime::createFromFormat('j F Y H:i', $date_str);
// In some case, the date is not recognized : as a workaround the actual date is taken
if($date === false) {
$date = new DateTime();
}
return $date->getTimestamp();
}

View File

@@ -20,12 +20,13 @@ class LeMondeInformatiqueBridge extends FeedExpander {
str_replace(
'/grande/',
'/petite/',
$article_html->find('.article-image', 0)->find('img', 0)->src
$article_html->find('.article-image > img, figure > img', 0)->src
)
);
//No response header sets the encoding, explicit conversion is needed or subsequent xml_encode() will fail
$item['content'] = utf8_encode($this->cleanArticle($article_html->find('div.col-primary', 0)->innertext));
$content_node = $article_html->find('div.col-primary, div.col-sm-9', 0);
$item['content'] = utf8_encode($this->cleanArticle($content_node->innertext));
$item['author'] = utf8_encode($article_html->find('div.author-infos', 0)->find('b', 0)->plaintext);
return $item;

View File

@@ -35,25 +35,33 @@ class OneFortuneADayBridge extends BridgeAbstract {
'23:00' => 23,
),
'defaultValue' => 5
),
'lucky' => array(
'name' => 'Lucky number (optional)',
'type' => 'text'
)
));
const LIMIT_ITEMS = 7;
const DAY_SECS = 86400;
public function getDescription(){
return self::DESCRIPTION . '<br/>Set a lucky number to get your personal quotes, like ' . mt_rand();
}
public function collectData() {
$time = gmmktime((int)$this->getInput('time'), 0, 0);
if ($time > time())
$time -= self::DAY_SECS;
for ($i = self::LIMIT_ITEMS; $i > 0; --$i) {
$seed = date('Ymd', $time);
$seed = gmdate('Ymd', $time) . $this->getInput('lucky');
$quote = $this->getQuote($seed);
$item['title'] = strftime('%A, %x', $time);
$item['content'] = htmlentities($quote, ENT_QUOTES, 'UTF-8');
$item['timestamp'] = $time;
$item['uri'] = 'urn:sha1:' . hash('sha1', $seed);
$item['uid'] = hash('sha1', $seed);
$this->items[] = $item;

View File

@@ -14,7 +14,7 @@ class SoundCloudBridge extends BridgeAbstract {
)
));
const CLIENT_ID = '4jkoEFmZEDaqjwJ9Eih4ATNhcH3vMVfp';
const CLIENT_ID = 'W0KEWWILAjDiRH89X0jpwzuq6rbSK08R';
public function collectData(){

99
caches/SQLiteCache.php Normal file
View File

@@ -0,0 +1,99 @@
<?php
/**
* Cache based on SQLite 3 <https://www.sqlite.org>
*/
class SQLiteCache implements CacheInterface {
protected $path;
protected $param;
private $db = null;
public function __construct() {
if (!extension_loaded('sqlite3'))
die('"sqlite3" extension not loaded. Please check "php.ini"');
$file = PATH_CACHE . 'cache.sqlite';
if (!is_file($file)) {
$this->db = new SQLite3($file);
$this->db->enableExceptions(true);
$this->db->exec("CREATE TABLE storage ('key' BLOB PRIMARY KEY, 'value' BLOB, 'updated' INTEGER)");
} else {
$this->db = new SQLite3($file);
$this->db->enableExceptions(true);
}
$this->db->busyTimeout(5000);
}
public function loadData(){
$Qselect = $this->db->prepare('SELECT value FROM storage WHERE key = :key');
$Qselect->bindValue(':key', $this->getCacheKey());
$result = $Qselect->execute();
if ($result instanceof SQLite3Result) {
$data = $result->fetchArray(SQLITE3_ASSOC);
if (isset($data['value'])) {
return unserialize($data['value']);
}
}
return null;
}
public function saveData($datas){
$Qupdate = $this->db->prepare('INSERT OR REPLACE INTO storage (key, value, updated) VALUES (:key, :value, :updated)');
$Qupdate->bindValue(':key', $this->getCacheKey());
$Qupdate->bindValue(':value', serialize($datas));
$Qupdate->bindValue(':updated', time());
$Qupdate->execute();
return $this;
}
public function getTime(){
$Qselect = $this->db->prepare('SELECT updated FROM storage WHERE key = :key');
$Qselect->bindValue(':key', $this->getCacheKey());
$result = $Qselect->execute();
if ($result instanceof SQLite3Result) {
$data = $result->fetchArray(SQLITE3_ASSOC);
if (isset($data['updated'])) {
return $data['updated'];
}
}
return false;
}
public function purgeCache($duration){
$Qdelete = $this->db->prepare('DELETE FROM storage WHERE updated < :expired');
$Qdelete->bindValue(':expired', time() - $duration);
$Qdelete->execute();
}
/**
* Set cache path
* @return self
*/
public function setPath($path){
$this->path = $path;
return $this;
}
/**
* Set HTTP GET parameters
* @return self
*/
public function setParameters(array $param){
$this->param = array_map('strtolower', $param);
return $this;
}
////////////////////////////////////////////////////////////////////////////
protected function getCacheKey(){
if(is_null($this->param)) {
throw new \Exception('Call "setParameters" first!');
}
return hash('sha1', $this->path . http_build_query($this->param), true);
}
}

View File

@@ -193,7 +193,7 @@ class Cache {
}
// Trim trailing 'Cache' if exists
if(preg_match('/(.+)(?:Cache)/i', $name, $matches)) {
if(preg_match('/(.+)(?:Cache)$/i', $name, $matches)) {
$name = $matches[1];
}

View File

@@ -28,7 +28,7 @@ final class Configuration {
*
* @todo Replace this property by a constant.
*/
public static $VERSION = 'dev.2019-02-19';
public static $VERSION = '2019-03-17';
/**
* Holds the configuration data.

View File

@@ -5,7 +5,6 @@ use PHPUnit\Framework\TestCase;
class CacheImplementationTest extends TestCase {
private $class;
private $obj;
/**
* @dataProvider dataCachesProvider
@@ -22,7 +21,7 @@ class CacheImplementationTest extends TestCase {
*/
public function testClassType($path) {
$this->setCache($path);
$this->assertInstanceOf(CacheInterface::class, $this->obj);
$this->assertTrue(is_subclass_of($this->class, CacheInterface::class), 'class must be subclass of CacheInterface');
}
////////////////////////////////////////////////////////////////////////////
@@ -39,6 +38,5 @@ class CacheImplementationTest extends TestCase {
require_once $path;
$this->class = basename($path, '.php');
$this->assertTrue(class_exists($this->class), 'class ' . $this->class . ' doesn\'t exist');
$this->obj = new $this->class();
}
}