New plugin hook: ability to add custom filters to Shaarli search engine

A new plugin hook has been added: hook_test_filter_search_entry
This hook allows to filter out bookmark with custom plugin code when a search is performed.

Related to #143
This commit is contained in:
ArthurHoaro 2021-01-20 15:59:00 +01:00
parent 8997ae6c8e
commit bcba6bd353
27 changed files with 593 additions and 224 deletions

View file

@ -145,6 +145,7 @@ protected function setLinkDb($conf)
{ {
$linkDb = new BookmarkFileService( $linkDb = new BookmarkFileService(
$conf, $conf,
$this->container->get('pluginManager'),
$this->container->get('history'), $this->container->get('history'),
new FlockMutex(fopen(SHAARLI_MUTEX_FILE, 'r'), 2), new FlockMutex(fopen(SHAARLI_MUTEX_FILE, 'r'), 2),
true true

View file

@ -15,6 +15,7 @@
use Shaarli\History; use Shaarli\History;
use Shaarli\Legacy\LegacyLinkDB; use Shaarli\Legacy\LegacyLinkDB;
use Shaarli\Legacy\LegacyUpdater; use Shaarli\Legacy\LegacyUpdater;
use Shaarli\Plugin\PluginManager;
use Shaarli\Render\PageCacheManager; use Shaarli\Render\PageCacheManager;
use Shaarli\Updater\UpdaterUtils; use Shaarli\Updater\UpdaterUtils;
@ -40,6 +41,9 @@ class BookmarkFileService implements BookmarkServiceInterface
/** @var ConfigManager instance */ /** @var ConfigManager instance */
protected $conf; protected $conf;
/** @var PluginManager */
protected $pluginManager;
/** @var History instance */ /** @var History instance */
protected $history; protected $history;
@ -57,6 +61,7 @@ class BookmarkFileService implements BookmarkServiceInterface
*/ */
public function __construct( public function __construct(
ConfigManager $conf, ConfigManager $conf,
PluginManager $pluginManager,
History $history, History $history,
Mutex $mutex, Mutex $mutex,
bool $isLoggedIn bool $isLoggedIn
@ -95,7 +100,8 @@ public function __construct(
} }
} }
$this->bookmarkFilter = new BookmarkFilter($this->bookmarks, $this->conf); $this->pluginManager = $pluginManager;
$this->bookmarkFilter = new BookmarkFilter($this->bookmarks, $this->conf, $this->pluginManager);
} }
/** /**

View file

@ -4,9 +4,9 @@
namespace Shaarli\Bookmark; namespace Shaarli\Bookmark;
use Exception;
use Shaarli\Bookmark\Exception\BookmarkNotFoundException; use Shaarli\Bookmark\Exception\BookmarkNotFoundException;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\Plugin\PluginManager;
/** /**
* Class LinkFilter. * Class LinkFilter.
@ -30,11 +30,6 @@ class BookmarkFilter
*/ */
public static $FILTER_TAG = 'tags'; public static $FILTER_TAG = 'tags';
/**
* @var string filter by day.
*/
public static $FILTER_DAY = 'FILTER_DAY';
/** /**
* @var string filter by day. * @var string filter by day.
*/ */
@ -62,13 +57,17 @@ class BookmarkFilter
/** @var ConfigManager */ /** @var ConfigManager */
protected $conf; protected $conf;
/** @var PluginManager */
protected $pluginManager;
/** /**
* @param Bookmark[] $bookmarks initialization. * @param Bookmark[] $bookmarks initialization.
*/ */
public function __construct($bookmarks, ConfigManager $conf) public function __construct($bookmarks, ConfigManager $conf, PluginManager $pluginManager)
{ {
$this->bookmarks = $bookmarks; $this->bookmarks = $bookmarks;
$this->conf = $conf; $this->conf = $conf;
$this->pluginManager = $pluginManager;
} }
/** /**
@ -112,12 +111,12 @@ public function filter(
$filtered = $this->bookmarks; $filtered = $this->bookmarks;
} }
if (!empty($request[0])) { if (!empty($request[0])) {
$filtered = (new BookmarkFilter($filtered, $this->conf)) $filtered = (new BookmarkFilter($filtered, $this->conf, $this->pluginManager))
->filterTags($request[0], $casesensitive, $visibility) ->filterTags($request[0], $casesensitive, $visibility)
; ;
} }
if (!empty($request[1])) { if (!empty($request[1])) {
$filtered = (new BookmarkFilter($filtered, $this->conf)) $filtered = (new BookmarkFilter($filtered, $this->conf, $this->pluginManager))
->filterFulltext($request[1], $visibility) ->filterFulltext($request[1], $visibility)
; ;
} }
@ -130,8 +129,6 @@ public function filter(
} else { } else {
return $this->filterTags($request, $casesensitive, $visibility); return $this->filterTags($request, $casesensitive, $visibility);
} }
case self::$FILTER_DAY:
return $this->filterDay($request, $visibility);
default: default:
return $this->noFilter($visibility); return $this->noFilter($visibility);
} }
@ -146,13 +143,20 @@ public function filter(
*/ */
private function noFilter(string $visibility = 'all') private function noFilter(string $visibility = 'all')
{ {
if ($visibility === 'all') {
return $this->bookmarks;
}
$out = []; $out = [];
foreach ($this->bookmarks as $key => $value) { foreach ($this->bookmarks as $key => $value) {
if ($value->isPrivate() && $visibility === 'private') { if (
!$this->pluginManager->filterSearchEntry(
$value,
['source' => 'no_filter', 'visibility' => $visibility]
)
) {
continue;
}
if ($visibility === 'all') {
$out[$key] = $value;
} elseif ($value->isPrivate() && $visibility === 'private') {
$out[$key] = $value; $out[$key] = $value;
} elseif (!$value->isPrivate() && $visibility === 'public') { } elseif (!$value->isPrivate() && $visibility === 'public') {
$out[$key] = $value; $out[$key] = $value;
@ -233,18 +237,34 @@ private function filterFulltext(string $searchterms, string $visibility = 'all')
} }
// Iterate over every stored link. // Iterate over every stored link.
foreach ($this->bookmarks as $id => $link) { foreach ($this->bookmarks as $id => $bookmark) {
if (
!$this->pluginManager->filterSearchEntry(
$bookmark,
[
'source' => 'fulltext',
'searchterms' => $searchterms,
'andSearch' => $andSearch,
'exactSearch' => $exactSearch,
'excludeSearch' => $excludeSearch,
'visibility' => $visibility
]
)
) {
continue;
}
// ignore non private bookmarks when 'privatonly' is on. // ignore non private bookmarks when 'privatonly' is on.
if ($visibility !== 'all') { if ($visibility !== 'all') {
if (!$link->isPrivate() && $visibility === 'private') { if (!$bookmark->isPrivate() && $visibility === 'private') {
continue; continue;
} elseif ($link->isPrivate() && $visibility === 'public') { } elseif ($bookmark->isPrivate() && $visibility === 'public') {
continue; continue;
} }
} }
$lengths = []; $lengths = [];
$content = $this->buildFullTextSearchableLink($link, $lengths); $content = $this->buildFullTextSearchableLink($bookmark, $lengths);
// Be optimistic // Be optimistic
$found = true; $found = true;
@ -270,68 +290,18 @@ private function filterFulltext(string $searchterms, string $visibility = 'all')
} }
if ($found !== false) { if ($found !== false) {
$link->addAdditionalContentEntry( $bookmark->addAdditionalContentEntry(
'search_highlight', 'search_highlight',
$this->postProcessFoundPositions($lengths, $foundPositions) $this->postProcessFoundPositions($lengths, $foundPositions)
); );
$filtered[$id] = $link; $filtered[$id] = $bookmark;
} }
} }
return $filtered; return $filtered;
} }
/**
* generate a regex fragment out of a tag
*
* @param string $tag to to generate regexs from. may start with '-' to negate, contain '*' as wildcard
*
* @return string generated regex fragment
*/
protected function tag2regex(string $tag): string
{
$tagsSeparator = $this->conf->get('general.tags_separator', ' ');
$len = strlen($tag);
if (!$len || $tag === "-" || $tag === "*") {
// nothing to search, return empty regex
return '';
}
if ($tag[0] === "-") {
// query is negated
$i = 1; // use offset to start after '-' character
$regex = '(?!'; // create negative lookahead
} else {
$i = 0; // start at first character
$regex = '(?='; // use positive lookahead
}
// before tag may only be the separator or the beginning
$regex .= '.*(?:^|' . $tagsSeparator . ')';
// iterate over string, separating it into placeholder and content
for (; $i < $len; $i++) {
if ($tag[$i] === '*') {
// placeholder found
$regex .= '[^' . $tagsSeparator . ']*?';
} else {
// regular characters
$offset = strpos($tag, '*', $i);
if ($offset === false) {
// no placeholder found, set offset to end of string
$offset = $len;
}
// subtract one, as we want to get before the placeholder or end of string
$offset -= 1;
// we got a tag name that we want to search for. escape any regex characters to prevent conflicts.
$regex .= preg_quote(substr($tag, $i, $offset - $i + 1), '/');
// move $i on
$i = $offset;
}
}
// after the tag may only be the separator or the end
$regex .= '(?:$|' . $tagsSeparator . '))';
return $regex;
}
/** /**
* Returns the list of bookmarks associated with a given list of tags * Returns the list of bookmarks associated with a given list of tags
* *
@ -381,25 +351,39 @@ public function filterTags($tags, bool $casesensitive = false, string $visibilit
$filtered = []; $filtered = [];
// iterate over each link // iterate over each link
foreach ($this->bookmarks as $key => $link) { foreach ($this->bookmarks as $key => $bookmark) {
if (
!$this->pluginManager->filterSearchEntry(
$bookmark,
[
'source' => 'tags',
'tags' => $tags,
'casesensitive' => $casesensitive,
'visibility' => $visibility
]
)
) {
continue;
}
// check level of visibility // check level of visibility
// ignore non private bookmarks when 'privateonly' is on. // ignore non private bookmarks when 'privateonly' is on.
if ($visibility !== 'all') { if ($visibility !== 'all') {
if (!$link->isPrivate() && $visibility === 'private') { if (!$bookmark->isPrivate() && $visibility === 'private') {
continue; continue;
} elseif ($link->isPrivate() && $visibility === 'public') { } elseif ($bookmark->isPrivate() && $visibility === 'public') {
continue; continue;
} }
} }
// build search string, start with tags of current link // build search string, start with tags of current link
$search = $link->getTagsString($tagsSeparator); $search = $bookmark->getTagsString($tagsSeparator);
if (strlen(trim($link->getDescription())) && strpos($link->getDescription(), '#') !== false) { if (strlen(trim($bookmark->getDescription())) && strpos($bookmark->getDescription(), '#') !== false) {
// description given and at least one possible tag found // description given and at least one possible tag found
$descTags = []; $descTags = [];
// find all tags in the form of #tag in the description // find all tags in the form of #tag in the description
preg_match_all( preg_match_all(
'/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm', '/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm',
$link->getDescription(), $bookmark->getDescription(),
$descTags $descTags
); );
if (count($descTags[1])) { if (count($descTags[1])) {
@ -412,8 +396,9 @@ public function filterTags($tags, bool $casesensitive = false, string $visibilit
// this entry does _not_ match our regex // this entry does _not_ match our regex
continue; continue;
} }
$filtered[$key] = $link; $filtered[$key] = $bookmark;
} }
return $filtered; return $filtered;
} }
@ -427,55 +412,30 @@ public function filterTags($tags, bool $casesensitive = false, string $visibilit
public function filterUntagged(string $visibility) public function filterUntagged(string $visibility)
{ {
$filtered = []; $filtered = [];
foreach ($this->bookmarks as $key => $link) { foreach ($this->bookmarks as $key => $bookmark) {
if (
!$this->pluginManager->filterSearchEntry(
$bookmark,
['source' => 'untagged', 'visibility' => $visibility]
)
) {
continue;
}
if ($visibility !== 'all') { if ($visibility !== 'all') {
if (!$link->isPrivate() && $visibility === 'private') { if (!$bookmark->isPrivate() && $visibility === 'private') {
continue; continue;
} elseif ($link->isPrivate() && $visibility === 'public') { } elseif ($bookmark->isPrivate() && $visibility === 'public') {
continue; continue;
} }
} }
if (empty($link->getTags())) { if (empty($bookmark->getTags())) {
$filtered[$key] = $link;
}
}
return $filtered;
}
/**
* Returns the list of articles for a given day, chronologically sorted
*
* Day must be in the form 'YYYYMMDD' (e.g. '20120125'), e.g.
* print_r($mydb->filterDay('20120125'));
*
* @param string $day day to filter.
* @param string $visibility return only all/private/public bookmarks.
* @return Bookmark[] all link matching given day.
*
* @throws Exception if date format is invalid.
*/
public function filterDay(string $day, string $visibility)
{
if (!checkDateFormat('Ymd', $day)) {
throw new Exception('Invalid date format');
}
$filtered = [];
foreach ($this->bookmarks as $key => $bookmark) {
if ($visibility === static::$PUBLIC && $bookmark->isPrivate()) {
continue;
}
if ($bookmark->getCreated()->format('Ymd') == $day) {
$filtered[$key] = $bookmark; $filtered[$key] = $bookmark;
} }
} }
// sort by date ASC return $filtered;
return array_reverse($filtered, true);
} }
/** /**
@ -497,6 +457,56 @@ public static function tagsStrToArray(string $tags, bool $casesensitive): array
return preg_split('/\s+/', $tagsOut, -1, PREG_SPLIT_NO_EMPTY); return preg_split('/\s+/', $tagsOut, -1, PREG_SPLIT_NO_EMPTY);
} }
/**
* generate a regex fragment out of a tag
*
* @param string $tag to to generate regexs from. may start with '-' to negate, contain '*' as wildcard
*
* @return string generated regex fragment
*/
protected function tag2regex(string $tag): string
{
$tagsSeparator = $this->conf->get('general.tags_separator', ' ');
$len = strlen($tag);
if (!$len || $tag === "-" || $tag === "*") {
// nothing to search, return empty regex
return '';
}
if ($tag[0] === "-") {
// query is negated
$i = 1; // use offset to start after '-' character
$regex = '(?!'; // create negative lookahead
} else {
$i = 0; // start at first character
$regex = '(?='; // use positive lookahead
}
// before tag may only be the separator or the beginning
$regex .= '.*(?:^|' . $tagsSeparator . ')';
// iterate over string, separating it into placeholder and content
for (; $i < $len; $i++) {
if ($tag[$i] === '*') {
// placeholder found
$regex .= '[^' . $tagsSeparator . ']*?';
} else {
// regular characters
$offset = strpos($tag, '*', $i);
if ($offset === false) {
// no placeholder found, set offset to end of string
$offset = $len;
}
// subtract one, as we want to get before the placeholder or end of string
$offset -= 1;
// we got a tag name that we want to search for. escape any regex characters to prevent conflicts.
$regex .= preg_quote(substr($tag, $i, $offset - $i + 1), '/');
// move $i on
$i = $offset;
}
}
// after the tag may only be the separator or the end
$regex .= '(?:$|' . $tagsSeparator . '))';
return $regex;
}
/** /**
* This method finalize the content of the foundPositions array, * This method finalize the content of the foundPositions array,
* by associated all search results to their associated bookmark field, * by associated all search results to their associated bookmark field,

View file

@ -95,6 +95,7 @@ public function build(): ShaarliContainer
$container['bookmarkService'] = function (ShaarliContainer $container): BookmarkServiceInterface { $container['bookmarkService'] = function (ShaarliContainer $container): BookmarkServiceInterface {
return new BookmarkFileService( return new BookmarkFileService(
$container->conf, $container->conf,
$container->pluginManager,
$container->history, $container->history,
new FlockMutex(fopen(SHAARLI_MUTEX_FILE, 'r'), 2), new FlockMutex(fopen(SHAARLI_MUTEX_FILE, 'r'), 2),
$container->loginManager->isLoggedIn() $container->loginManager->isLoggedIn()

View file

@ -2,6 +2,7 @@
namespace Shaarli\Plugin; namespace Shaarli\Plugin;
use Shaarli\Bookmark\Bookmark;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\Plugin\Exception\PluginFileNotFoundException; use Shaarli\Plugin\Exception\PluginFileNotFoundException;
use Shaarli\Plugin\Exception\PluginInvalidRouteException; use Shaarli\Plugin\Exception\PluginInvalidRouteException;
@ -45,6 +46,9 @@ class PluginManager
*/ */
protected $errors; protected $errors;
/** @var callable[]|null Preloaded list of hook function for filterSearchEntry() */
protected $filterSearchEntryHooks = null;
/** /**
* Plugins subdirectory. * Plugins subdirectory.
* *
@ -273,6 +277,14 @@ public function getRegisteredRoutes(): array
return $this->registeredRoutes; return $this->registeredRoutes;
} }
/**
* @return array List of registered filter_search_entry hooks
*/
public function getFilterSearchEntryHooks(): ?array
{
return $this->filterSearchEntryHooks;
}
/** /**
* Return the list of encountered errors. * Return the list of encountered errors.
* *
@ -283,6 +295,50 @@ public function getErrors()
return $this->errors; return $this->errors;
} }
/**
* Apply additional filter on every search result of BookmarkFilter calling plugins hooks.
*
* @param Bookmark $bookmark To check.
* @param array $context Additional info about search context, depends on the search source.
*
* @return bool True if the result must be kept in search results, false otherwise.
*/
public function filterSearchEntry(Bookmark $bookmark, array $context): bool
{
if ($this->filterSearchEntryHooks === null) {
$this->loadFilterSearchEntryHooks();
}
if ($this->filterSearchEntryHooks === []) {
return true;
}
foreach ($this->filterSearchEntryHooks as $filterSearchEntryHook) {
if ($filterSearchEntryHook($bookmark, $context) === false) {
return false;
}
}
return true;
}
/**
* filterSearchEntry() method will be called for every search result,
* so for performances we preload existing functions to invoke them directly.
*/
protected function loadFilterSearchEntryHooks(): void
{
$this->filterSearchEntryHooks = [];
foreach ($this->loadedPlugins as $plugin) {
$hookFunction = $this->buildHookName('filter_search_entry', $plugin);
if (function_exists($hookFunction)) {
$this->filterSearchEntryHooks[] = $hookFunction;
}
}
}
/** /**
* Checks whether provided input is valid to register a new route. * Checks whether provided input is valid to register a new route.
* It must contain keys `method`, `route`, `callable` (all strings). * It must contain keys `method`, `route`, `callable` (all strings).

View file

@ -27,7 +27,6 @@ You should have the following tree view:
| |---| demo_plugin.php | |---| demo_plugin.php
``` ```
### Plugin initialization ### Plugin initialization
At the beginning of Shaarli execution, all enabled plugins are loaded. At this point, the plugin system looks for an `init()` function in the <plugin_name>.php to execute and run it if it exists. This function must be named this way, and takes the `ConfigManager` as parameter. At the beginning of Shaarli execution, all enabled plugins are loaded. At this point, the plugin system looks for an `init()` function in the <plugin_name>.php to execute and run it if it exists. This function must be named this way, and takes the `ConfigManager` as parameter.
@ -209,6 +208,7 @@ If it's still not working, please [open an issue](https://github.com/shaarli/Sha
| [save_link](#save_link) | Allow to alter the link being saved in the datastore. | | [save_link](#save_link) | Allow to alter the link being saved in the datastore. |
| [delete_link](#delete_link) | Allow to do an action before a link is deleted from the datastore. | | [delete_link](#delete_link) | Allow to do an action before a link is deleted from the datastore. |
| [save_plugin_parameters](#save_plugin_parameters) | Allow to manipulate plugin parameters before they're saved. | | [save_plugin_parameters](#save_plugin_parameters) | Allow to manipulate plugin parameters before they're saved. |
| [filter_search_entry](#filter_search_entry) | Add custom filters to Shaarli search engine |
#### render_header #### render_header
@ -565,6 +565,23 @@ the array will contain an entry with `MYPLUGIN_PARAMETER` as a key.
Also [special data](#special-data). Also [special data](#special-data).
#### filter_search_entry
Triggered for *every* bookmark when Shaarli's BookmarkService method `search()` is used.
Any custom filter can be added to filter out bookmarks from search results.
The hook **must** return either:
- `true` to keep bookmark entry in search result set
- `false` to discard bookmark entry in result set
> Note: custom filters are called *before* default filters are applied.
##### Parameters
- `Shaarli\Bookmark\Bookmark` object: entry to evaluate
- $context `array`: additional information provided depending on what search is currently used,
the user request, etc.
## Guide for template designers ## Guide for template designers
### Plugin administration ### Plugin administration

View file

@ -17,6 +17,7 @@
* and check user status with _LOGGEDIN_. * and check user status with _LOGGEDIN_.
*/ */
use Shaarli\Bookmark\Bookmark;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\Plugin\PluginManager; use Shaarli\Plugin\PluginManager;
use Shaarli\Render\TemplatePage; use Shaarli\Render\TemplatePage;
@ -263,6 +264,17 @@ function hook_demo_plugin_render_linklist($data)
} }
$data['action_plugin'][] = $action; $data['action_plugin'][] = $action;
// Action to trigger custom filter hiding bookmarks not containing 'e' letter in their description
$action = [
'attr' => [
'href' => '?e',
'title' => 'Hide bookmarks without "e" in their description.',
],
'html' => 'e',
'on' => isset($_GET['e'])
];
$data['action_plugin'][] = $action;
// link_plugin (for each link) // link_plugin (for each link)
foreach ($data['links'] as &$value) { foreach ($data['links'] as &$value) {
$value['link_plugin'][] = ' DEMO \o/'; $value['link_plugin'][] = ' DEMO \o/';
@ -486,6 +498,27 @@ function hook_demo_plugin_save_plugin_parameters($data)
return $data; return $data;
} }
/**
* This hook is called when a search is performed, on every search entry.
* It allows to add custom filters, and filter out additional link.
*
* For exemple here, we hide all bookmarks not containing the letter 'e' in their description.
*
* @param Bookmark $bookmark Search entry. Note that this is a Bookmark object, and not a link array.
* It should NOT be altered.
* @param array $context Additional info on the search performed.
*
* @return bool True if the bookmark should be kept in the search result, false to discard it.
*/
function hook_demo_plugin_filter_search_entry(Bookmark $bookmark, array $context): bool
{
if (isset($_GET['e'])) {
return strpos($bookmark->getDescription(), 'e') !== false;
}
return true;
}
/** /**
* This function is never called, but contains translation calls for GNU gettext extraction. * This function is never called, but contains translation calls for GNU gettext extraction.
*/ */

View file

@ -2,6 +2,7 @@
namespace Shaarli\Plugin; namespace Shaarli\Plugin;
use Shaarli\Bookmark\Bookmark;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
/** /**
@ -159,4 +160,19 @@ public function testRegisteredRoutesInvalid(): void
$errors = $this->pluginManager->getErrors(); $errors = $this->pluginManager->getErrors();
static::assertSame(['test_route_invalid [plugin incompatibility]: trying to register invalid route.'], $errors); static::assertSame(['test_route_invalid [plugin incompatibility]: trying to register invalid route.'], $errors);
} }
public function testSearchFilterPlugin(): void
{
PluginManager::$PLUGINS_PATH = self::$pluginPath;
$this->pluginManager->load([self::$pluginName]);
static::assertNull($this->pluginManager->getFilterSearchEntryHooks());
static::assertTrue($this->pluginManager->filterSearchEntry(new Bookmark(), ['_result' => true]));
static::assertCount(1, $this->pluginManager->getFilterSearchEntryHooks());
static::assertSame('hook_test_filter_search_entry', $this->pluginManager->getFilterSearchEntryHooks()[0]);
static::assertFalse($this->pluginManager->filterSearchEntry(new Bookmark(), ['_result' => false]));
}
} }

View file

@ -3,6 +3,7 @@
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Slim\Container; use Slim\Container;
use Slim\Http\Environment; use Slim\Http\Environment;
use Slim\Http\Request; use Slim\Http\Request;
@ -56,6 +57,7 @@ protected function setUp(): void
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['history'] = $history; $this->container['history'] = $history;
$this->container['pluginManager'] = new PluginManager($this->conf);
} }
/** /**

View file

@ -5,6 +5,7 @@
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Shaarli\TestCase; use Shaarli\TestCase;
use Slim\Container; use Slim\Container;
use Slim\Http\Environment; use Slim\Http\Environment;
@ -55,12 +56,18 @@ protected function setUp(): void
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
$this->refDB->write(self::$testDatastore); $this->refDB->write(self::$testDatastore);
$this->pluginManager = new PluginManager($this->conf);
$history = new History('sandbox/history.php'); $history = new History('sandbox/history.php');
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['db'] = new BookmarkFileService($this->conf, $history, $mutex, true); $this->container['db'] = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$history,
$mutex,
true
);
$this->container['history'] = null; $this->container['history'] = null;
$this->controller = new Info($this->container); $this->controller = new Info($this->container);

View file

@ -7,6 +7,7 @@
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Slim\Container; use Slim\Container;
use Slim\Http\Environment; use Slim\Http\Environment;
use Slim\Http\Request; use Slim\Http\Request;
@ -57,6 +58,9 @@ class DeleteLinkTest extends \Shaarli\TestCase
/** @var NoMutex */ /** @var NoMutex */
protected $mutex; protected $mutex;
/** @var PluginManager */
protected $pluginManager;
/** /**
* Before each test, instantiate a new Api with its config, plugins and bookmarks. * Before each test, instantiate a new Api with its config, plugins and bookmarks.
*/ */
@ -70,7 +74,14 @@ protected function setUp(): void
$refHistory = new \ReferenceHistory(); $refHistory = new \ReferenceHistory();
$refHistory->write(self::$testHistory); $refHistory->write(self::$testHistory);
$this->history = new History(self::$testHistory); $this->history = new History(self::$testHistory);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->pluginManager = new PluginManager($this->conf);
$this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
@ -105,7 +116,13 @@ public function testDeleteLinkValid()
$this->assertEquals(204, $response->getStatusCode()); $this->assertEquals(204, $response->getStatusCode());
$this->assertEmpty((string) $response->getBody()); $this->assertEmpty((string) $response->getBody());
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$this->assertFalse($this->bookmarkService->exists($id)); $this->assertFalse($this->bookmarkService->exists($id));
$historyEntry = $this->history->getHistory()[0]; $historyEntry = $this->history->getHistory()[0];

View file

@ -7,6 +7,7 @@
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Slim\Container; use Slim\Container;
use Slim\Http\Environment; use Slim\Http\Environment;
use Slim\Http\Request; use Slim\Http\Request;
@ -67,7 +68,14 @@ protected function setUp(): void
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['db'] = new BookmarkFileService($this->conf, $history, $mutex, true); $pluginManager = new PluginManager($this->conf);
$this->container['db'] = new BookmarkFileService(
$this->conf,
$pluginManager,
$history,
$mutex,
true
);
$this->container['history'] = null; $this->container['history'] = null;
$this->controller = new Links($this->container); $this->controller = new Links($this->container);

View file

@ -7,6 +7,7 @@
use Shaarli\Bookmark\LinkDB; use Shaarli\Bookmark\LinkDB;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Slim\Container; use Slim\Container;
use Slim\Http\Environment; use Slim\Http\Environment;
use Slim\Http\Request; use Slim\Http\Request;
@ -67,7 +68,14 @@ protected function setUp(): void
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['db'] = new BookmarkFileService($this->conf, $history, $mutex, true); $pluginManager = new PluginManager($this->conf);
$this->container['db'] = new BookmarkFileService(
$this->conf,
$pluginManager,
$history,
$mutex,
true
);
$this->container['history'] = null; $this->container['history'] = null;
$this->controller = new Links($this->container); $this->controller = new Links($this->container);

View file

@ -7,6 +7,7 @@
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Shaarli\TestCase; use Shaarli\TestCase;
use Slim\Container; use Slim\Container;
use Slim\Http\Environment; use Slim\Http\Environment;
@ -81,8 +82,14 @@ protected function setUp(): void
$refHistory = new \ReferenceHistory(); $refHistory = new \ReferenceHistory();
$refHistory->write(self::$testHistory); $refHistory->write(self::$testHistory);
$this->history = new History(self::$testHistory); $this->history = new History(self::$testHistory);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $mutex, true); $pluginManager = new PluginManager($this->conf);
$this->bookmarkService = new BookmarkFileService(
$this->conf,
$pluginManager,
$this->history,
$mutex,
true
);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['db'] = $this->bookmarkService; $this->container['db'] = $this->bookmarkService;

View file

@ -8,6 +8,7 @@
use Shaarli\Bookmark\BookmarkFileService; use Shaarli\Bookmark\BookmarkFileService;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Slim\Container; use Slim\Container;
use Slim\Http\Environment; use Slim\Http\Environment;
use Slim\Http\Request; use Slim\Http\Request;
@ -73,8 +74,14 @@ protected function setUp(): void
$refHistory = new \ReferenceHistory(); $refHistory = new \ReferenceHistory();
$refHistory->write(self::$testHistory); $refHistory->write(self::$testHistory);
$this->history = new History(self::$testHistory); $this->history = new History(self::$testHistory);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $mutex, true); $pluginManager = new PluginManager($this->conf);
$this->bookmarkService = new BookmarkFileService(
$this->conf,
$pluginManager,
$this->history,
$mutex,
true
);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['db'] = $this->bookmarkService; $this->container['db'] = $this->bookmarkService;

View file

@ -8,6 +8,7 @@
use Shaarli\Bookmark\LinkDB; use Shaarli\Bookmark\LinkDB;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Slim\Container; use Slim\Container;
use Slim\Http\Environment; use Slim\Http\Environment;
use Slim\Http\Request; use Slim\Http\Request;
@ -55,6 +56,9 @@ class DeleteTagTest extends \Shaarli\TestCase
*/ */
protected $controller; protected $controller;
/** @var PluginManager */
protected $pluginManager;
/** @var NoMutex */ /** @var NoMutex */
protected $mutex; protected $mutex;
@ -71,7 +75,14 @@ protected function setUp(): void
$refHistory = new \ReferenceHistory(); $refHistory = new \ReferenceHistory();
$refHistory->write(self::$testHistory); $refHistory->write(self::$testHistory);
$this->history = new History(self::$testHistory); $this->history = new History(self::$testHistory);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->pluginManager = new PluginManager($this->conf);
$this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
@ -107,7 +118,13 @@ public function testDeleteTagValid()
$this->assertEquals(204, $response->getStatusCode()); $this->assertEquals(204, $response->getStatusCode());
$this->assertEmpty((string) $response->getBody()); $this->assertEmpty((string) $response->getBody());
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$tags = $this->bookmarkService->bookmarksCountPerTag(); $tags = $this->bookmarkService->bookmarksCountPerTag();
$this->assertFalse(isset($tags[$tagName])); $this->assertFalse(isset($tags[$tagName]));
@ -141,7 +158,13 @@ public function testDeleteTagCaseSensitivity()
$this->assertEquals(204, $response->getStatusCode()); $this->assertEquals(204, $response->getStatusCode());
$this->assertEmpty((string) $response->getBody()); $this->assertEmpty((string) $response->getBody());
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$tags = $this->bookmarkService->bookmarksCountPerTag(); $tags = $this->bookmarkService->bookmarksCountPerTag();
$this->assertFalse(isset($tags[$tagName])); $this->assertFalse(isset($tags[$tagName]));
$this->assertTrue($tags[strtolower($tagName)] > 0); $this->assertTrue($tags[strtolower($tagName)] > 0);

View file

@ -7,6 +7,7 @@
use Shaarli\Bookmark\LinkDB; use Shaarli\Bookmark\LinkDB;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Slim\Container; use Slim\Container;
use Slim\Http\Environment; use Slim\Http\Environment;
use Slim\Http\Request; use Slim\Http\Request;
@ -46,6 +47,9 @@ class GetTagNameTest extends \Shaarli\TestCase
*/ */
protected $controller; protected $controller;
/** @var PluginManager */
protected $pluginManager;
/** /**
* Number of JSON fields per link. * Number of JSON fields per link.
*/ */
@ -65,7 +69,14 @@ protected function setUp(): void
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['db'] = new BookmarkFileService($this->conf, $history, $mutex, true); $this->pluginManager = new PluginManager($this->conf);
$this->container['db'] = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$history,
$mutex,
true
);
$this->container['history'] = null; $this->container['history'] = null;
$this->controller = new Tags($this->container); $this->controller = new Tags($this->container);

View file

@ -6,6 +6,7 @@
use Shaarli\Bookmark\LinkDB; use Shaarli\Bookmark\LinkDB;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Slim\Container; use Slim\Container;
use Slim\Http\Environment; use Slim\Http\Environment;
use Slim\Http\Request; use Slim\Http\Request;
@ -50,6 +51,9 @@ class GetTagsTest extends \Shaarli\TestCase
*/ */
protected $controller; protected $controller;
/** @var PluginManager */
protected $pluginManager;
/** /**
* Number of JSON field per link. * Number of JSON field per link.
*/ */
@ -66,9 +70,14 @@ protected function setUp(): void
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
$this->refDB->write(self::$testDatastore); $this->refDB->write(self::$testDatastore);
$history = new History('sandbox/history.php'); $history = new History('sandbox/history.php');
$this->pluginManager = new PluginManager($this->conf);
$this->bookmarkService = new BookmarkFileService($this->conf, $history, $mutex, true); $this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$history,
$mutex,
true
);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;
$this->container['db'] = $this->bookmarkService; $this->container['db'] = $this->bookmarkService;

View file

@ -8,6 +8,7 @@
use Shaarli\Bookmark\LinkDB; use Shaarli\Bookmark\LinkDB;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Slim\Container; use Slim\Container;
use Slim\Http\Environment; use Slim\Http\Environment;
use Slim\Http\Request; use Slim\Http\Request;
@ -55,6 +56,9 @@ class PutTagTest extends \Shaarli\TestCase
*/ */
protected $controller; protected $controller;
/** @var PluginManager */
protected $pluginManager;
/** /**
* Number of JSON field per link. * Number of JSON field per link.
*/ */
@ -73,7 +77,14 @@ protected function setUp(): void
$refHistory = new \ReferenceHistory(); $refHistory = new \ReferenceHistory();
$refHistory->write(self::$testHistory); $refHistory->write(self::$testHistory);
$this->history = new History(self::$testHistory); $this->history = new History(self::$testHistory);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $mutex, true); $this->pluginManager = new PluginManager($this->conf);
$this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$mutex,
true
);
$this->container = new Container(); $this->container = new Container();
$this->container['conf'] = $this->conf; $this->container['conf'] = $this->conf;

View file

@ -14,6 +14,7 @@
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\Formatter\BookmarkMarkdownFormatter; use Shaarli\Formatter\BookmarkMarkdownFormatter;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Shaarli\TestCase; use Shaarli\TestCase;
/** /**
@ -56,6 +57,9 @@ class BookmarkFileServiceTest extends TestCase
/** @var NoMutex */ /** @var NoMutex */
protected $mutex; protected $mutex;
/** @var PluginManager */
protected $pluginManager;
/** /**
* Instantiates public and private LinkDBs with test data * Instantiates public and private LinkDBs with test data
* *
@ -93,8 +97,21 @@ protected function setUp(): void
$this->refDB = new \ReferenceLinkDB(); $this->refDB = new \ReferenceLinkDB();
$this->refDB->write(self::$testDatastore); $this->refDB->write(self::$testDatastore);
$this->history = new History('sandbox/history.php'); $this->history = new History('sandbox/history.php');
$this->publicLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, false); $this->pluginManager = new PluginManager($this->conf);
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->publicLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
false
);
$this->privateLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
} }
/** /**
@ -111,7 +128,13 @@ public function testDatabaseMigration()
$db = self::getMethod('migrate'); $db = self::getMethod('migrate');
$db->invokeArgs($this->privateLinkDB, []); $db->invokeArgs($this->privateLinkDB, []);
$db = new \FakeBookmarkService($this->conf, $this->history, $this->mutex, true); $db = new \FakeBookmarkService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks()); $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks());
$this->assertEquals($this->refDB->countLinks(), $db->count()); $this->assertEquals($this->refDB->countLinks(), $db->count());
} }
@ -180,7 +203,13 @@ public function testAddFull()
$this->assertEquals($updated, $bookmark->getUpdated()); $this->assertEquals($updated, $bookmark->getUpdated());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->privateLinkDB = new \FakeBookmarkService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$bookmark = $this->privateLinkDB->get(43); $bookmark = $this->privateLinkDB->get(43);
$this->assertEquals(43, $bookmark->getId()); $this->assertEquals(43, $bookmark->getId());
@ -218,7 +247,13 @@ public function testAddMinimal()
$this->assertNull($bookmark->getUpdated()); $this->assertNull($bookmark->getUpdated());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->privateLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$bookmark = $this->privateLinkDB->get(43); $bookmark = $this->privateLinkDB->get(43);
$this->assertEquals(43, $bookmark->getId()); $this->assertEquals(43, $bookmark->getId());
@ -248,7 +283,13 @@ public function testAddMinimalNoWrite()
$this->assertEquals(43, $bookmark->getId()); $this->assertEquals(43, $bookmark->getId());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->privateLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$this->privateLinkDB->get(43); $this->privateLinkDB->get(43);
} }
@ -309,7 +350,13 @@ public function testSetFull()
$this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated()); $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->privateLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$bookmark = $this->privateLinkDB->get(42); $bookmark = $this->privateLinkDB->get(42);
$this->assertEquals(42, $bookmark->getId()); $this->assertEquals(42, $bookmark->getId());
@ -350,7 +397,13 @@ public function testSetMinimal()
$this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated()); $this->assertTrue(new \DateTime('5 seconds ago') < $bookmark->getUpdated());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->privateLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$bookmark = $this->privateLinkDB->get(42); $bookmark = $this->privateLinkDB->get(42);
$this->assertEquals(42, $bookmark->getId()); $this->assertEquals(42, $bookmark->getId());
@ -383,7 +436,13 @@ public function testSetMinimalNoWrite()
$this->assertEquals($title, $bookmark->getTitle()); $this->assertEquals($title, $bookmark->getTitle());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->privateLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$bookmark = $this->privateLinkDB->get(42); $bookmark = $this->privateLinkDB->get(42);
$this->assertEquals(42, $bookmark->getId()); $this->assertEquals(42, $bookmark->getId());
@ -436,7 +495,13 @@ public function testAddOrSetNew()
$this->assertEquals(43, $bookmark->getId()); $this->assertEquals(43, $bookmark->getId());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->privateLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$bookmark = $this->privateLinkDB->get(43); $bookmark = $this->privateLinkDB->get(43);
$this->assertEquals(43, $bookmark->getId()); $this->assertEquals(43, $bookmark->getId());
@ -456,7 +521,13 @@ public function testAddOrSetExisting()
$this->assertEquals($title, $bookmark->getTitle()); $this->assertEquals($title, $bookmark->getTitle());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->privateLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$bookmark = $this->privateLinkDB->get(42); $bookmark = $this->privateLinkDB->get(42);
$this->assertEquals(42, $bookmark->getId()); $this->assertEquals(42, $bookmark->getId());
@ -488,7 +559,13 @@ public function testAddOrSetMinimalNoWrite()
$this->assertEquals($title, $bookmark->getTitle()); $this->assertEquals($title, $bookmark->getTitle());
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->privateLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$bookmark = $this->privateLinkDB->get(42); $bookmark = $this->privateLinkDB->get(42);
$this->assertEquals(42, $bookmark->getId()); $this->assertEquals(42, $bookmark->getId());
@ -514,7 +591,13 @@ public function testRemoveExisting()
$this->assertInstanceOf(BookmarkNotFoundException::class, $exception); $this->assertInstanceOf(BookmarkNotFoundException::class, $exception);
// reload from file // reload from file
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->privateLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$this->privateLinkDB->get(42); $this->privateLinkDB->get(42);
} }
@ -607,7 +690,7 @@ public function testConstructDatastoreNotWriteable()
$conf = new ConfigManager('tests/utils/config/configJson'); $conf = new ConfigManager('tests/utils/config/configJson');
$conf->set('resource.datastore', 'null/store.db'); $conf->set('resource.datastore', 'null/store.db');
new BookmarkFileService($conf, $this->history, $this->mutex, true); new BookmarkFileService($conf, $this->pluginManager, $this->history, $this->mutex, true);
} }
/** /**
@ -617,7 +700,7 @@ public function testCheckDBNewLoggedIn()
{ {
unlink(self::$testDatastore); unlink(self::$testDatastore);
$this->assertFileNotExists(self::$testDatastore); $this->assertFileNotExists(self::$testDatastore);
new BookmarkFileService($this->conf, $this->history, $this->mutex, true); new BookmarkFileService($this->conf, $this->pluginManager, $this->history, $this->mutex, true);
$this->assertFileExists(self::$testDatastore); $this->assertFileExists(self::$testDatastore);
// ensure the correct data has been written // ensure the correct data has been written
@ -631,7 +714,7 @@ public function testCheckDBNewLoggedOut()
{ {
unlink(self::$testDatastore); unlink(self::$testDatastore);
$this->assertFileNotExists(self::$testDatastore); $this->assertFileNotExists(self::$testDatastore);
$db = new \FakeBookmarkService($this->conf, $this->history, $this->mutex, false); $db = new \FakeBookmarkService($this->conf, $this->pluginManager, $this->history, $this->mutex, false);
$this->assertFileNotExists(self::$testDatastore); $this->assertFileNotExists(self::$testDatastore);
$this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks()); $this->assertInstanceOf(BookmarkArray::class, $db->getBookmarks());
$this->assertCount(0, $db->getBookmarks()); $this->assertCount(0, $db->getBookmarks());
@ -664,13 +747,13 @@ public function testReadPrivateDB()
*/ */
public function testSave() public function testSave()
{ {
$testDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $testDB = new BookmarkFileService($this->conf, $this->pluginManager, $this->history, $this->mutex, true);
$dbSize = $testDB->count(); $dbSize = $testDB->count();
$bookmark = new Bookmark(); $bookmark = new Bookmark();
$testDB->add($bookmark); $testDB->add($bookmark);
$testDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $testDB = new BookmarkFileService($this->conf, $this->pluginManager, $this->history, $this->mutex, true);
$this->assertEquals($dbSize + 1, $testDB->count()); $this->assertEquals($dbSize + 1, $testDB->count());
} }
@ -680,7 +763,7 @@ public function testSave()
public function testCountHiddenPublic() public function testCountHiddenPublic()
{ {
$this->conf->set('privacy.hide_public_links', true); $this->conf->set('privacy.hide_public_links', true);
$linkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, false); $linkDB = new BookmarkFileService($this->conf, $this->pluginManager, $this->history, $this->mutex, false);
$this->assertEquals(0, $linkDB->count()); $this->assertEquals(0, $linkDB->count());
} }
@ -906,7 +989,13 @@ public function testFilterHashWithPrivateKey()
$bookmark->addAdditionalContentEntry('private_key', $privateKey); $bookmark->addAdditionalContentEntry('private_key', $privateKey);
$this->privateLinkDB->save(); $this->privateLinkDB->save();
$this->privateLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, false); $this->privateLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
false
);
$bookmark = $this->privateLinkDB->findByHash($hash, $privateKey); $bookmark = $this->privateLinkDB->findByHash($hash, $privateKey);
static::assertSame(6, $bookmark->getId()); static::assertSame(6, $bookmark->getId());
@ -1152,7 +1241,13 @@ public function testGetLatestWithSticky(): void
public function testGetLatestEmptyDatastore(): void public function testGetLatestEmptyDatastore(): void
{ {
unlink($this->conf->get('resource.datastore')); unlink($this->conf->get('resource.datastore'));
$this->publicLinkDB = new BookmarkFileService($this->conf, $this->history, $this->mutex, false); $this->publicLinkDB = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
false
);
$bookmark = $this->publicLinkDB->getLatest(); $bookmark = $this->publicLinkDB->getLatest();

View file

@ -6,6 +6,7 @@
use ReferenceLinkDB; use ReferenceLinkDB;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Shaarli\TestCase; use Shaarli\TestCase;
/** /**
@ -32,19 +33,24 @@ class BookmarkFilterTest extends TestCase
*/ */
protected static $bookmarkService; protected static $bookmarkService;
/** @var PluginManager */
protected static $pluginManager;
/** /**
* Instantiate linkFilter with ReferenceLinkDB data. * Instantiate linkFilter with ReferenceLinkDB data.
*/ */
public static function setUpBeforeClass(): void public static function setUpBeforeClass(): void
{ {
$mutex = new NoMutex(); $mutex = new NoMutex();
$conf = new ConfigManager('tests/utils/config/configJson'); $conf = new ConfigManager('tests/utils/config/configJson');
$conf->set('resource.datastore', self::$testDatastore); $conf->set('resource.datastore', self::$testDatastore);
static::$pluginManager = new PluginManager($conf);
self::$refDB = new \ReferenceLinkDB(); self::$refDB = new \ReferenceLinkDB();
self::$refDB->write(self::$testDatastore); self::$refDB->write(self::$testDatastore);
$history = new History('sandbox/history.php'); $history = new History('sandbox/history.php');
self::$bookmarkService = new \FakeBookmarkService($conf, $history, $mutex, true); self::$bookmarkService = new \FakeBookmarkService($conf, static::$pluginManager, $history, $mutex, true);
self::$linkFilter = new BookmarkFilter(self::$bookmarkService->getBookmarks(), $conf); self::$linkFilter = new BookmarkFilter(self::$bookmarkService->getBookmarks(), $conf, static::$pluginManager);
} }
/** /**
@ -178,61 +184,6 @@ public function testFilterUnknownTag()
); );
} }
/**
* Return bookmarks for a given day
*/
public function testFilterDay()
{
$this->assertEquals(
4,
count(self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, '20121206'))
);
}
/**
* Return bookmarks for a given day
*/
public function testFilterDayRestrictedVisibility(): void
{
$this->assertEquals(
3,
count(self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, '20121206', false, BookmarkFilter::$PUBLIC))
);
}
/**
* 404 - day not found
*/
public function testFilterUnknownDay()
{
$this->assertEquals(
0,
count(self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, '19700101'))
);
}
/**
* Use an invalid date format
*/
public function testFilterInvalidDayWithChars()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessageRegExp('/Invalid date format/');
self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, 'Rainy day, dream away');
}
/**
* Use an invalid date format
*/
public function testFilterInvalidDayDigits()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessageRegExp('/Invalid date format/');
self::$linkFilter->filter(BookmarkFilter::$FILTER_DAY, '20');
}
/** /**
* Retrieve a link entry with its hash * Retrieve a link entry with its hash
*/ */

View file

@ -5,6 +5,7 @@
use malkusch\lock\mutex\NoMutex; use malkusch\lock\mutex\NoMutex;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Shaarli\TestCase; use Shaarli\TestCase;
/** /**
@ -38,6 +39,9 @@ class BookmarkInitializerTest extends TestCase
/** @var NoMutex */ /** @var NoMutex */
protected $mutex; protected $mutex;
/** @var PluginManager */
protected $pluginManager;
/** /**
* Initialize an empty BookmarkFileService * Initialize an empty BookmarkFileService
*/ */
@ -51,8 +55,15 @@ public function setUp(): void
copy('tests/utils/config/configJson.json.php', self::$testConf .'.json.php'); copy('tests/utils/config/configJson.json.php', self::$testConf .'.json.php');
$this->conf = new ConfigManager(self::$testConf); $this->conf = new ConfigManager(self::$testConf);
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->pluginManager = new PluginManager($this->conf);
$this->history = new History('sandbox/history.php'); $this->history = new History('sandbox/history.php');
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$this->initializer = new BookmarkInitializer($this->bookmarkService); $this->initializer = new BookmarkInitializer($this->bookmarkService);
} }
@ -64,7 +75,13 @@ public function testInitializeNotEmptyDataStore(): void
{ {
$refDB = new \ReferenceLinkDB(); $refDB = new \ReferenceLinkDB();
$refDB->write(self::$testDatastore); $refDB->write(self::$testDatastore);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$this->initializer = new BookmarkInitializer($this->bookmarkService); $this->initializer = new BookmarkInitializer($this->bookmarkService);
$this->initializer->initialize(); $this->initializer->initialize();
@ -95,7 +112,13 @@ public function testInitializeNotEmptyDataStore(): void
$this->bookmarkService->save(); $this->bookmarkService->save();
// Reload from file // Reload from file
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$this->assertEquals($refDB->countLinks() + 3, $this->bookmarkService->count()); $this->assertEquals($refDB->countLinks() + 3, $this->bookmarkService->count());
$bookmark = $this->bookmarkService->get(43); $bookmark = $this->bookmarkService->get(43);
@ -126,7 +149,13 @@ public function testInitializeNotEmptyDataStore(): void
public function testInitializeNonExistentDataStore(): void public function testInitializeNonExistentDataStore(): void
{ {
$this->conf->set('resource.datastore', static::$testDatastore . '_empty'); $this->conf->set('resource.datastore', static::$testDatastore . '_empty');
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $this->mutex, true); $this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$this->mutex,
true
);
$this->initializer->initialize(); $this->initializer->initialize();

View file

@ -11,6 +11,7 @@
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\Formatter\FormatterFactory; use Shaarli\Formatter\FormatterFactory;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Shaarli\TestCase; use Shaarli\TestCase;
/** /**
@ -55,8 +56,15 @@ public static function setUpBeforeClass(): void
$refLinkDB->write(self::$testDatastore); $refLinkDB->write(self::$testDatastore);
$history = new History('sandbox/history.php'); $history = new History('sandbox/history.php');
$factory = new FormatterFactory($conf, true); $factory = new FormatterFactory($conf, true);
$pluginManager = new PluginManager($conf);
self::$formatter = $factory->getFormatter(); self::$formatter = $factory->getFormatter();
self::$bookmarkService = new BookmarkFileService($conf, $history, $mutex, true); self::$bookmarkService = new BookmarkFileService(
$conf,
$pluginManager,
$history,
$mutex,
true
);
self::$serverInfo = array( self::$serverInfo = array(
'HTTPS' => 'Off', 'HTTPS' => 'Off',

View file

@ -8,6 +8,7 @@
use Shaarli\Formatter\BookmarkFormatter; use Shaarli\Formatter\BookmarkFormatter;
use Shaarli\Formatter\FormatterFactory; use Shaarli\Formatter\FormatterFactory;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Shaarli\TestCase; use Shaarli\TestCase;
require_once 'tests/utils/ReferenceLinkDB.php'; require_once 'tests/utils/ReferenceLinkDB.php';
@ -47,6 +48,9 @@ class BookmarkExportTest extends TestCase
*/ */
protected static $history; protected static $history;
/** @var PluginManager */
protected static $pluginManager;
/** /**
* @var NetscapeBookmarkUtils * @var NetscapeBookmarkUtils
*/ */
@ -63,7 +67,14 @@ public static function setUpBeforeClass(): void
static::$refDb = new \ReferenceLinkDB(); static::$refDb = new \ReferenceLinkDB();
static::$refDb->write(static::$testDatastore); static::$refDb->write(static::$testDatastore);
static::$history = new History('sandbox/history.php'); static::$history = new History('sandbox/history.php');
static::$bookmarkService = new BookmarkFileService(static::$conf, static::$history, $mutex, true); static::$pluginManager = new PluginManager(static::$conf);
static::$bookmarkService = new BookmarkFileService(
static::$conf,
static::$pluginManager,
static::$history,
$mutex,
true
);
$factory = new FormatterFactory(static::$conf, true); $factory = new FormatterFactory(static::$conf, true);
static::$formatter = $factory->getFormatter('raw'); static::$formatter = $factory->getFormatter('raw');
} }

View file

@ -10,6 +10,7 @@
use Shaarli\Bookmark\BookmarkFilter; use Shaarli\Bookmark\BookmarkFilter;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Shaarli\TestCase; use Shaarli\TestCase;
use Slim\Http\UploadedFile; use Slim\Http\UploadedFile;
@ -71,6 +72,9 @@ class BookmarkImportTest extends TestCase
*/ */
protected $netscapeBookmarkUtils; protected $netscapeBookmarkUtils;
/** @var PluginManager */
protected $pluginManager;
/** /**
* @var string Save the current timezone. * @var string Save the current timezone.
*/ */
@ -99,7 +103,14 @@ protected function setUp(): void
$this->conf->set('resource.page_cache', $this->pagecache); $this->conf->set('resource.page_cache', $this->pagecache);
$this->conf->set('resource.datastore', self::$testDatastore); $this->conf->set('resource.datastore', self::$testDatastore);
$this->history = new History(self::$historyFilePath); $this->history = new History(self::$historyFilePath);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->history, $mutex, true); $this->pluginManager = new PluginManager($this->conf);
$this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->pluginManager,
$this->history,
$mutex,
true
);
$this->netscapeBookmarkUtils = new NetscapeBookmarkUtils($this->bookmarkService, $this->conf, $this->history); $this->netscapeBookmarkUtils = new NetscapeBookmarkUtils($this->bookmarkService, $this->conf, $this->history);
} }

View file

@ -1,5 +1,7 @@
<?php <?php
use Shaarli\Bookmark\Bookmark;
/** /**
* Hook for test. * Hook for test.
* *
@ -43,3 +45,8 @@ function test_register_routes(): array
], ],
]; ];
} }
function hook_test_filter_search_entry(Bookmark $bookmark, array $context): bool
{
return $context['_result'];
}

View file

@ -7,6 +7,7 @@
use Shaarli\Bookmark\BookmarkServiceInterface; use Shaarli\Bookmark\BookmarkServiceInterface;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
use Shaarli\History; use Shaarli\History;
use Shaarli\Plugin\PluginManager;
use Shaarli\TestCase; use Shaarli\TestCase;
@ -51,7 +52,13 @@ protected function setUp(): void
copy('tests/utils/config/configJson.json.php', self::$configFile .'.json.php'); copy('tests/utils/config/configJson.json.php', self::$configFile .'.json.php');
$this->conf = new ConfigManager(self::$configFile); $this->conf = new ConfigManager(self::$configFile);
$this->bookmarkService = new BookmarkFileService($this->conf, $this->createMock(History::class), $mutex, true); $this->bookmarkService = new BookmarkFileService(
$this->conf,
$this->createMock(PluginManager::class),
$this->createMock(History::class),
$mutex,
true
);
$this->updater = new Updater([], $this->bookmarkService, $this->conf, true); $this->updater = new Updater([], $this->bookmarkService, $this->conf, true);
} }