MyShaarli/application/updater/Updater.php

191 lines
5.4 KiB
PHP
Raw Permalink Normal View History

<?php
namespace Shaarli\Updater;
2023-05-24 11:35:15 +02:00
use Shaarli\Bookmark\BookmarkServiceInterface;
2017-03-09 20:51:28 +01:00
use Shaarli\Config\ConfigManager;
use Shaarli\Updater\Exception\UpdaterException;
/**
2023-05-24 11:35:15 +02:00
* Class Updater.
* Used to update stuff when a new Shaarli's version is reached.
2023-05-24 11:35:15 +02:00
* Update methods are ran only once, and the stored in a TXT file.
*/
class Updater
{
/**
* @var array Updates which are already done.
*/
protected $doneUpdates;
/**
2023-05-24 11:35:15 +02:00
* @var BookmarkServiceInterface instance.
*/
2023-05-24 11:35:15 +02:00
protected $bookmarkService;
/**
* @var ConfigManager $conf Configuration Manager instance.
*/
protected $conf;
/**
* @var bool True if the user is logged in, false otherwise.
*/
protected $isLoggedIn;
/**
2023-05-24 11:35:15 +02:00
* @var \ReflectionMethod[] List of current class methods.
*/
2023-05-24 11:35:15 +02:00
protected $methods;
/**
2023-05-24 11:35:15 +02:00
* @var string $basePath Shaarli root directory (from HTTP Request)
*/
2023-05-24 11:35:15 +02:00
protected $basePath = null;
/**
* Object constructor.
*
2023-05-24 11:35:15 +02:00
* @param array $doneUpdates Updates which are already done.
* @param BookmarkServiceInterface $linkDB LinksService instance.
* @param ConfigManager $conf Configuration Manager instance.
* @param boolean $isLoggedIn True if the user is logged in.
*/
2023-05-24 11:35:15 +02:00
public function __construct($doneUpdates, $linkDB, $conf, $isLoggedIn)
{
$this->doneUpdates = $doneUpdates;
2023-05-24 11:35:15 +02:00
$this->bookmarkService = $linkDB;
$this->conf = $conf;
$this->isLoggedIn = $isLoggedIn;
// Retrieve all update methods.
2023-05-24 11:35:15 +02:00
$class = new \ReflectionClass($this);
$this->methods = $class->getMethods();
}
/**
* Run all new updates.
* Update methods have to start with 'updateMethod' and return true (on success).
*
2023-05-24 11:35:15 +02:00
* @param string $basePath Shaarli root directory (from HTTP Request)
*
* @return array An array containing ran updates.
*
* @throws UpdaterException If something went wrong.
*/
2023-05-24 11:35:15 +02:00
public function update(string $basePath = null)
{
2023-05-24 11:35:15 +02:00
$updatesRan = [];
// If the user isn't logged in, exit without updating.
if ($this->isLoggedIn !== true) {
return $updatesRan;
}
if ($this->methods === null) {
2023-05-24 11:35:15 +02:00
throw new UpdaterException('Couldn\'t retrieve LegacyUpdater class methods.');
}
foreach ($this->methods as $method) {
// Not an update method or already done, pass.
2023-05-24 11:35:15 +02:00
if (
! startsWith($method->getName(), 'updateMethod')
|| in_array($method->getName(), $this->doneUpdates)
) {
continue;
}
try {
$method->setAccessible(true);
$res = $method->invoke($this);
// Update method must return true to be considered processed.
if ($res === true) {
$updatesRan[] = $method->getName();
}
2023-05-24 11:35:15 +02:00
} catch (\Exception $e) {
throw new UpdaterException($method, $e);
}
}
$this->doneUpdates = array_merge($this->doneUpdates, $updatesRan);
return $updatesRan;
}
/**
* @return array Updates methods already processed.
*/
public function getDoneUpdates()
{
return $this->doneUpdates;
}
2023-05-24 11:35:15 +02:00
public function readUpdates(string $updatesFilepath): array
{
2023-05-24 11:35:15 +02:00
return UpdaterUtils::readUpdatesFile($updatesFilepath);
}
2023-05-24 11:35:15 +02:00
public function writeUpdates(string $updatesFilepath, array $updates): void
{
2023-05-24 11:35:15 +02:00
UpdaterUtils::writeUpdatesFile($updatesFilepath, $updates);
}
/**
2023-05-24 11:35:15 +02:00
* With the Slim routing system, default header link should be `/subfolder/` instead of `?`.
* Otherwise you can not go back to the home page.
* Example: `/subfolder/picture-wall` -> `/subfolder/picture-wall?` instead of `/subfolder/`.
*/
2023-05-24 11:35:15 +02:00
public function updateMethodRelativeHomeLink(): bool
{
2023-05-24 11:35:15 +02:00
if ('?' === trim($this->conf->get('general.header_link'))) {
$this->conf->set('general.header_link', $this->basePath . '/', true, true);
}
return true;
}
2017-01-14 16:43:32 +01:00
/**
2023-05-24 11:35:15 +02:00
* With the Slim routing system, note bookmarks URL formatted `?abcdef`
* should be replaced with `/shaare/abcdef`
2017-01-14 16:43:32 +01:00
*/
2023-05-24 11:35:15 +02:00
public function updateMethodMigrateExistingNotesUrl(): bool
2017-01-14 16:43:32 +01:00
{
2023-05-24 11:35:15 +02:00
$updated = false;
2023-05-24 11:35:15 +02:00
foreach ($this->bookmarkService->search()->getBookmarks() as $bookmark) {
if (
$bookmark->isNote()
&& startsWith($bookmark->getUrl(), '?')
&& 1 === preg_match('/^\?([a-zA-Z0-9-_@]{6})($|&|#)/', $bookmark->getUrl(), $match)
) {
$updated = true;
$bookmark = $bookmark->setUrl('/shaare/' . $match[1]);
2023-05-24 11:35:15 +02:00
$this->bookmarkService->set($bookmark, false);
}
}
2023-05-24 11:35:15 +02:00
if ($updated) {
$this->bookmarkService->save();
}
return true;
}
2024-12-10 16:31:21 +01:00
public function updateMethodRemoveSettingRemoteBranch(): bool
{
if ($this->conf->exists('updates.check_updates_branch')) {
$this->conf->remove('updates.check_updates_branch', true, true);
}
return true;
}
2023-05-24 11:35:15 +02:00
public function setBasePath(string $basePath): self
{
2023-05-24 11:35:15 +02:00
$this->basePath = $basePath;
2023-05-24 11:35:15 +02:00
return $this;
}
}