Make FeedBuilder instance creation independant of the request stack
This commit is contained in:
parent
c56a540c6e
commit
f4929b1188
3 changed files with 87 additions and 129 deletions
|
@ -43,21 +43,9 @@ class FeedBuilder
|
|||
*/
|
||||
protected $formatter;
|
||||
|
||||
/**
|
||||
* @var string RSS or ATOM feed.
|
||||
*/
|
||||
protected $feedType;
|
||||
|
||||
/**
|
||||
* @var array $_SERVER
|
||||
*/
|
||||
/** @var mixed[] $_SERVER */
|
||||
protected $serverInfo;
|
||||
|
||||
/**
|
||||
* @var array $_GET
|
||||
*/
|
||||
protected $userInput;
|
||||
|
||||
/**
|
||||
* @var boolean True if the user is currently logged in, false otherwise.
|
||||
*/
|
||||
|
@ -77,7 +65,6 @@ class FeedBuilder
|
|||
* @var string server locale.
|
||||
*/
|
||||
protected $locale;
|
||||
|
||||
/**
|
||||
* @var DateTime Latest item date.
|
||||
*/
|
||||
|
@ -88,37 +75,36 @@ class FeedBuilder
|
|||
*
|
||||
* @param BookmarkServiceInterface $linkDB LinkDB instance.
|
||||
* @param BookmarkFormatter $formatter instance.
|
||||
* @param string $feedType Type of feed.
|
||||
* @param array $serverInfo $_SERVER.
|
||||
* @param array $userInput $_GET.
|
||||
* @param boolean $isLoggedIn True if the user is currently logged in, false otherwise.
|
||||
*/
|
||||
public function __construct($linkDB, $formatter, $feedType, $serverInfo, $userInput, $isLoggedIn)
|
||||
public function __construct($linkDB, $formatter, array $serverInfo, $isLoggedIn)
|
||||
{
|
||||
$this->linkDB = $linkDB;
|
||||
$this->formatter = $formatter;
|
||||
$this->feedType = $feedType;
|
||||
$this->serverInfo = $serverInfo;
|
||||
$this->userInput = $userInput;
|
||||
$this->isLoggedIn = $isLoggedIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build data for feed templates.
|
||||
*
|
||||
* @param string $feedType Type of feed (RSS/ATOM).
|
||||
* @param array $userInput $_GET.
|
||||
*
|
||||
* @return array Formatted data for feeds templates.
|
||||
*/
|
||||
public function buildData()
|
||||
public function buildData(string $feedType, ?array $userInput)
|
||||
{
|
||||
// Search for untagged bookmarks
|
||||
if (isset($this->userInput['searchtags']) && empty($this->userInput['searchtags'])) {
|
||||
$this->userInput['searchtags'] = false;
|
||||
if (isset($this->userInput['searchtags']) && empty($userInput['searchtags'])) {
|
||||
$userInput['searchtags'] = false;
|
||||
}
|
||||
|
||||
// Optionally filter the results:
|
||||
$linksToDisplay = $this->linkDB->search($this->userInput);
|
||||
$linksToDisplay = $this->linkDB->search($userInput);
|
||||
|
||||
$nblinksToDisplay = $this->getNbLinks(count($linksToDisplay));
|
||||
$nblinksToDisplay = $this->getNbLinks(count($linksToDisplay), $userInput);
|
||||
|
||||
// Can't use array_keys() because $link is a LinkDB instance and not a real array.
|
||||
$keys = array();
|
||||
|
@ -130,11 +116,11 @@ public function buildData()
|
|||
$this->formatter->addContextData('index_url', $pageaddr);
|
||||
$linkDisplayed = array();
|
||||
for ($i = 0; $i < $nblinksToDisplay && $i < count($keys); $i++) {
|
||||
$linkDisplayed[$keys[$i]] = $this->buildItem($linksToDisplay[$keys[$i]], $pageaddr);
|
||||
$linkDisplayed[$keys[$i]] = $this->buildItem($feedType, $linksToDisplay[$keys[$i]], $pageaddr);
|
||||
}
|
||||
|
||||
$data['language'] = $this->getTypeLanguage();
|
||||
$data['last_update'] = $this->getLatestDateFormatted();
|
||||
$data['language'] = $this->getTypeLanguage($feedType);
|
||||
$data['last_update'] = $this->getLatestDateFormatted($feedType);
|
||||
$data['show_dates'] = !$this->hideDates || $this->isLoggedIn;
|
||||
// Remove leading slash from REQUEST_URI.
|
||||
$data['self_link'] = escape(server_url($this->serverInfo))
|
||||
|
@ -146,45 +132,6 @@ public function buildData()
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a feed item (one per shaare).
|
||||
*
|
||||
* @param Bookmark $link Single link array extracted from LinkDB.
|
||||
* @param string $pageaddr Index URL.
|
||||
*
|
||||
* @return array Link array with feed attributes.
|
||||
*/
|
||||
protected function buildItem($link, $pageaddr)
|
||||
{
|
||||
$data = $this->formatter->format($link);
|
||||
$data['guid'] = $pageaddr . '?' . $data['shorturl'];
|
||||
if ($this->usePermalinks === true) {
|
||||
$permalink = '<a href="'. $data['url'] .'" title="'. t('Direct link') .'">'. t('Direct link') .'</a>';
|
||||
} else {
|
||||
$permalink = '<a href="'. $data['guid'] .'" title="'. t('Permalink') .'">'. t('Permalink') .'</a>';
|
||||
}
|
||||
$data['description'] .= PHP_EOL . PHP_EOL . '<br>— ' . $permalink;
|
||||
|
||||
$data['pub_iso_date'] = $this->getIsoDate($data['created']);
|
||||
|
||||
// atom:entry elements MUST contain exactly one atom:updated element.
|
||||
if (!empty($link->getUpdated())) {
|
||||
$data['up_iso_date'] = $this->getIsoDate($data['updated'], DateTime::ATOM);
|
||||
} else {
|
||||
$data['up_iso_date'] = $this->getIsoDate($data['created'], DateTime::ATOM);
|
||||
}
|
||||
|
||||
// Save the more recent item.
|
||||
if (empty($this->latestDate) || $this->latestDate < $data['created']) {
|
||||
$this->latestDate = $data['created'];
|
||||
}
|
||||
if (!empty($data['updated']) && $this->latestDate < $data['updated']) {
|
||||
$this->latestDate = $data['updated'];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this to true to use permalinks instead of direct bookmarks.
|
||||
*
|
||||
|
@ -215,22 +162,64 @@ public function setLocale($locale)
|
|||
$this->locale = strtolower($locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a feed item (one per shaare).
|
||||
*
|
||||
* @param string $feedType Type of feed (RSS/ATOM).
|
||||
* @param Bookmark $link Single link array extracted from LinkDB.
|
||||
* @param string $pageaddr Index URL.
|
||||
*
|
||||
* @return array Link array with feed attributes.
|
||||
*/
|
||||
protected function buildItem(string $feedType, $link, $pageaddr)
|
||||
{
|
||||
$data = $this->formatter->format($link);
|
||||
$data['guid'] = $pageaddr . '?' . $data['shorturl'];
|
||||
if ($this->usePermalinks === true) {
|
||||
$permalink = '<a href="'. $data['url'] .'" title="'. t('Direct link') .'">'. t('Direct link') .'</a>';
|
||||
} else {
|
||||
$permalink = '<a href="'. $data['guid'] .'" title="'. t('Permalink') .'">'. t('Permalink') .'</a>';
|
||||
}
|
||||
$data['description'] .= PHP_EOL . PHP_EOL . '<br>— ' . $permalink;
|
||||
|
||||
$data['pub_iso_date'] = $this->getIsoDate($feedType, $data['created']);
|
||||
|
||||
// atom:entry elements MUST contain exactly one atom:updated element.
|
||||
if (!empty($link->getUpdated())) {
|
||||
$data['up_iso_date'] = $this->getIsoDate($feedType, $data['updated'], DateTime::ATOM);
|
||||
} else {
|
||||
$data['up_iso_date'] = $this->getIsoDate($feedType, $data['created'], DateTime::ATOM);
|
||||
}
|
||||
|
||||
// Save the more recent item.
|
||||
if (empty($this->latestDate) || $this->latestDate < $data['created']) {
|
||||
$this->latestDate = $data['created'];
|
||||
}
|
||||
if (!empty($data['updated']) && $this->latestDate < $data['updated']) {
|
||||
$this->latestDate = $data['updated'];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the language according to the feed type, based on the locale:
|
||||
*
|
||||
* - RSS format: en-us (default: 'en-en').
|
||||
* - ATOM format: fr (default: 'en').
|
||||
*
|
||||
* @param string $feedType Type of feed (RSS/ATOM).
|
||||
*
|
||||
* @return string The language.
|
||||
*/
|
||||
public function getTypeLanguage()
|
||||
protected function getTypeLanguage(string $feedType)
|
||||
{
|
||||
// Use the locale do define the language, if available.
|
||||
if (!empty($this->locale) && preg_match('/^\w{2}[_\-]\w{2}/', $this->locale)) {
|
||||
$length = ($this->feedType === self::$FEED_RSS) ? 5 : 2;
|
||||
$length = ($feedType === self::$FEED_RSS) ? 5 : 2;
|
||||
return str_replace('_', '-', substr($this->locale, 0, $length));
|
||||
}
|
||||
return ($this->feedType === self::$FEED_RSS) ? 'en-en' : 'en';
|
||||
return ($feedType === self::$FEED_RSS) ? 'en-en' : 'en';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -238,32 +227,35 @@ public function getTypeLanguage()
|
|||
*
|
||||
* Return an empty string if invalid DateTime is passed.
|
||||
*
|
||||
* @param string $feedType Type of feed (RSS/ATOM).
|
||||
*
|
||||
* @return string Formatted date.
|
||||
*/
|
||||
protected function getLatestDateFormatted()
|
||||
protected function getLatestDateFormatted(string $feedType)
|
||||
{
|
||||
if (empty($this->latestDate) || !$this->latestDate instanceof DateTime) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$type = ($this->feedType == self::$FEED_RSS) ? DateTime::RSS : DateTime::ATOM;
|
||||
$type = ($feedType == self::$FEED_RSS) ? DateTime::RSS : DateTime::ATOM;
|
||||
return $this->latestDate->format($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ISO date from DateTime according to feed type.
|
||||
*
|
||||
* @param string $feedType Type of feed (RSS/ATOM).
|
||||
* @param DateTime $date Date to format.
|
||||
* @param string|bool $format Force format.
|
||||
*
|
||||
* @return string Formatted date.
|
||||
*/
|
||||
protected function getIsoDate(DateTime $date, $format = false)
|
||||
protected function getIsoDate(string $feedType, DateTime $date, $format = false)
|
||||
{
|
||||
if ($format !== false) {
|
||||
return $date->format($format);
|
||||
}
|
||||
if ($this->feedType == self::$FEED_RSS) {
|
||||
if ($feedType == self::$FEED_RSS) {
|
||||
return $date->format(DateTime::RSS);
|
||||
}
|
||||
return $date->format(DateTime::ATOM);
|
||||
|
@ -275,21 +267,22 @@ protected function getIsoDate(DateTime $date, $format = false)
|
|||
* If 'nb' not set or invalid, default value: $DEFAULT_NB_LINKS.
|
||||
* If 'nb' is set to 'all', display all filtered bookmarks (max parameter).
|
||||
*
|
||||
* @param int $max maximum number of bookmarks to display.
|
||||
* @param int $max maximum number of bookmarks to display.
|
||||
* @param array $userInput $_GET.
|
||||
*
|
||||
* @return int number of bookmarks to display.
|
||||
*/
|
||||
public function getNbLinks($max)
|
||||
protected function getNbLinks($max, ?array $userInput)
|
||||
{
|
||||
if (empty($this->userInput['nb'])) {
|
||||
if (empty($userInput['nb'])) {
|
||||
return self::$DEFAULT_NB_LINKS;
|
||||
}
|
||||
|
||||
if ($this->userInput['nb'] == 'all') {
|
||||
if ($userInput['nb'] == 'all') {
|
||||
return $max;
|
||||
}
|
||||
|
||||
$intNb = intval($this->userInput['nb']);
|
||||
$intNb = intval($userInput['nb']);
|
||||
if (!is_int($intNb) || $intNb == 0) {
|
||||
return self::$DEFAULT_NB_LINKS;
|
||||
}
|
||||
|
|
|
@ -452,15 +452,13 @@ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionM
|
|||
$feedGenerator = new FeedBuilder(
|
||||
$bookmarkService,
|
||||
$factory->getFormatter(),
|
||||
$feedType,
|
||||
$_SERVER,
|
||||
$_GET,
|
||||
$loginManager->isLoggedIn()
|
||||
);
|
||||
$feedGenerator->setLocale(strtolower(setlocale(LC_COLLATE, 0)));
|
||||
$feedGenerator->setHideDates($conf->get('privacy.hide_timestamps') && !$loginManager->isLoggedIn());
|
||||
$feedGenerator->setUsePermalinks(isset($_GET['permalinks']) || !$conf->get('feed.rss_permalinks'));
|
||||
$data = $feedGenerator->buildData();
|
||||
$data = $feedGenerator->buildData($feedType, $_GET);
|
||||
|
||||
// Process plugin hook.
|
||||
$pluginManager->executeHooks('render_feed', $data, array(
|
||||
|
|
|
@ -64,23 +64,6 @@ public static function setUpBeforeClass()
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test GetTypeLanguage().
|
||||
*/
|
||||
public function testGetTypeLanguage()
|
||||
{
|
||||
$feedBuilder = new FeedBuilder(null, self::$formatter, FeedBuilder::$FEED_ATOM, null, null, false);
|
||||
$feedBuilder->setLocale(self::$LOCALE);
|
||||
$this->assertEquals(self::$ATOM_LANGUAGUE, $feedBuilder->getTypeLanguage());
|
||||
$feedBuilder = new FeedBuilder(null, self::$formatter, FeedBuilder::$FEED_RSS, null, null, false);
|
||||
$feedBuilder->setLocale(self::$LOCALE);
|
||||
$this->assertEquals(self::$RSS_LANGUAGE, $feedBuilder->getTypeLanguage());
|
||||
$feedBuilder = new FeedBuilder(null, self::$formatter, FeedBuilder::$FEED_ATOM, null, null, false);
|
||||
$this->assertEquals('en', $feedBuilder->getTypeLanguage());
|
||||
$feedBuilder = new FeedBuilder(null, self::$formatter, FeedBuilder::$FEED_RSS, null, null, false);
|
||||
$this->assertEquals('en-en', $feedBuilder->getTypeLanguage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test buildData with RSS feed.
|
||||
*/
|
||||
|
@ -89,13 +72,11 @@ public function testRSSBuildData()
|
|||
$feedBuilder = new FeedBuilder(
|
||||
self::$bookmarkService,
|
||||
self::$formatter,
|
||||
FeedBuilder::$FEED_RSS,
|
||||
self::$serverInfo,
|
||||
null,
|
||||
static::$serverInfo,
|
||||
false
|
||||
);
|
||||
$feedBuilder->setLocale(self::$LOCALE);
|
||||
$data = $feedBuilder->buildData();
|
||||
$data = $feedBuilder->buildData(FeedBuilder::$FEED_RSS, null);
|
||||
// Test headers (RSS)
|
||||
$this->assertEquals(self::$RSS_LANGUAGE, $data['language']);
|
||||
$this->assertRegExp('/Wed, 03 Aug 2016 09:30:33 \+\d{4}/', $data['last_update']);
|
||||
|
@ -140,13 +121,11 @@ public function testAtomBuildData()
|
|||
$feedBuilder = new FeedBuilder(
|
||||
self::$bookmarkService,
|
||||
self::$formatter,
|
||||
FeedBuilder::$FEED_ATOM,
|
||||
self::$serverInfo,
|
||||
null,
|
||||
static::$serverInfo,
|
||||
false
|
||||
);
|
||||
$feedBuilder->setLocale(self::$LOCALE);
|
||||
$data = $feedBuilder->buildData();
|
||||
$data = $feedBuilder->buildData(FeedBuilder::$FEED_ATOM, null);
|
||||
$this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
|
||||
$this->assertRegExp('/2016-08-03T09:30:33\+\d{2}:\d{2}/', $data['last_update']);
|
||||
$link = $data['links'][array_keys($data['links'])[2]];
|
||||
|
@ -166,13 +145,11 @@ public function testBuildDataFiltered()
|
|||
$feedBuilder = new FeedBuilder(
|
||||
self::$bookmarkService,
|
||||
self::$formatter,
|
||||
FeedBuilder::$FEED_ATOM,
|
||||
self::$serverInfo,
|
||||
$criteria,
|
||||
static::$serverInfo,
|
||||
false
|
||||
);
|
||||
$feedBuilder->setLocale(self::$LOCALE);
|
||||
$data = $feedBuilder->buildData();
|
||||
$data = $feedBuilder->buildData(FeedBuilder::$FEED_ATOM, $criteria);
|
||||
$this->assertEquals(1, count($data['links']));
|
||||
$link = array_shift($data['links']);
|
||||
$this->assertEquals(41, $link['id']);
|
||||
|
@ -190,13 +167,11 @@ public function testBuildDataCount()
|
|||
$feedBuilder = new FeedBuilder(
|
||||
self::$bookmarkService,
|
||||
self::$formatter,
|
||||
FeedBuilder::$FEED_ATOM,
|
||||
self::$serverInfo,
|
||||
$criteria,
|
||||
static::$serverInfo,
|
||||
false
|
||||
);
|
||||
$feedBuilder->setLocale(self::$LOCALE);
|
||||
$data = $feedBuilder->buildData();
|
||||
$data = $feedBuilder->buildData(FeedBuilder::$FEED_ATOM, $criteria);
|
||||
$this->assertEquals(3, count($data['links']));
|
||||
$link = $data['links'][array_keys($data['links'])[2]];
|
||||
$this->assertEquals(41, $link['id']);
|
||||
|
@ -211,14 +186,12 @@ public function testBuildDataPermalinks()
|
|||
$feedBuilder = new FeedBuilder(
|
||||
self::$bookmarkService,
|
||||
self::$formatter,
|
||||
FeedBuilder::$FEED_ATOM,
|
||||
self::$serverInfo,
|
||||
null,
|
||||
static::$serverInfo,
|
||||
false
|
||||
);
|
||||
$feedBuilder->setLocale(self::$LOCALE);
|
||||
$feedBuilder->setUsePermalinks(true);
|
||||
$data = $feedBuilder->buildData();
|
||||
$data = $feedBuilder->buildData(FeedBuilder::$FEED_ATOM, null);
|
||||
$this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
|
||||
$this->assertTrue($data['usepermalinks']);
|
||||
// First link is a permalink
|
||||
|
@ -247,14 +220,12 @@ public function testBuildDataHideDates()
|
|||
$feedBuilder = new FeedBuilder(
|
||||
self::$bookmarkService,
|
||||
self::$formatter,
|
||||
FeedBuilder::$FEED_ATOM,
|
||||
self::$serverInfo,
|
||||
null,
|
||||
static::$serverInfo,
|
||||
false
|
||||
);
|
||||
$feedBuilder->setLocale(self::$LOCALE);
|
||||
$feedBuilder->setHideDates(true);
|
||||
$data = $feedBuilder->buildData();
|
||||
$data = $feedBuilder->buildData(FeedBuilder::$FEED_ATOM, null);
|
||||
$this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
|
||||
$this->assertFalse($data['show_dates']);
|
||||
|
||||
|
@ -262,14 +233,12 @@ public function testBuildDataHideDates()
|
|||
$feedBuilder = new FeedBuilder(
|
||||
self::$bookmarkService,
|
||||
self::$formatter,
|
||||
FeedBuilder::$FEED_ATOM,
|
||||
self::$serverInfo,
|
||||
null,
|
||||
static::$serverInfo,
|
||||
true
|
||||
);
|
||||
$feedBuilder->setLocale(self::$LOCALE);
|
||||
$feedBuilder->setHideDates(true);
|
||||
$data = $feedBuilder->buildData();
|
||||
$data = $feedBuilder->buildData(FeedBuilder::$FEED_ATOM, null);
|
||||
$this->assertEquals(ReferenceLinkDB::$NB_LINKS_TOTAL, count($data['links']));
|
||||
$this->assertTrue($data['show_dates']);
|
||||
}
|
||||
|
@ -289,13 +258,11 @@ public function testBuildDataServerSubdir()
|
|||
$feedBuilder = new FeedBuilder(
|
||||
self::$bookmarkService,
|
||||
self::$formatter,
|
||||
FeedBuilder::$FEED_ATOM,
|
||||
$serverInfo,
|
||||
null,
|
||||
false
|
||||
);
|
||||
$feedBuilder->setLocale(self::$LOCALE);
|
||||
$data = $feedBuilder->buildData();
|
||||
$data = $feedBuilder->buildData(FeedBuilder::$FEED_ATOM, null);
|
||||
|
||||
$this->assertEquals(
|
||||
'http://host.tld:8080/~user/shaarli/index.php?do=feed',
|
||||
|
|
Loading…
Reference in a new issue