]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - application/updater/Updater.php
Handle pagination through BookmarkService
[github/shaarli/Shaarli.git] / application / updater / Updater.php
CommitLineData
510377d2 1<?php
f24896b2 2
bcf056c9
V
3namespace Shaarli\Updater;
4
cf92b4dd 5use Shaarli\Bookmark\BookmarkServiceInterface;
485b168a 6use Shaarli\Config\ConfigManager;
bcf056c9 7use Shaarli\Updater\Exception\UpdaterException;
510377d2
A
8
9/**
cf92b4dd 10 * Class Updater.
510377d2 11 * Used to update stuff when a new Shaarli's version is reached.
cf92b4dd 12 * Update methods are ran only once, and the stored in a TXT file.
510377d2
A
13 */
14class Updater
15{
16 /**
17 * @var array Updates which are already done.
18 */
19 protected $doneUpdates;
20
510377d2 21 /**
cf92b4dd 22 * @var BookmarkServiceInterface instance.
510377d2 23 */
1a8ac737 24 protected $bookmarkService;
510377d2 25
278d9ee2
A
26 /**
27 * @var ConfigManager $conf Configuration Manager instance.
28 */
29 protected $conf;
30
510377d2
A
31 /**
32 * @var bool True if the user is logged in, false otherwise.
33 */
34 protected $isLoggedIn;
35
28f26524 36 /**
cf92b4dd 37 * @var \ReflectionMethod[] List of current class methods.
510377d2
A
38 */
39 protected $methods;
40
c4ad3d4f
A
41 /**
42 * @var string $basePath Shaarli root directory (from HTTP Request)
43 */
44 protected $basePath = null;
45
510377d2
A
46 /**
47 * Object constructor.
48 *
cf92b4dd
A
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.
510377d2 53 */
cf92b4dd 54 public function __construct($doneUpdates, $linkDB, $conf, $isLoggedIn)
510377d2
A
55 {
56 $this->doneUpdates = $doneUpdates;
1a8ac737 57 $this->bookmarkService = $linkDB;
278d9ee2 58 $this->conf = $conf;
510377d2
A
59 $this->isLoggedIn = $isLoggedIn;
60
61 // Retrieve all update methods.
cf92b4dd 62 $class = new \ReflectionClass($this);
510377d2
A
63 $this->methods = $class->getMethods();
64 }
65
66 /**
67 * Run all new updates.
68 * Update methods have to start with 'updateMethod' and return true (on success).
69 *
c4ad3d4f
A
70 * @param string $basePath Shaarli root directory (from HTTP Request)
71 *
510377d2
A
72 * @return array An array containing ran updates.
73 *
74 * @throws UpdaterException If something went wrong.
75 */
c4ad3d4f 76 public function update(string $basePath = null)
510377d2 77 {
1a8ac737 78 $updatesRan = [];
510377d2
A
79
80 // If the user isn't logged in, exit without updating.
81 if ($this->isLoggedIn !== true) {
82 return $updatesRan;
83 }
84
ee6f4b64 85 if ($this->methods === null) {
cf92b4dd 86 throw new UpdaterException('Couldn\'t retrieve LegacyUpdater class methods.');
510377d2
A
87 }
88
89 foreach ($this->methods as $method) {
90 // Not an update method or already done, pass.
53054b2b
A
91 if (
92 ! startsWith($method->getName(), 'updateMethod')
510377d2
A
93 || in_array($method->getName(), $this->doneUpdates)
94 ) {
95 continue;
96 }
97
98 try {
99 $method->setAccessible(true);
100 $res = $method->invoke($this);
101 // Update method must return true to be considered processed.
102 if ($res === true) {
103 $updatesRan[] = $method->getName();
104 }
cf92b4dd 105 } catch (\Exception $e) {
510377d2
A
106 throw new UpdaterException($method, $e);
107 }
108 }
109
110 $this->doneUpdates = array_merge($this->doneUpdates, $updatesRan);
111
112 return $updatesRan;
113 }
114
115 /**
116 * @return array Updates methods already processed.
117 */
118 public function getDoneUpdates()
119 {
120 return $this->doneUpdates;
121 }
485b168a 122
1a8ac737
A
123 public function readUpdates(string $updatesFilepath): array
124 {
b99e00f7 125 return UpdaterUtils::readUpdatesFile($updatesFilepath);
1a8ac737
A
126 }
127
128 public function writeUpdates(string $updatesFilepath, array $updates): void
129 {
b99e00f7 130 UpdaterUtils::writeUpdatesFile($updatesFilepath, $updates);
1a8ac737
A
131 }
132
485b168a 133 /**
c4ad3d4f
A
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/`.
485b168a
A
137 */
138 public function updateMethodRelativeHomeLink(): bool
139 {
c4ad3d4f
A
140 if ('?' === trim($this->conf->get('general.header_link'))) {
141 $this->conf->set('general.header_link', $this->basePath . '/', true, true);
485b168a
A
142 }
143
144 return true;
145 }
1a8ac737
A
146
147 /**
148 * With the Slim routing system, note bookmarks URL formatted `?abcdef`
149 * should be replaced with `/shaare/abcdef`
150 */
151 public function updateMethodMigrateExistingNotesUrl(): bool
152 {
153 $updated = false;
154
9b8c0a45 155 foreach ($this->bookmarkService->search()->getBookmarks() as $bookmark) {
53054b2b
A
156 if (
157 $bookmark->isNote()
1a8ac737
A
158 && startsWith($bookmark->getUrl(), '?')
159 && 1 === preg_match('/^\?([a-zA-Z0-9-_@]{6})($|&|#)/', $bookmark->getUrl(), $match)
160 ) {
161 $updated = true;
f7f08cee 162 $bookmark = $bookmark->setUrl('/shaare/' . $match[1]);
1a8ac737
A
163
164 $this->bookmarkService->set($bookmark, false);
165 }
166 }
167
168 if ($updated) {
169 $this->bookmarkService->save();
170 }
171
172 return true;
173 }
c4ad3d4f
A
174
175 public function setBasePath(string $basePath): self
176 {
177 $this->basePath = $basePath;
178
179 return $this;
180 }
510377d2 181}