3 namespace Shaarli\Updater
;
5 use Shaarli\Bookmark\BookmarkServiceInterface
;
6 use Shaarli\Config\ConfigManager
;
7 use Shaarli\Updater\Exception\UpdaterException
;
11 * Used to update stuff when a new Shaarli's version is reached.
12 * Update methods are ran only once, and the stored in a TXT file.
17 * @var array Updates which are already done.
19 protected $doneUpdates;
22 * @var BookmarkServiceInterface instance.
24 protected $bookmarkService;
27 * @var ConfigManager $conf Configuration Manager instance.
32 * @var bool True if the user is logged in, false otherwise.
34 protected $isLoggedIn;
37 * @var \ReflectionMethod[] List of current class methods.
42 * @var string $basePath Shaarli root directory (from HTTP Request)
44 protected $basePath = null;
49 * @param array $doneUpdates Updates which are already done.
50 * @param BookmarkServiceInterface $linkDB LinksService instance.
51 * @param ConfigManager $conf Configuration Manager instance.
52 * @param boolean $isLoggedIn True if the user is logged in.
54 public function __construct($doneUpdates, $linkDB, $conf, $isLoggedIn)
56 $this->doneUpdates
= $doneUpdates;
57 $this->bookmarkService
= $linkDB;
59 $this->isLoggedIn
= $isLoggedIn;
61 // Retrieve all update methods.
62 $class = new \
ReflectionClass($this);
63 $this->methods
= $class->getMethods();
67 * Run all new updates.
68 * Update methods have to start with 'updateMethod' and return true (on success).
70 * @param string $basePath Shaarli root directory (from HTTP Request)
72 * @return array An array containing ran updates.
74 * @throws UpdaterException If something went wrong.
76 public function update(string $basePath = null)
80 // If the user isn't logged in, exit without updating.
81 if ($this->isLoggedIn
!== true) {
85 if ($this->methods
=== null) {
86 throw new UpdaterException('Couldn\'t retrieve LegacyUpdater class methods.');
89 foreach ($this->methods
as $method) {
90 // Not an update method or already done, pass.
92 ! startsWith($method->getName(), 'updateMethod')
93 || in_array($method->getName(), $this->doneUpdates
)
99 $method->setAccessible(true);
100 $res = $method->invoke($this);
101 // Update method must return true to be considered processed.
103 $updatesRan[] = $method->getName();
105 } catch (\Exception
$e) {
106 throw new UpdaterException($method, $e);
110 $this->doneUpdates
= array_merge($this->doneUpdates
, $updatesRan);
116 * @return array Updates methods already processed.
118 public function getDoneUpdates()
120 return $this->doneUpdates
;
123 public function readUpdates(string $updatesFilepath): array
125 return UpdaterUtils
::readUpdatesFile($updatesFilepath);
128 public function writeUpdates(string $updatesFilepath, array $updates): void
130 UpdaterUtils
::writeUpdatesFile($updatesFilepath, $updates);
134 * With the Slim routing system, default header link should be `/subfolder/` instead of `?`.
135 * Otherwise you can not go back to the home page.
136 * Example: `/subfolder/picture-wall` -> `/subfolder/picture-wall?` instead of `/subfolder/`.
138 public function updateMethodRelativeHomeLink(): bool
140 if ('?' === trim($this->conf
->get('general.header_link'))) {
141 $this->conf
->set('general.header_link', $this->basePath
. '/', true, true);
148 * With the Slim routing system, note bookmarks URL formatted `?abcdef`
149 * should be replaced with `/shaare/abcdef`
151 public function updateMethodMigrateExistingNotesUrl(): bool
155 foreach ($this->bookmarkService
->search() as $bookmark) {
158 && startsWith($bookmark->getUrl(), '?')
159 && 1 === preg_match('/^\?([a-zA-Z0-9-_@]{6})($|&|#)/', $bookmark->getUrl(), $match)
162 $bookmark = $bookmark->setUrl('/shaare/' . $match[1]);
164 $this->bookmarkService
->set($bookmark, false);
169 $this->bookmarkService
->save();
175 public function setBasePath(string $basePath): self
177 $this->basePath
= $basePath;