aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--application/FileUtils.php2
-rw-r--r--application/History.php4
-rw-r--r--application/NetscapeBookmarkUtils.php1
-rw-r--r--application/PageBuilder.php14
-rw-r--r--application/Updater.php11
-rw-r--r--application/api/ApiMiddleware.php5
-rw-r--r--application/api/controllers/ApiController.php9
-rw-r--r--application/api/controllers/History.php3
-rw-r--r--application/api/controllers/Links.php5
-rw-r--r--index.php24
-rw-r--r--tests/HistoryTest.php24
-rw-r--r--tests/NetscapeBookmarkUtils/BookmarkImportTest.php4
-rw-r--r--tests/api/controllers/DeleteLinkTest.php22
-rw-r--r--tests/api/controllers/GetLinkIdTest.php1
-rw-r--r--tests/api/controllers/GetLinksTest.php1
-rw-r--r--tests/api/controllers/HistoryTest.php7
-rw-r--r--tests/api/controllers/InfoTest.php1
-rw-r--r--tests/api/controllers/PostLinkTest.php23
-rw-r--r--tests/api/controllers/PutLinkTest.php23
-rw-r--r--tests/utils/ReferenceHistory.php22
21 files changed, 157 insertions, 55 deletions
diff --git a/README.md b/README.md
index cfdefc66..d57f5202 100644
--- a/README.md
+++ b/README.md
@@ -85,6 +85,12 @@ dailymotion, flickr, imageshack, imgur, vimeo, xkcd, youtube...
85- URL cleanup: automatic removal of `?utm_source=...`, `fb=...` 85- URL cleanup: automatic removal of `?utm_source=...`, `fb=...`
86- discreet pop-up notification when a new release is available 86- discreet pop-up notification when a new release is available
87 87
88### REST API
89
90Easily extensible by any client using the REST API exposed by Shaarli.
91
92See the [API documentation](http://shaarli.github.io/api-documentation/).
93
88### Other usages 94### Other usages
89Though Shaarli is primarily a bookmarking application, it can serve other purposes 95Though Shaarli is primarily a bookmarking application, it can serve other purposes
90(see [usage examples](https://github.com/shaarli/Shaarli/wiki#usage-examples)): 96(see [usage examples](https://github.com/shaarli/Shaarli/wiki#usage-examples)):
diff --git a/application/FileUtils.php b/application/FileUtils.php
index b8ad8970..a167f642 100644
--- a/application/FileUtils.php
+++ b/application/FileUtils.php
@@ -26,7 +26,7 @@ class FileUtils
26 * The file will be created if it doesn't exist. 26 * The file will be created if it doesn't exist.
27 * 27 *
28 * @param string $file File path. 28 * @param string $file File path.
29 * @param string $content Content to write. 29 * @param mixed $content Content to write.
30 * 30 *
31 * @return int|bool Number of bytes written or false if it fails. 31 * @return int|bool Number of bytes written or false if it fails.
32 * 32 *
diff --git a/application/History.php b/application/History.php
index f93b0356..116b9264 100644
--- a/application/History.php
+++ b/application/History.php
@@ -135,7 +135,7 @@ class History
135 135
136 $item = [ 136 $item = [
137 'event' => $status, 137 'event' => $status,
138 'datetime' => (new DateTime())->format(DateTime::ATOM), 138 'datetime' => new DateTime(),
139 'id' => $id !== null ? $id : '', 139 'id' => $id !== null ? $id : '',
140 ]; 140 ];
141 $this->history = array_merge([$item], $this->history); 141 $this->history = array_merge([$item], $this->history);
@@ -177,7 +177,7 @@ class History
177 { 177 {
178 $comparaison = new DateTime('-'. $this->retentionTime . ' seconds'); 178 $comparaison = new DateTime('-'. $this->retentionTime . ' seconds');
179 foreach ($this->history as $key => $value) { 179 foreach ($this->history as $key => $value) {
180 if (DateTime::createFromFormat(DateTime::ATOM, $value['datetime']) < $comparaison) { 180 if ($value['datetime'] < $comparaison) {
181 unset($this->history[$key]); 181 unset($this->history[$key]);
182 } 182 }
183 } 183 }
diff --git a/application/NetscapeBookmarkUtils.php b/application/NetscapeBookmarkUtils.php
index bbfde138..2a10ff22 100644
--- a/application/NetscapeBookmarkUtils.php
+++ b/application/NetscapeBookmarkUtils.php
@@ -180,6 +180,7 @@ class NetscapeBookmarkUtils
180 $newLink['id'] = $existingLink['id']; 180 $newLink['id'] = $existingLink['id'];
181 $newLink['created'] = $existingLink['created']; 181 $newLink['created'] = $existingLink['created'];
182 $newLink['updated'] = new DateTime(); 182 $newLink['updated'] = new DateTime();
183 $newLink['shorturl'] = $existingLink['shorturl'];
183 $linkDb[$existingLink['id']] = $newLink; 184 $linkDb[$existingLink['id']] = $newLink;
184 $importCount++; 185 $importCount++;
185 $overwriteCount++; 186 $overwriteCount++;
diff --git a/application/PageBuilder.php b/application/PageBuilder.php
index 8e39455b..50e3f124 100644
--- a/application/PageBuilder.php
+++ b/application/PageBuilder.php
@@ -22,15 +22,22 @@ class PageBuilder
22 protected $conf; 22 protected $conf;
23 23
24 /** 24 /**
25 * @var LinkDB $linkDB instance.
26 */
27 protected $linkDB;
28
29 /**
25 * PageBuilder constructor. 30 * PageBuilder constructor.
26 * $tpl is initialized at false for lazy loading. 31 * $tpl is initialized at false for lazy loading.
27 * 32 *
28 * @param ConfigManager $conf Configuration Manager instance (reference). 33 * @param ConfigManager $conf Configuration Manager instance (reference).
34 * @param LinkDB $linkDB instance.
29 */ 35 */
30 public function __construct(&$conf) 36 public function __construct(&$conf, $linkDB = null)
31 { 37 {
32 $this->tpl = false; 38 $this->tpl = false;
33 $this->conf = $conf; 39 $this->conf = $conf;
40 $this->linkDB = $linkDB;
34 } 41 }
35 42
36 /** 43 /**
@@ -81,6 +88,9 @@ class PageBuilder
81 $this->tpl->assign('feed_type', $this->conf->get('feed.show_atom', true) !== false ? 'atom' : 'rss'); 88 $this->tpl->assign('feed_type', $this->conf->get('feed.show_atom', true) !== false ? 'atom' : 'rss');
82 $this->tpl->assign('hide_timestamps', $this->conf->get('privacy.hide_timestamps', false)); 89 $this->tpl->assign('hide_timestamps', $this->conf->get('privacy.hide_timestamps', false));
83 $this->tpl->assign('token', getToken($this->conf)); 90 $this->tpl->assign('token', getToken($this->conf));
91 if ($this->linkDB !== null) {
92 $this->tpl->assign('tags', $this->linkDB->allTags());
93 }
84 // To be removed with a proper theme configuration. 94 // To be removed with a proper theme configuration.
85 $this->tpl->assign('conf', $this->conf); 95 $this->tpl->assign('conf', $this->conf);
86 } 96 }
diff --git a/application/Updater.php b/application/Updater.php
index 0fb68c5a..03d93a6f 100644
--- a/application/Updater.php
+++ b/application/Updater.php
@@ -440,6 +440,17 @@ class Updater
440 $this->conf->write($this->isLoggedIn); 440 $this->conf->write($this->isLoggedIn);
441 return true; 441 return true;
442 } 442 }
443
444 /**
445 * Reset history store file due to date format change.
446 */
447 public function updateMethodResetHistoryFile()
448 {
449 if (is_file($this->conf->get('resource.history'))) {
450 unlink($this->conf->get('resource.history'));
451 }
452 return true;
453 }
443} 454}
444 455
445/** 456/**
diff --git a/application/api/ApiMiddleware.php b/application/api/ApiMiddleware.php
index 4120f7a9..ff209393 100644
--- a/application/api/ApiMiddleware.php
+++ b/application/api/ApiMiddleware.php
@@ -4,6 +4,7 @@ namespace Shaarli\Api;
4use Shaarli\Api\Exceptions\ApiException; 4use Shaarli\Api\Exceptions\ApiException;
5use Shaarli\Api\Exceptions\ApiAuthorizationException; 5use Shaarli\Api\Exceptions\ApiAuthorizationException;
6 6
7use Shaarli\Config\ConfigManager;
7use Slim\Container; 8use Slim\Container;
8use Slim\Http\Request; 9use Slim\Http\Request;
9use Slim\Http\Response; 10use Slim\Http\Response;
@@ -31,7 +32,7 @@ class ApiMiddleware
31 protected $container; 32 protected $container;
32 33
33 /** 34 /**
34 * @var \ConfigManager instance. 35 * @var ConfigManager instance.
35 */ 36 */
36 protected $conf; 37 protected $conf;
37 38
@@ -121,7 +122,7 @@ class ApiMiddleware
121 * 122 *
122 * FIXME! LinkDB could use a refactoring to avoid this trick. 123 * FIXME! LinkDB could use a refactoring to avoid this trick.
123 * 124 *
124 * @param \ConfigManager $conf instance. 125 * @param ConfigManager $conf instance.
125 */ 126 */
126 protected function setLinkDb($conf) 127 protected function setLinkDb($conf)
127 { 128 {
diff --git a/application/api/controllers/ApiController.php b/application/api/controllers/ApiController.php
index f35b923a..3be85b98 100644
--- a/application/api/controllers/ApiController.php
+++ b/application/api/controllers/ApiController.php
@@ -2,6 +2,7 @@
2 2
3namespace Shaarli\Api\Controllers; 3namespace Shaarli\Api\Controllers;
4 4
5use Shaarli\Config\ConfigManager;
5use \Slim\Container; 6use \Slim\Container;
6 7
7/** 8/**
@@ -19,7 +20,7 @@ abstract class ApiController
19 protected $ci; 20 protected $ci;
20 21
21 /** 22 /**
22 * @var \ConfigManager 23 * @var ConfigManager
23 */ 24 */
24 protected $conf; 25 protected $conf;
25 26
@@ -29,6 +30,11 @@ abstract class ApiController
29 protected $linkDb; 30 protected $linkDb;
30 31
31 /** 32 /**
33 * @var \History
34 */
35 protected $history;
36
37 /**
32 * @var int|null JSON style option. 38 * @var int|null JSON style option.
33 */ 39 */
34 protected $jsonStyle; 40 protected $jsonStyle;
@@ -45,6 +51,7 @@ abstract class ApiController
45 $this->ci = $ci; 51 $this->ci = $ci;
46 $this->conf = $ci->get('conf'); 52 $this->conf = $ci->get('conf');
47 $this->linkDb = $ci->get('db'); 53 $this->linkDb = $ci->get('db');
54 $this->history = $ci->get('history');
48 if ($this->conf->get('dev.debug', false)) { 55 if ($this->conf->get('dev.debug', false)) {
49 $this->jsonStyle = JSON_PRETTY_PRINT; 56 $this->jsonStyle = JSON_PRETTY_PRINT;
50 } else { 57 } else {
diff --git a/application/api/controllers/History.php b/application/api/controllers/History.php
index c4ff3e5d..2ff9deaf 100644
--- a/application/api/controllers/History.php
+++ b/application/api/controllers/History.php
@@ -28,8 +28,7 @@ class History extends ApiController
28 */ 28 */
29 public function getHistory($request, $response) 29 public function getHistory($request, $response)
30 { 30 {
31 $history = (new \History($this->conf->get('resource.history')))->getHistory(); 31 $history = $this->history->getHistory();
32 $history = array_reverse($history);
33 32
34 // Return history operations from the {offset}th, starting from {since}. 33 // Return history operations from the {offset}th, starting from {since}.
35 $since = \DateTime::createFromFormat(\DateTime::ATOM, $request->getParam('since')); 34 $since = \DateTime::createFromFormat(\DateTime::ATOM, $request->getParam('since'));
diff --git a/application/api/controllers/Links.php b/application/api/controllers/Links.php
index a40e974d..eb78dd26 100644
--- a/application/api/controllers/Links.php
+++ b/application/api/controllers/Links.php
@@ -141,6 +141,7 @@ class Links extends ApiController
141 141
142 $this->linkDb[$link['id']] = $link; 142 $this->linkDb[$link['id']] = $link;
143 $this->linkDb->save($this->conf->get('resource.page_cache')); 143 $this->linkDb->save($this->conf->get('resource.page_cache'));
144 $this->history->addLink($link);
144 $out = ApiUtils::formatLink($link, index_url($this->ci['environment'])); 145 $out = ApiUtils::formatLink($link, index_url($this->ci['environment']));
145 $redirect = $this->ci->router->relativePathFor('getLink', ['id' => $link['id']]); 146 $redirect = $this->ci->router->relativePathFor('getLink', ['id' => $link['id']]);
146 return $response->withAddedHeader('Location', $redirect) 147 return $response->withAddedHeader('Location', $redirect)
@@ -184,6 +185,7 @@ class Links extends ApiController
184 $responseLink = ApiUtils::updateLink($responseLink, $requestLink); 185 $responseLink = ApiUtils::updateLink($responseLink, $requestLink);
185 $this->linkDb[$responseLink['id']] = $responseLink; 186 $this->linkDb[$responseLink['id']] = $responseLink;
186 $this->linkDb->save($this->conf->get('resource.page_cache')); 187 $this->linkDb->save($this->conf->get('resource.page_cache'));
188 $this->history->updateLink($responseLink);
187 189
188 $out = ApiUtils::formatLink($responseLink, $index); 190 $out = ApiUtils::formatLink($responseLink, $index);
189 return $response->withJson($out, 200, $this->jsonStyle); 191 return $response->withJson($out, 200, $this->jsonStyle);
@@ -205,9 +207,10 @@ class Links extends ApiController
205 if (! isset($this->linkDb[$args['id']])) { 207 if (! isset($this->linkDb[$args['id']])) {
206 throw new ApiLinkNotFoundException(); 208 throw new ApiLinkNotFoundException();
207 } 209 }
208 210 $link = $this->linkDb[$args['id']];
209 unset($this->linkDb[(int) $args['id']]); 211 unset($this->linkDb[(int) $args['id']]);
210 $this->linkDb->save($this->conf->get('resource.page_cache')); 212 $this->linkDb->save($this->conf->get('resource.page_cache'));
213 $this->history->deleteLink($link);
211 214
212 return $response->withStatus(204); 215 return $response->withStatus(204);
213 } 216 }
diff --git a/index.php b/index.php
index cddc9eeb..ab1e30da 100644
--- a/index.php
+++ b/index.php
@@ -707,7 +707,7 @@ function showLinkList($PAGE, $LINKSDB, $conf, $pluginManager) {
707 * @param PluginManager $pluginManager Plugin Manager instance, 707 * @param PluginManager $pluginManager Plugin Manager instance,
708 * @param LinkDB $LINKSDB 708 * @param LinkDB $LINKSDB
709 */ 709 */
710function renderPage($conf, $pluginManager, $LINKSDB) 710function renderPage($conf, $pluginManager, $LINKSDB, $history)
711{ 711{
712 $updater = new Updater( 712 $updater = new Updater(
713 read_updates_file($conf->get('resource.updates')), 713 read_updates_file($conf->get('resource.updates')),
@@ -728,13 +728,7 @@ function renderPage($conf, $pluginManager, $LINKSDB)
728 die($e->getMessage()); 728 die($e->getMessage());
729 } 729 }
730 730
731 try { 731 $PAGE = new PageBuilder($conf, $LINKSDB);
732 $history = new History($conf->get('resource.history'));
733 } catch(Exception $e) {
734 die($e->getMessage());
735 }
736
737 $PAGE = new PageBuilder($conf);
738 $PAGE->assign('linkcount', count($LINKSDB)); 732 $PAGE->assign('linkcount', count($LINKSDB));
739 $PAGE->assign('privateLinkcount', count_private($LINKSDB)); 733 $PAGE->assign('privateLinkcount', count_private($LINKSDB));
740 $PAGE->assign('plugin_errors', $pluginManager->getErrors()); 734 $PAGE->assign('plugin_errors', $pluginManager->getErrors());
@@ -1167,7 +1161,6 @@ function renderPage($conf, $pluginManager, $LINKSDB)
1167 $PAGE->assign('hide_public_links', $conf->get('privacy.hide_public_links', false)); 1161 $PAGE->assign('hide_public_links', $conf->get('privacy.hide_public_links', false));
1168 $PAGE->assign('api_enabled', $conf->get('api.enabled', true)); 1162 $PAGE->assign('api_enabled', $conf->get('api.enabled', true));
1169 $PAGE->assign('api_secret', $conf->get('api.secret')); 1163 $PAGE->assign('api_secret', $conf->get('api.secret'));
1170 $history->updateSettings();
1171 $PAGE->renderPage('configure'); 1164 $PAGE->renderPage('configure');
1172 exit; 1165 exit;
1173 } 1166 }
@@ -1177,7 +1170,6 @@ function renderPage($conf, $pluginManager, $LINKSDB)
1177 if ($targetPage == Router::$PAGE_CHANGETAG) 1170 if ($targetPage == Router::$PAGE_CHANGETAG)
1178 { 1171 {
1179 if (empty($_POST['fromtag']) || (empty($_POST['totag']) && isset($_POST['renametag']))) { 1172 if (empty($_POST['fromtag']) || (empty($_POST['totag']) && isset($_POST['renametag']))) {
1180 $PAGE->assign('tags', $LINKSDB->allTags());
1181 $PAGE->renderPage('changetag'); 1173 $PAGE->renderPage('changetag');
1182 exit; 1174 exit;
1183 } 1175 }
@@ -1578,7 +1570,6 @@ function renderPage($conf, $pluginManager, $LINKSDB)
1578 1570
1579 // Plugin administration form action 1571 // Plugin administration form action
1580 if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) { 1572 if ($targetPage == Router::$PAGE_SAVE_PLUGINSADMIN) {
1581 $history->updateSettings();
1582 try { 1573 try {
1583 if (isset($_POST['parameters_form'])) { 1574 if (isset($_POST['parameters_form'])) {
1584 unset($_POST['parameters_form']); 1575 unset($_POST['parameters_form']);
@@ -1590,6 +1581,7 @@ function renderPage($conf, $pluginManager, $LINKSDB)
1590 $conf->set('general.enabled_plugins', save_plugin_config($_POST)); 1581 $conf->set('general.enabled_plugins', save_plugin_config($_POST));
1591 } 1582 }
1592 $conf->write(isLoggedIn()); 1583 $conf->write(isLoggedIn());
1584 $history->updateSettings();
1593 } 1585 }
1594 catch (Exception $e) { 1586 catch (Exception $e) {
1595 error_log( 1587 error_log(
@@ -1707,7 +1699,6 @@ function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager)
1707 'visibility' => ! empty($_SESSION['privateonly']) ? 'private' : '', 1699 'visibility' => ! empty($_SESSION['privateonly']) ? 'private' : '',
1708 'redirector' => $conf->get('redirector.url'), // Optional redirector URL. 1700 'redirector' => $conf->get('redirector.url'), // Optional redirector URL.
1709 'links' => $linkDisp, 1701 'links' => $linkDisp,
1710 'tags' => $LINKSDB->allTags(),
1711 ); 1702 );
1712 1703
1713 // If there is only a single link, we change on-the-fly the title of the page. 1704 // If there is only a single link, we change on-the-fly the title of the page.
@@ -2240,9 +2231,16 @@ $linkDb = new LinkDB(
2240 $conf->get('redirector.encode_url') 2231 $conf->get('redirector.encode_url')
2241); 2232);
2242 2233
2234try {
2235 $history = new History($conf->get('resource.history'));
2236} catch(Exception $e) {
2237 die($e->getMessage());
2238}
2239
2243$container = new \Slim\Container(); 2240$container = new \Slim\Container();
2244$container['conf'] = $conf; 2241$container['conf'] = $conf;
2245$container['plugins'] = $pluginManager; 2242$container['plugins'] = $pluginManager;
2243$container['history'] = $history;
2246$app = new \Slim\App($container); 2244$app = new \Slim\App($container);
2247 2245
2248// REST API routes 2246// REST API routes
@@ -2262,7 +2260,7 @@ $response = $app->run(true);
2262if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], '/api/v1') === false) { 2260if ($response->getStatusCode() == 404 && strpos($_SERVER['REQUEST_URI'], '/api/v1') === false) {
2263 // We use UTF-8 for proper international characters handling. 2261 // We use UTF-8 for proper international characters handling.
2264 header('Content-Type: text/html; charset=utf-8'); 2262 header('Content-Type: text/html; charset=utf-8');
2265 renderPage($conf, $pluginManager, $linkDb); 2263 renderPage($conf, $pluginManager, $linkDb, $history);
2266} else { 2264} else {
2267 $app->respond($response); 2265 $app->respond($response);
2268} 2266}
diff --git a/tests/HistoryTest.php b/tests/HistoryTest.php
index 91525845..d3bef5a3 100644
--- a/tests/HistoryTest.php
+++ b/tests/HistoryTest.php
@@ -74,21 +74,21 @@ class HistoryTest extends PHPUnit_Framework_TestCase
74 $history->addLink(['id' => 0]); 74 $history->addLink(['id' => 0]);
75 $actual = $history->getHistory()[0]; 75 $actual = $history->getHistory()[0];
76 $this->assertEquals(History::CREATED, $actual['event']); 76 $this->assertEquals(History::CREATED, $actual['event']);
77 $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); 77 $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
78 $this->assertEquals(0, $actual['id']); 78 $this->assertEquals(0, $actual['id']);
79 79
80 $history = new History(self::$historyFilePath); 80 $history = new History(self::$historyFilePath);
81 $history->addLink(['id' => 1]); 81 $history->addLink(['id' => 1]);
82 $actual = $history->getHistory()[0]; 82 $actual = $history->getHistory()[0];
83 $this->assertEquals(History::CREATED, $actual['event']); 83 $this->assertEquals(History::CREATED, $actual['event']);
84 $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); 84 $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
85 $this->assertEquals(1, $actual['id']); 85 $this->assertEquals(1, $actual['id']);
86 86
87 $history = new History(self::$historyFilePath); 87 $history = new History(self::$historyFilePath);
88 $history->addLink(['id' => 'str']); 88 $history->addLink(['id' => 'str']);
89 $actual = $history->getHistory()[0]; 89 $actual = $history->getHistory()[0];
90 $this->assertEquals(History::CREATED, $actual['event']); 90 $this->assertEquals(History::CREATED, $actual['event']);
91 $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); 91 $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
92 $this->assertEquals('str', $actual['id']); 92 $this->assertEquals('str', $actual['id']);
93 } 93 }
94 94
@@ -101,7 +101,7 @@ class HistoryTest extends PHPUnit_Framework_TestCase
101 $history->updateLink(['id' => 1]); 101 $history->updateLink(['id' => 1]);
102 $actual = $history->getHistory()[0]; 102 $actual = $history->getHistory()[0];
103 $this->assertEquals(History::UPDATED, $actual['event']); 103 $this->assertEquals(History::UPDATED, $actual['event']);
104 $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); 104 $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
105 $this->assertEquals(1, $actual['id']); 105 $this->assertEquals(1, $actual['id']);
106 } 106 }
107 107
@@ -114,7 +114,7 @@ class HistoryTest extends PHPUnit_Framework_TestCase
114 $history->deleteLink(['id' => 1]); 114 $history->deleteLink(['id' => 1]);
115 $actual = $history->getHistory()[0]; 115 $actual = $history->getHistory()[0];
116 $this->assertEquals(History::DELETED, $actual['event']); 116 $this->assertEquals(History::DELETED, $actual['event']);
117 $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); 117 $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
118 $this->assertEquals(1, $actual['id']); 118 $this->assertEquals(1, $actual['id']);
119 } 119 }
120 120
@@ -127,7 +127,7 @@ class HistoryTest extends PHPUnit_Framework_TestCase
127 $history->updateSettings(); 127 $history->updateSettings();
128 $actual = $history->getHistory()[0]; 128 $actual = $history->getHistory()[0];
129 $this->assertEquals(History::SETTINGS, $actual['event']); 129 $this->assertEquals(History::SETTINGS, $actual['event']);
130 $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); 130 $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
131 $this->assertEmpty($actual['id']); 131 $this->assertEmpty($actual['id']);
132 } 132 }
133 133
@@ -140,13 +140,13 @@ class HistoryTest extends PHPUnit_Framework_TestCase
140 $history->updateLink(['id' => 1]); 140 $history->updateLink(['id' => 1]);
141 $actual = $history->getHistory()[0]; 141 $actual = $history->getHistory()[0];
142 $this->assertEquals(History::UPDATED, $actual['event']); 142 $this->assertEquals(History::UPDATED, $actual['event']);
143 $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); 143 $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
144 $this->assertEquals(1, $actual['id']); 144 $this->assertEquals(1, $actual['id']);
145 145
146 $history->addLink(['id' => 1]); 146 $history->addLink(['id' => 1]);
147 $actual = $history->getHistory()[0]; 147 $actual = $history->getHistory()[0];
148 $this->assertEquals(History::CREATED, $actual['event']); 148 $this->assertEquals(History::CREATED, $actual['event']);
149 $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); 149 $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
150 $this->assertEquals(1, $actual['id']); 150 $this->assertEquals(1, $actual['id']);
151 } 151 }
152 152
@@ -160,7 +160,7 @@ class HistoryTest extends PHPUnit_Framework_TestCase
160 $history = new History(self::$historyFilePath); 160 $history = new History(self::$historyFilePath);
161 $actual = $history->getHistory()[0]; 161 $actual = $history->getHistory()[0];
162 $this->assertEquals(History::UPDATED, $actual['event']); 162 $this->assertEquals(History::UPDATED, $actual['event']);
163 $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); 163 $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
164 $this->assertEquals(1, $actual['id']); 164 $this->assertEquals(1, $actual['id']);
165 } 165 }
166 166
@@ -176,12 +176,12 @@ class HistoryTest extends PHPUnit_Framework_TestCase
176 $history = new History(self::$historyFilePath); 176 $history = new History(self::$historyFilePath);
177 $actual = $history->getHistory()[0]; 177 $actual = $history->getHistory()[0];
178 $this->assertEquals(History::CREATED, $actual['event']); 178 $this->assertEquals(History::CREATED, $actual['event']);
179 $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); 179 $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
180 $this->assertEquals(1, $actual['id']); 180 $this->assertEquals(1, $actual['id']);
181 181
182 $actual = $history->getHistory()[1]; 182 $actual = $history->getHistory()[1];
183 $this->assertEquals(History::UPDATED, $actual['event']); 183 $this->assertEquals(History::UPDATED, $actual['event']);
184 $this->assertTrue(new DateTime('-2 seconds') < DateTime::createFromFormat(DateTime::ATOM, $actual['datetime'])); 184 $this->assertTrue(new DateTime('-2 seconds') < $actual['datetime']);
185 $this->assertEquals(1, $actual['id']); 185 $this->assertEquals(1, $actual['id']);
186 } 186 }
187 187
@@ -194,7 +194,7 @@ class HistoryTest extends PHPUnit_Framework_TestCase
194 $history->updateLink(['id' => 1]); 194 $history->updateLink(['id' => 1]);
195 $this->assertEquals(1, count($history->getHistory())); 195 $this->assertEquals(1, count($history->getHistory()));
196 $arr = $history->getHistory(); 196 $arr = $history->getHistory();
197 $arr[0]['datetime'] = (new DateTime('-1 hour'))->format(DateTime::ATOM); 197 $arr[0]['datetime'] = new DateTime('-1 hour');
198 FileUtils::writeFlatDB(self::$historyFilePath, $arr); 198 FileUtils::writeFlatDB(self::$historyFilePath, $arr);
199 199
200 $history = new History(self::$historyFilePath, 60); 200 $history = new History(self::$historyFilePath, 60);
diff --git a/tests/NetscapeBookmarkUtils/BookmarkImportTest.php b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php
index f838f259..5fc1d1e8 100644
--- a/tests/NetscapeBookmarkUtils/BookmarkImportTest.php
+++ b/tests/NetscapeBookmarkUtils/BookmarkImportTest.php
@@ -628,7 +628,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
628 $this->assertEquals($nbLinks, count($history)); 628 $this->assertEquals($nbLinks, count($history));
629 foreach ($history as $value) { 629 foreach ($history as $value) {
630 $this->assertEquals(History::CREATED, $value['event']); 630 $this->assertEquals(History::CREATED, $value['event']);
631 $this->assertTrue(new DateTime('-5 seconds') < DateTime::createFromFormat(DateTime::ATOM, $value['datetime'])); 631 $this->assertTrue(new DateTime('-5 seconds') < $value['datetime']);
632 $this->assertTrue(is_int($value['id'])); 632 $this->assertTrue(is_int($value['id']));
633 } 633 }
634 634
@@ -638,7 +638,7 @@ class BookmarkImportTest extends PHPUnit_Framework_TestCase
638 $this->assertEquals($nbLinks * 2, count($history)); 638 $this->assertEquals($nbLinks * 2, count($history));
639 for ($i = 0 ; $i < $nbLinks ; $i++) { 639 for ($i = 0 ; $i < $nbLinks ; $i++) {
640 $this->assertEquals(History::UPDATED, $history[$i]['event']); 640 $this->assertEquals(History::UPDATED, $history[$i]['event']);
641 $this->assertTrue(new DateTime('-5 seconds') < DateTime::createFromFormat(DateTime::ATOM, $history[$i]['datetime'])); 641 $this->assertTrue(new DateTime('-5 seconds') < $history[$i]['datetime']);
642 $this->assertTrue(is_int($history[$i]['id'])); 642 $this->assertTrue(is_int($history[$i]['id']));
643 } 643 }
644 } 644 }
diff --git a/tests/api/controllers/DeleteLinkTest.php b/tests/api/controllers/DeleteLinkTest.php
index 6894e8a2..7d797137 100644
--- a/tests/api/controllers/DeleteLinkTest.php
+++ b/tests/api/controllers/DeleteLinkTest.php
@@ -17,6 +17,11 @@ class DeleteLinkTest extends \PHPUnit_Framework_TestCase
17 protected static $testDatastore = 'sandbox/datastore.php'; 17 protected static $testDatastore = 'sandbox/datastore.php';
18 18
19 /** 19 /**
20 * @var string datastore to test write operations
21 */
22 protected static $testHistory = 'sandbox/history.php';
23
24 /**
20 * @var ConfigManager instance 25 * @var ConfigManager instance
21 */ 26 */
22 protected $conf; 27 protected $conf;
@@ -32,6 +37,11 @@ class DeleteLinkTest extends \PHPUnit_Framework_TestCase
32 protected $linkDB; 37 protected $linkDB;
33 38
34 /** 39 /**
40 * @var \History instance.
41 */
42 protected $history;
43
44 /**
35 * @var Container instance. 45 * @var Container instance.
36 */ 46 */
37 protected $container; 47 protected $container;
@@ -50,9 +60,13 @@ class DeleteLinkTest extends \PHPUnit_Framework_TestCase
50 $this->refDB = new \ReferenceLinkDB(); 60 $this->refDB = new \ReferenceLinkDB();
51 $this->refDB->write(self::$testDatastore); 61 $this->refDB->write(self::$testDatastore);
52 $this->linkDB = new \LinkDB(self::$testDatastore, true, false); 62 $this->linkDB = new \LinkDB(self::$testDatastore, true, false);
63 $refHistory = new \ReferenceHistory();
64 $refHistory->write(self::$testHistory);
65 $this->history = new \History(self::$testHistory);
53 $this->container = new Container(); 66 $this->container = new Container();
54 $this->container['conf'] = $this->conf; 67 $this->container['conf'] = $this->conf;
55 $this->container['db'] = $this->linkDB; 68 $this->container['db'] = $this->linkDB;
69 $this->container['history'] = $this->history;
56 70
57 $this->controller = new Links($this->container); 71 $this->controller = new Links($this->container);
58 } 72 }
@@ -63,6 +77,7 @@ class DeleteLinkTest extends \PHPUnit_Framework_TestCase
63 public function tearDown() 77 public function tearDown()
64 { 78 {
65 @unlink(self::$testDatastore); 79 @unlink(self::$testDatastore);
80 @unlink(self::$testHistory);
66 } 81 }
67 82
68 /** 83 /**
@@ -83,6 +98,13 @@ class DeleteLinkTest extends \PHPUnit_Framework_TestCase
83 98
84 $this->linkDB = new \LinkDB(self::$testDatastore, true, false); 99 $this->linkDB = new \LinkDB(self::$testDatastore, true, false);
85 $this->assertFalse(isset($this->linkDB[$id])); 100 $this->assertFalse(isset($this->linkDB[$id]));
101
102 $historyEntry = $this->history->getHistory()[0];
103 $this->assertEquals(\History::DELETED, $historyEntry['event']);
104 $this->assertTrue(
105 (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime']
106 );
107 $this->assertEquals($id, $historyEntry['id']);
86 } 108 }
87 109
88 /** 110 /**
diff --git a/tests/api/controllers/GetLinkIdTest.php b/tests/api/controllers/GetLinkIdTest.php
index 45b18e6a..57528d5a 100644
--- a/tests/api/controllers/GetLinkIdTest.php
+++ b/tests/api/controllers/GetLinkIdTest.php
@@ -62,6 +62,7 @@ class GetLinkIdTest extends \PHPUnit_Framework_TestCase
62 $this->container = new Container(); 62 $this->container = new Container();
63 $this->container['conf'] = $this->conf; 63 $this->container['conf'] = $this->conf;
64 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); 64 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false);
65 $this->container['history'] = null;
65 66
66 $this->controller = new Links($this->container); 67 $this->controller = new Links($this->container);
67 } 68 }
diff --git a/tests/api/controllers/GetLinksTest.php b/tests/api/controllers/GetLinksTest.php
index 10330cd9..84ae7f7a 100644
--- a/tests/api/controllers/GetLinksTest.php
+++ b/tests/api/controllers/GetLinksTest.php
@@ -61,6 +61,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase
61 $this->container = new Container(); 61 $this->container = new Container();
62 $this->container['conf'] = $this->conf; 62 $this->container['conf'] = $this->conf;
63 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); 63 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false);
64 $this->container['history'] = null;
64 65
65 $this->controller = new Links($this->container); 66 $this->controller = new Links($this->container);
66 } 67 }
diff --git a/tests/api/controllers/HistoryTest.php b/tests/api/controllers/HistoryTest.php
index 21e9c0ba..61046d97 100644
--- a/tests/api/controllers/HistoryTest.php
+++ b/tests/api/controllers/HistoryTest.php
@@ -30,11 +30,6 @@ class HistoryTest extends \PHPUnit_Framework_TestCase
30 protected $refHistory = null; 30 protected $refHistory = null;
31 31
32 /** 32 /**
33 * @var \History instance.
34 */
35 protected $history;
36
37 /**
38 * @var Container instance. 33 * @var Container instance.
39 */ 34 */
40 protected $container; 35 protected $container;
@@ -52,10 +47,10 @@ class HistoryTest extends \PHPUnit_Framework_TestCase
52 $this->conf = new ConfigManager('tests/utils/config/configJson.json.php'); 47 $this->conf = new ConfigManager('tests/utils/config/configJson.json.php');
53 $this->refHistory = new \ReferenceHistory(); 48 $this->refHistory = new \ReferenceHistory();
54 $this->refHistory->write(self::$testHistory); 49 $this->refHistory->write(self::$testHistory);
55 $this->conf->set('resource.history', self::$testHistory);
56 $this->container = new Container(); 50 $this->container = new Container();
57 $this->container['conf'] = $this->conf; 51 $this->container['conf'] = $this->conf;
58 $this->container['db'] = true; 52 $this->container['db'] = true;
53 $this->container['history'] = new \History(self::$testHistory);
59 54
60 $this->controller = new History($this->container); 55 $this->controller = new History($this->container);
61 } 56 }
diff --git a/tests/api/controllers/InfoTest.php b/tests/api/controllers/InfoTest.php
index 4beef3f7..e85eb281 100644
--- a/tests/api/controllers/InfoTest.php
+++ b/tests/api/controllers/InfoTest.php
@@ -54,6 +54,7 @@ class InfoTest extends \PHPUnit_Framework_TestCase
54 $this->container = new Container(); 54 $this->container = new Container();
55 $this->container['conf'] = $this->conf; 55 $this->container['conf'] = $this->conf;
56 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); 56 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false);
57 $this->container['history'] = null;
57 58
58 $this->controller = new Info($this->container); 59 $this->controller = new Info($this->container);
59 } 60 }
diff --git a/tests/api/controllers/PostLinkTest.php b/tests/api/controllers/PostLinkTest.php
index 3ed7bcb0..31954e39 100644
--- a/tests/api/controllers/PostLinkTest.php
+++ b/tests/api/controllers/PostLinkTest.php
@@ -24,6 +24,11 @@ class PostLinkTest extends \PHPUnit_Framework_TestCase
24 protected static $testDatastore = 'sandbox/datastore.php'; 24 protected static $testDatastore = 'sandbox/datastore.php';
25 25
26 /** 26 /**
27 * @var string datastore to test write operations
28 */
29 protected static $testHistory = 'sandbox/history.php';
30
31 /**
27 * @var ConfigManager instance 32 * @var ConfigManager instance
28 */ 33 */
29 protected $conf; 34 protected $conf;
@@ -34,6 +39,11 @@ class PostLinkTest extends \PHPUnit_Framework_TestCase
34 protected $refDB = null; 39 protected $refDB = null;
35 40
36 /** 41 /**
42 * @var \History instance.
43 */
44 protected $history;
45
46 /**
37 * @var Container instance. 47 * @var Container instance.
38 */ 48 */
39 protected $container; 49 protected $container;
@@ -57,9 +67,14 @@ class PostLinkTest extends \PHPUnit_Framework_TestCase
57 $this->refDB = new \ReferenceLinkDB(); 67 $this->refDB = new \ReferenceLinkDB();
58 $this->refDB->write(self::$testDatastore); 68 $this->refDB->write(self::$testDatastore);
59 69
70 $refHistory = new \ReferenceHistory();
71 $refHistory->write(self::$testHistory);
72 $this->history = new \History(self::$testHistory);
73
60 $this->container = new Container(); 74 $this->container = new Container();
61 $this->container['conf'] = $this->conf; 75 $this->container['conf'] = $this->conf;
62 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); 76 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false);
77 $this->container['history'] = new \History(self::$testHistory);
63 78
64 $this->controller = new Links($this->container); 79 $this->controller = new Links($this->container);
65 80
@@ -85,6 +100,7 @@ class PostLinkTest extends \PHPUnit_Framework_TestCase
85 public function tearDown() 100 public function tearDown()
86 { 101 {
87 @unlink(self::$testDatastore); 102 @unlink(self::$testDatastore);
103 @unlink(self::$testHistory);
88 } 104 }
89 105
90 /** 106 /**
@@ -112,6 +128,13 @@ class PostLinkTest extends \PHPUnit_Framework_TestCase
112 $this->assertEquals(false, $data['private']); 128 $this->assertEquals(false, $data['private']);
113 $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])); 129 $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['created']));
114 $this->assertEquals('', $data['updated']); 130 $this->assertEquals('', $data['updated']);
131
132 $historyEntry = $this->history->getHistory()[0];
133 $this->assertEquals(\History::CREATED, $historyEntry['event']);
134 $this->assertTrue(
135 (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime']
136 );
137 $this->assertEquals(43, $historyEntry['id']);
115 } 138 }
116 139
117 /** 140 /**
diff --git a/tests/api/controllers/PutLinkTest.php b/tests/api/controllers/PutLinkTest.php
index 4096c1a7..8a562571 100644
--- a/tests/api/controllers/PutLinkTest.php
+++ b/tests/api/controllers/PutLinkTest.php
@@ -18,6 +18,11 @@ class PutLinkTest extends \PHPUnit_Framework_TestCase
18 protected static $testDatastore = 'sandbox/datastore.php'; 18 protected static $testDatastore = 'sandbox/datastore.php';
19 19
20 /** 20 /**
21 * @var string datastore to test write operations
22 */
23 protected static $testHistory = 'sandbox/history.php';
24
25 /**
21 * @var ConfigManager instance 26 * @var ConfigManager instance
22 */ 27 */
23 protected $conf; 28 protected $conf;
@@ -28,6 +33,11 @@ class PutLinkTest extends \PHPUnit_Framework_TestCase
28 protected $refDB = null; 33 protected $refDB = null;
29 34
30 /** 35 /**
36 * @var \History instance.
37 */
38 protected $history;
39
40 /**
31 * @var Container instance. 41 * @var Container instance.
32 */ 42 */
33 protected $container; 43 protected $container;
@@ -51,9 +61,14 @@ class PutLinkTest extends \PHPUnit_Framework_TestCase
51 $this->refDB = new \ReferenceLinkDB(); 61 $this->refDB = new \ReferenceLinkDB();
52 $this->refDB->write(self::$testDatastore); 62 $this->refDB->write(self::$testDatastore);
53 63
64 $refHistory = new \ReferenceHistory();
65 $refHistory->write(self::$testHistory);
66 $this->history = new \History(self::$testHistory);
67
54 $this->container = new Container(); 68 $this->container = new Container();
55 $this->container['conf'] = $this->conf; 69 $this->container['conf'] = $this->conf;
56 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false); 70 $this->container['db'] = new \LinkDB(self::$testDatastore, true, false);
71 $this->container['history'] = new \History(self::$testHistory);
57 72
58 $this->controller = new Links($this->container); 73 $this->controller = new Links($this->container);
59 74
@@ -71,6 +86,7 @@ class PutLinkTest extends \PHPUnit_Framework_TestCase
71 public function tearDown() 86 public function tearDown()
72 { 87 {
73 @unlink(self::$testDatastore); 88 @unlink(self::$testDatastore);
89 @unlink(self::$testHistory);
74 } 90 }
75 91
76 /** 92 /**
@@ -100,6 +116,13 @@ class PutLinkTest extends \PHPUnit_Framework_TestCase
100 \DateTime::createFromFormat(\DateTime::ATOM, $data['created']) 116 \DateTime::createFromFormat(\DateTime::ATOM, $data['created'])
101 ); 117 );
102 $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated'])); 118 $this->assertTrue(new \DateTime('5 seconds ago') < \DateTime::createFromFormat(\DateTime::ATOM, $data['updated']));
119
120 $historyEntry = $this->history->getHistory()[0];
121 $this->assertEquals(\History::UPDATED, $historyEntry['event']);
122 $this->assertTrue(
123 (new \DateTime())->add(\DateInterval::createFromDateString('-5 seconds')) < $historyEntry['datetime']
124 );
125 $this->assertEquals($id, $historyEntry['id']);
103 } 126 }
104 127
105 /** 128 /**
diff --git a/tests/utils/ReferenceHistory.php b/tests/utils/ReferenceHistory.php
index 20284770..75cbb326 100644
--- a/tests/utils/ReferenceHistory.php
+++ b/tests/utils/ReferenceHistory.php
@@ -15,15 +15,14 @@ class ReferenceHistory
15 public function __construct() 15 public function __construct()
16 { 16 {
17 $this->addEntry( 17 $this->addEntry(
18 History::CREATED, 18 History::DELETED,
19 DateTime::createFromFormat('Ymd_His', '20170101_121212'), 19 DateTime::createFromFormat('Ymd_His', '20170303_121216'),
20 123 20 124
21 ); 21 );
22 22
23 $this->addEntry( 23 $this->addEntry(
24 History::CREATED, 24 History::SETTINGS,
25 DateTime::createFromFormat('Ymd_His', '20170201_121214'), 25 DateTime::createFromFormat('Ymd_His', '20170302_121215')
26 124
27 ); 26 );
28 27
29 $this->addEntry( 28 $this->addEntry(
@@ -33,14 +32,15 @@ class ReferenceHistory
33 ); 32 );
34 33
35 $this->addEntry( 34 $this->addEntry(
36 History::SETTINGS, 35 History::CREATED,
37 DateTime::createFromFormat('Ymd_His', '20170302_121215') 36 DateTime::createFromFormat('Ymd_His', '20170201_121214'),
37 124
38 ); 38 );
39 39
40 $this->addEntry( 40 $this->addEntry(
41 History::DELETED, 41 History::CREATED,
42 DateTime::createFromFormat('Ymd_His', '20170303_121216'), 42 DateTime::createFromFormat('Ymd_His', '20170101_121212'),
43 124 43 123
44 ); 44 );
45 } 45 }
46 46