* Searching '-mytag' will now exlude all shaares with 'mytag' tag.
* All tags starting with a '-' are renamed without it (through the Updater).
* Unit tests.
Minor code changes:
* LinkDB->filter() can now take no parameters (get all link depending on logged status).
* tagsStrToArray() is now static and filters blank tags.
*
* @return array filtered links
*/
- public function filter($type, $request, $casesensitive = false, $privateonly = false)
+ public function filter($type = '', $request = '', $casesensitive = false, $privateonly = false)
{
$linkFilter = new LinkFilter($this->_links);
$requestFilter = is_array($request) ? implode(' ', $request) : $request;
*/
public function filterTags($tags, $casesensitive = false, $privateonly = false)
{
- $searchtags = $this->tagsStrToArray($tags, $casesensitive);
+ $searchtags = self::tagsStrToArray($tags, $casesensitive);
$filtered = array();
+ if (empty($searchtags)) {
+ return $filtered;
+ }
- foreach ($this->links as $l) {
+ foreach ($this->links as $link) {
// ignore non private links when 'privatonly' is on.
- if (! $l['private'] && $privateonly === true) {
+ if (! $link['private'] && $privateonly === true) {
continue;
}
- $linktags = $this->tagsStrToArray($l['tags'], $casesensitive);
+ $linktags = self::tagsStrToArray($link['tags'], $casesensitive);
- if (count(array_intersect($linktags, $searchtags)) == count($searchtags)) {
- $filtered[$l['linkdate']] = $l;
+ $found = true;
+ for ($i = 0 ; $i < count($searchtags) && $found; $i++) {
+ // Exclusive search, quit if tag found.
+ // Or, tag not found in the link, quit.
+ if (($searchtags[$i][0] == '-' && in_array(substr($searchtags[$i], 1), $linktags))
+ || ($searchtags[$i][0] != '-') && ! in_array($searchtags[$i], $linktags)
+ ) {
+ $found = false;
+ }
+ }
+
+ if ($found) {
+ $filtered[$link['linkdate']] = $link;
}
}
krsort($filtered);
*
* @return array filtered tags string.
*/
- public function tagsStrToArray($tags, $casesensitive)
+ public static function tagsStrToArray($tags, $casesensitive)
{
// We use UTF-8 conversion to handle various graphemes (i.e. cyrillic, or greek)
$tagsOut = $casesensitive ? $tags : mb_convert_case($tags, MB_CASE_LOWER, 'UTF-8');
$tagsOut = str_replace(',', ' ', $tagsOut);
- return explode(' ', trim($tagsOut));
+ return array_filter(explode(' ', trim($tagsOut)), 'strlen');
}
}
return true;
}
+
+ /**
+ * Rename tags starting with a '-' to work with tag exclusion search.
+ */
+ public function updateMethodRenameDashTags()
+ {
+ $linklist = $this->linkDB->filter();
+ foreach ($linklist as $link) {
+ $link['tags'] = preg_replace('/(^| )\-/', '$1', $link['tags']);
+ $link['tags'] = implode(' ', array_unique(LinkFilter::tagsStrToArray($link['tags'], true)));
+ $this->linkDB[$link['linkdate']] = $link;
+ }
+ $this->linkDB->savedb($this->config['config']['PAGECACHE']);
+ return true;
+ }
}
/**
'media' => 1,
'software' => 1,
'stallman' => 1,
- 'free' => 1
+ 'free' => 1,
+ '-exclude' => 1,
),
self::$publicLinkDB->allTags()
);
'html' => 1,
'w3c' => 1,
'css' => 1,
- 'Mercurial' => 1
+ 'Mercurial' => 1,
+ '-exclude' => 1,
),
self::$privateLinkDB->allTags()
);
count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'free software'))
);
}
+
+ /**
+ * Tag search with exclusion.
+ */
+ public function testTagFilterWithExclusion()
+ {
+ $this->assertEquals(
+ 1,
+ count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'gnu -free'))
+ );
+
+ $this->assertEquals(
+ 5,
+ count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '-free'))
+ );
+ }
}
*/
private static $configFields;
+ /**
+ * @var string Path to test datastore.
+ */
+ protected static $testDatastore = 'sandbox/datastore.php';
+
/**
* Executed before each test.
*/
'config' => array(
'CONFIG_FILE' => 'tests/Updater/config.php',
'DATADIR' => 'tests/Updater',
+ 'PAGECACHE' => 'sandbox/pagecache',
'config1' => 'config1data',
'config2' => 'config2data',
)
include self::$configFields['config']['CONFIG_FILE'];
$this->assertEquals(self::$configFields['login'], $GLOBALS['login']);
}
+
+ public function testRenameDashTags()
+ {
+ $refDB = new ReferenceLinkDB();
+ $refDB->write(self::$testDatastore);
+ $linkDB = new LinkDB(self::$testDatastore, true, false);
+ $this->assertEmpty($linkDB->filter(LinkFilter::$FILTER_TAG, 'exclude'));
+ $updater = new Updater(array(), self::$configFields, $linkDB, true);
+ $updater->updateMethodRenameDashTags();
+ var_dump($linkDB->filter(LinkFilter::$FILTER_TAG, 'exclude'));
+ $this->assertNotEmpty($linkDB->filter(LinkFilter::$FILTER_TAG, 'exclude'));
+ }
}
'Richard Stallman and the Free Software Revolution',
0,
'20150310_114633',
- 'free gnu software stallman'
+ 'free gnu software stallman -exclude'
);
$this->addLink(