Merge pull request #1635 from ArthurHoaro/feature/phpcs

This commit is contained in:
ArthurHoaro 2020-11-10 10:46:04 +01:00 committed by GitHub
commit 302662797c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
95 changed files with 480 additions and 386 deletions

View file

@ -49,6 +49,10 @@ cache:
directories: directories:
- $HOME/.composer/cache - $HOME/.composer/cache
before_install:
# Disable xdebug: it significantly speed up tests and linter, and we don't use coverage yet
- phpenv config-rm xdebug.ini || echo 'No xdebug config.'
install: install:
# install/update composer and php dependencies # install/update composer and php dependencies
- composer config --unset platform && composer config platform.php $TRAVIS_PHP_VERSION - composer config --unset platform && composer config platform.php $TRAVIS_PHP_VERSION
@ -60,4 +64,5 @@ before_script:
script: script:
- make clean - make clean
- make check_permissions - make check_permissions
- make code_sniffer
- make all_tests - make all_tests

View file

@ -27,10 +27,6 @@ PHPCS := $(BIN)/phpcs
code_sniffer: code_sniffer:
@$(PHPCS) @$(PHPCS)
### - errors filtered by coding standard: PEAR, PSR1, PSR2, Zend...
PHPCS_%:
@$(PHPCS) --report-full --report-width=200 --standard=$*
### - errors by Git author ### - errors by Git author
code_sniffer_blame: code_sniffer_blame:
@$(PHPCS) --report-gitblame @$(PHPCS) --report-gitblame

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli; namespace Shaarli;
use DateTime; use DateTime;
@ -31,27 +32,27 @@ class History
/** /**
* @var string Action key: a new link has been created. * @var string Action key: a new link has been created.
*/ */
const CREATED = 'CREATED'; public const CREATED = 'CREATED';
/** /**
* @var string Action key: a link has been updated. * @var string Action key: a link has been updated.
*/ */
const UPDATED = 'UPDATED'; public const UPDATED = 'UPDATED';
/** /**
* @var string Action key: a link has been deleted. * @var string Action key: a link has been deleted.
*/ */
const DELETED = 'DELETED'; public const DELETED = 'DELETED';
/** /**
* @var string Action key: settings have been updated. * @var string Action key: settings have been updated.
*/ */
const SETTINGS = 'SETTINGS'; public const SETTINGS = 'SETTINGS';
/** /**
* @var string Action key: a bulk import has been processed. * @var string Action key: a bulk import has been processed.
*/ */
const IMPORT = 'IMPORT'; public const IMPORT = 'IMPORT';
/** /**
* @var string History file path. * @var string History file path.

View file

@ -41,7 +41,7 @@ class Languages
/** /**
* Core translations domain * Core translations domain
*/ */
const DEFAULT_DOMAIN = 'shaarli'; public const DEFAULT_DOMAIN = 'shaarli';
/** /**
* @var TranslatorInterface * @var TranslatorInterface
@ -76,7 +76,8 @@ public function __construct($language, $conf)
$this->language = $confLanguage; $this->language = $confLanguage;
} }
if (! extension_loaded('gettext') if (
! extension_loaded('gettext')
|| in_array($this->conf->get('translation.mode', 'auto'), ['auto', 'php']) || in_array($this->conf->get('translation.mode', 'auto'), ['auto', 'php'])
) { ) {
$this->initPhpTranslator(); $this->initPhpTranslator();
@ -98,7 +99,7 @@ protected function initGettextTranslator()
$this->translator->loadDomain(self::DEFAULT_DOMAIN, 'inc/languages'); $this->translator->loadDomain(self::DEFAULT_DOMAIN, 'inc/languages');
// Default extension translation from the current theme // Default extension translation from the current theme
$themeTransFolder = rtrim($this->conf->get('raintpl_tpl'), '/') .'/'. $this->conf->get('theme') .'/language'; $themeTransFolder = rtrim($this->conf->get('raintpl_tpl'), '/') . '/' . $this->conf->get('theme') . '/language';
if (is_dir($themeTransFolder)) { if (is_dir($themeTransFolder)) {
$this->translator->loadDomain($this->conf->get('theme'), $themeTransFolder, false); $this->translator->loadDomain($this->conf->get('theme'), $themeTransFolder, false);
} }
@ -121,7 +122,9 @@ protected function initPhpTranslator()
$translations = new Translations(); $translations = new Translations();
// Core translations // Core translations
try { try {
$translations = $translations->addFromPoFile('inc/languages/'. $this->language .'/LC_MESSAGES/shaarli.po'); $translations = $translations->addFromPoFile(
'inc/languages/' . $this->language . '/LC_MESSAGES/shaarli.po'
);
$translations->setDomain('shaarli'); $translations->setDomain('shaarli');
$this->translator->loadTranslations($translations); $this->translator->loadTranslations($translations);
} catch (\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
@ -129,11 +132,11 @@ protected function initPhpTranslator()
// Default extension translation from the current theme // Default extension translation from the current theme
$theme = $this->conf->get('theme'); $theme = $this->conf->get('theme');
$themeTransFolder = rtrim($this->conf->get('raintpl_tpl'), '/') .'/'. $theme .'/language'; $themeTransFolder = rtrim($this->conf->get('raintpl_tpl'), '/') . '/' . $theme . '/language';
if (is_dir($themeTransFolder)) { if (is_dir($themeTransFolder)) {
try { try {
$translations = Translations::fromPoFile( $translations = Translations::fromPoFile(
$themeTransFolder .'/'. $this->language .'/LC_MESSAGES/'. $theme .'.po' $themeTransFolder . '/' . $this->language . '/LC_MESSAGES/' . $theme . '.po'
); );
$translations->setDomain($theme); $translations->setDomain($theme);
$this->translator->loadTranslations($translations); $this->translator->loadTranslations($translations);
@ -149,7 +152,7 @@ protected function initPhpTranslator()
try { try {
$extension = Translations::fromPoFile( $extension = Translations::fromPoFile(
$translationPath . $this->language .'/LC_MESSAGES/'. $domain .'.po' $translationPath . $this->language . '/LC_MESSAGES/' . $domain . '.po'
); );
$extension->setDomain($domain); $extension->setDomain($domain);
$this->translator->loadTranslations($extension); $this->translator->loadTranslations($extension);

View file

@ -13,7 +13,7 @@
*/ */
class Thumbnailer class Thumbnailer
{ {
const COMMON_MEDIA_DOMAINS = [ protected const COMMON_MEDIA_DOMAINS = [
'imgur.com', 'imgur.com',
'flickr.com', 'flickr.com',
'youtube.com', 'youtube.com',
@ -31,9 +31,9 @@ class Thumbnailer
'deviantart.com', 'deviantart.com',
]; ];
const MODE_ALL = 'all'; public const MODE_ALL = 'all';
const MODE_COMMON = 'common'; public const MODE_COMMON = 'common';
const MODE_NONE = 'none'; public const MODE_NONE = 'none';
/** /**
* @var WebThumbnailer instance. * @var WebThumbnailer instance.
@ -60,7 +60,7 @@ public function __construct($conf)
// TODO: create a proper error handling system able to catch exceptions... // TODO: create a proper error handling system able to catch exceptions...
die(t( die(t(
'php-gd extension must be loaded to use thumbnails. ' 'php-gd extension must be loaded to use thumbnails. '
.'Thumbnails are now disabled. Please reload the page.' . 'Thumbnails are now disabled. Please reload the page.'
)); ));
} }
@ -81,7 +81,8 @@ public function __construct($conf)
*/ */
public function get($url) public function get($url)
{ {
if ($this->conf->get('thumbnails.mode') === self::MODE_COMMON if (
$this->conf->get('thumbnails.mode') === self::MODE_COMMON
&& ! $this->isCommonMediaOrImage($url) && ! $this->isCommonMediaOrImage($url)
) { ) {
return false; return false;

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Generates a list of available timezone continents and cities. * Generates a list of available timezone continents and cities.
* *
@ -43,7 +44,7 @@ function generateTimeZoneData($installedTimeZones, $preselectedTimezone = '')
// Try to split the provided timezone // Try to split the provided timezone
$spos = strpos($preselectedTimezone, '/'); $spos = strpos($preselectedTimezone, '/');
$pcontinent = substr($preselectedTimezone, 0, $spos); $pcontinent = substr($preselectedTimezone, 0, $spos);
$pcity = substr($preselectedTimezone, $spos+1); $pcity = substr($preselectedTimezone, $spos + 1);
} }
$continents = []; $continents = [];
@ -60,7 +61,7 @@ function generateTimeZoneData($installedTimeZones, $preselectedTimezone = '')
} }
$continent = substr($tz, 0, $spos); $continent = substr($tz, 0, $spos);
$city = substr($tz, $spos+1); $city = substr($tz, $spos + 1);
$cities[] = ['continent' => $continent, 'city' => $city]; $cities[] = ['continent' => $continent, 'city' => $city];
$continents[$continent] = true; $continents[$continent] = true;
} }
@ -85,7 +86,7 @@ function generateTimeZoneData($installedTimeZones, $preselectedTimezone = '')
function isTimeZoneValid($continent, $city) function isTimeZoneValid($continent, $city)
{ {
return in_array( return in_array(
$continent.'/'.$city, $continent . '/' . $city,
timezone_identifiers_list() timezone_identifiers_list()
); );
} }

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Shaarli utilities * Shaarli utilities
*/ */
@ -102,7 +103,7 @@ function escape($input)
} }
if (is_array($input)) { if (is_array($input)) {
$out = array(); $out = [];
foreach ($input as $key => $value) { foreach ($input as $key => $value) {
$out[escape($key)] = escape($value); $out[escape($key)] = escape($value);
} }
@ -163,7 +164,7 @@ function checkDateFormat($format, $string)
* *
* @return string $referer - final referer. * @return string $referer - final referer.
*/ */
function generateLocation($referer, $host, $loopTerms = array()) function generateLocation($referer, $host, $loopTerms = [])
{ {
$finalReferer = './?'; $finalReferer = './?';
@ -196,7 +197,7 @@ function generateLocation($referer, $host, $loopTerms = array())
function autoLocale($headerLocale) function autoLocale($headerLocale)
{ {
// Default if browser does not send HTTP_ACCEPT_LANGUAGE // Default if browser does not send HTTP_ACCEPT_LANGUAGE
$locales = array('en_US', 'en_US.utf8', 'en_US.UTF-8'); $locales = ['en_US', 'en_US.utf8', 'en_US.UTF-8'];
if (! empty($headerLocale)) { if (! empty($headerLocale)) {
if (preg_match_all('/([a-z]{2,3})[-_]?([a-z]{2})?,?/i', $headerLocale, $matches, PREG_SET_ORDER)) { if (preg_match_all('/([a-z]{2,3})[-_]?([a-z]{2})?,?/i', $headerLocale, $matches, PREG_SET_ORDER)) {
$attempts = []; $attempts = [];
@ -376,13 +377,15 @@ function return_bytes($val)
return $val; return $val;
} }
$val = trim($val); $val = trim($val);
$last = strtolower($val[strlen($val)-1]); $last = strtolower($val[strlen($val) - 1]);
$val = intval(substr($val, 0, -1)); $val = intval(substr($val, 0, -1));
switch ($last) { switch ($last) {
case 'g': case 'g':
$val *= 1024; $val *= 1024;
// do no break in order 1024^2 for each unit
case 'm': case 'm':
$val *= 1024; $val *= 1024;
// do no break in order 1024^2 for each unit
case 'k': case 'k':
$val *= 1024; $val *= 1024;
} }
@ -482,7 +485,9 @@ function alphabetical_sort(&$data, $reverse = false, $byKeys = false)
*/ */
function t($text, $nText = '', $nb = 1, $domain = 'shaarli', $variables = [], $fixCase = false) function t($text, $nText = '', $nb = 1, $domain = 'shaarli', $variables = [], $fixCase = false)
{ {
$postFunction = $fixCase ? 'ucfirst' : function ($input) { return $input; }; $postFunction = $fixCase ? 'ucfirst' : function ($input) {
return $input;
};
return $postFunction(dn__($domain, $text, $nText, $nb, $variables)); return $postFunction(dn__($domain, $text, $nText, $nb, $variables));
} }
@ -494,4 +499,3 @@ function exception2text(Throwable $e): string
{ {
return $e->getMessage() . PHP_EOL . $e->getFile() . $e->getLine() . PHP_EOL . $e->getTraceAsString(); return $e->getMessage() . PHP_EOL . $e->getFile() . $e->getLine() . PHP_EOL . $e->getTraceAsString();
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Api; namespace Shaarli\Api;
use malkusch\lock\mutex\FlockMutex; use malkusch\lock\mutex\FlockMutex;
@ -108,7 +109,8 @@ protected function checkRequest($request)
*/ */
protected function checkToken($request) protected function checkToken($request)
{ {
if (!$request->hasHeader('Authorization') if (
!$request->hasHeader('Authorization')
&& !isset($this->container->environment['REDIRECT_HTTP_AUTHORIZATION']) && !isset($this->container->environment['REDIRECT_HTTP_AUTHORIZATION'])
) { ) {
throw new ApiAuthorizationException('JWT token not provided'); throw new ApiAuthorizationException('JWT token not provided');

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Api; namespace Shaarli\Api;
use Shaarli\Api\Exceptions\ApiAuthorizationException; use Shaarli\Api\Exceptions\ApiAuthorizationException;
@ -27,7 +28,7 @@ public static function validateJwtToken($token, $secret)
throw new ApiAuthorizationException('Malformed JWT token'); throw new ApiAuthorizationException('Malformed JWT token');
} }
$genSign = Base64Url::encode(hash_hmac('sha512', $parts[0] .'.'. $parts[1], $secret, true)); $genSign = Base64Url::encode(hash_hmac('sha512', $parts[0] . '.' . $parts[1], $secret, true));
if ($parts[2] != $genSign) { if ($parts[2] != $genSign) {
throw new ApiAuthorizationException('Invalid JWT signature'); throw new ApiAuthorizationException('Invalid JWT signature');
} }
@ -42,7 +43,8 @@ public static function validateJwtToken($token, $secret)
throw new ApiAuthorizationException('Invalid JWT payload'); throw new ApiAuthorizationException('Invalid JWT payload');
} }
if (empty($payload->iat) if (
empty($payload->iat)
|| $payload->iat > time() || $payload->iat > time()
|| time() - $payload->iat > ApiMiddleware::$TOKEN_DURATION || time() - $payload->iat > ApiMiddleware::$TOKEN_DURATION
) { ) {

View file

@ -1,6 +1,5 @@
<?php <?php
namespace Shaarli\Api\Controllers; namespace Shaarli\Api\Controllers;
use Shaarli\Api\Exceptions\ApiBadParametersException; use Shaarli\Api\Exceptions\ApiBadParametersException;

View file

@ -29,13 +29,13 @@ public function getInfo($request, $response)
$info = [ $info = [
'global_counter' => $this->bookmarkService->count(), 'global_counter' => $this->bookmarkService->count(),
'private_counter' => $this->bookmarkService->count(BookmarkFilter::$PRIVATE), 'private_counter' => $this->bookmarkService->count(BookmarkFilter::$PRIVATE),
'settings' => array( 'settings' => [
'title' => $this->conf->get('general.title', 'Shaarli'), 'title' => $this->conf->get('general.title', 'Shaarli'),
'header_link' => $this->conf->get('general.header_link', '?'), 'header_link' => $this->conf->get('general.header_link', '?'),
'timezone' => $this->conf->get('general.timezone', 'UTC'), 'timezone' => $this->conf->get('general.timezone', 'UTC'),
'enabled_plugins' => $this->conf->get('general.enabled_plugins', []), 'enabled_plugins' => $this->conf->get('general.enabled_plugins', []),
'default_private_links' => $this->conf->get('privacy.default_private_links', false), 'default_private_links' => $this->conf->get('privacy.default_private_links', false),
), ],
]; ];
return $response->withJson($info, 200, $this->jsonStyle); return $response->withJson($info, 200, $this->jsonStyle);

View file

@ -119,7 +119,8 @@ public function postLink($request, $response)
$data = (array) ($request->getParsedBody() ?? []); $data = (array) ($request->getParsedBody() ?? []);
$bookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links')); $bookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links'));
// duplicate by URL, return 409 Conflict // duplicate by URL, return 409 Conflict
if (! empty($bookmark->getUrl()) if (
! empty($bookmark->getUrl())
&& ! empty($dup = $this->bookmarkService->findByUrl($bookmark->getUrl())) && ! empty($dup = $this->bookmarkService->findByUrl($bookmark->getUrl()))
) { ) {
return $response->withJson( return $response->withJson(
@ -159,7 +160,8 @@ public function putLink($request, $response, $args)
$requestBookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links')); $requestBookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links'));
// duplicate URL on a different link, return 409 Conflict // duplicate URL on a different link, return 409 Conflict
if (! empty($requestBookmark->getUrl()) if (
! empty($requestBookmark->getUrl())
&& ! empty($dup = $this->bookmarkService->findByUrl($requestBookmark->getUrl())) && ! empty($dup = $this->bookmarkService->findByUrl($requestBookmark->getUrl()))
&& $dup->getId() != $id && $dup->getId() != $id
) { ) {

View file

@ -28,7 +28,7 @@ public function getApiResponse()
*/ */
public function setMessage($message) public function setMessage($message)
{ {
$original = $this->debug === true ? ': '. $this->getMessage() : ''; $original = $this->debug === true ? ': ' . $this->getMessage() : '';
$this->message = $message . $original; $this->message = $message . $original;
} }
} }

View file

@ -44,7 +44,7 @@ protected function getApiResponseBody()
} }
return [ return [
'message' => $this->getMessage(), 'message' => $this->getMessage(),
'stacktrace' => get_class($this) .': '. $this->getTraceAsString() 'stacktrace' => get_class($this) . ': ' . $this->getTraceAsString()
]; ];
} }

View file

@ -19,7 +19,7 @@
class Bookmark class Bookmark
{ {
/** @var string Date format used in string (former ID format) */ /** @var string Date format used in string (former ID format) */
const LINK_DATE_FORMAT = 'Ymd_His'; public const LINK_DATE_FORMAT = 'Ymd_His';
/** @var int Bookmark ID */ /** @var int Bookmark ID */
protected $id; protected $id;
@ -106,7 +106,8 @@ public function fromArray(array $data, string $tagsSeparator = ' '): Bookmark
*/ */
public function validate(): void public function validate(): void
{ {
if ($this->id === null if (
$this->id === null
|| ! is_int($this->id) || ! is_int($this->id)
|| empty($this->shortUrl) || empty($this->shortUrl)
|| empty($this->created) || empty($this->created)
@ -114,7 +115,7 @@ public function validate(): void
throw new InvalidBookmarkException($this); throw new InvalidBookmarkException($this);
} }
if (empty($this->url)) { if (empty($this->url)) {
$this->url = '/shaare/'. $this->shortUrl; $this->url = '/shaare/' . $this->shortUrl;
} }
if (empty($this->title)) { if (empty($this->title)) {
$this->title = $this->url; $this->title = $this->url;

View file

@ -72,7 +72,8 @@ public function count()
*/ */
public function offsetSet($offset, $value) public function offsetSet($offset, $value)
{ {
if (! $value instanceof Bookmark if (
! $value instanceof Bookmark
|| $value->getId() === null || empty($value->getUrl()) || $value->getId() === null || empty($value->getUrl())
|| ($offset !== null && ! is_int($offset)) || ! is_int($value->getId()) || ($offset !== null && ! is_int($offset)) || ! is_int($value->getId())
|| $offset !== null && $offset !== $value->getId() || $offset !== null && $offset !== $value->getId()
@ -222,7 +223,8 @@ public function getNextId(): int
*/ */
public function getByUrl(string $url): ?Bookmark public function getByUrl(string $url): ?Bookmark
{ {
if (! empty($url) if (
! empty($url)
&& isset($this->urls[$url]) && isset($this->urls[$url])
&& isset($this->bookmarks[$this->urls[$url]]) && isset($this->bookmarks[$this->urls[$url]])
) { ) {

View file

@ -69,7 +69,7 @@ public function __construct(ConfigManager $conf, History $history, Mutex $mutex,
} else { } else {
try { try {
$this->bookmarks = $this->bookmarksIO->read(); $this->bookmarks = $this->bookmarksIO->read();
} catch (EmptyDataStoreException|DatastoreNotInitializedException $e) { } catch (EmptyDataStoreException | DatastoreNotInitializedException $e) {
$this->bookmarks = new BookmarkArray(); $this->bookmarks = new BookmarkArray();
if ($this->isLoggedIn) { if ($this->isLoggedIn) {
@ -85,7 +85,7 @@ public function __construct(ConfigManager $conf, History $history, Mutex $mutex,
if (! $this->bookmarks instanceof BookmarkArray) { if (! $this->bookmarks instanceof BookmarkArray) {
$this->migrate(); $this->migrate();
exit( exit(
'Your data store has been migrated, please reload the page.'. PHP_EOL . 'Your data store has been migrated, please reload the page.' . PHP_EOL .
'If this message keeps showing up, please delete data/updates.txt file.' 'If this message keeps showing up, please delete data/updates.txt file.'
); );
} }
@ -102,7 +102,8 @@ public function findByHash(string $hash, string $privateKey = null): Bookmark
$bookmark = $this->bookmarkFilter->filter(BookmarkFilter::$FILTER_HASH, $hash); $bookmark = $this->bookmarkFilter->filter(BookmarkFilter::$FILTER_HASH, $hash);
// PHP 7.3 introduced array_key_first() to avoid this hack // PHP 7.3 introduced array_key_first() to avoid this hack
$first = reset($bookmark); $first = reset($bookmark);
if (!$this->isLoggedIn if (
!$this->isLoggedIn
&& $first->isPrivate() && $first->isPrivate()
&& (empty($privateKey) || $privateKey !== $first->getAdditionalContentEntry('private_key')) && (empty($privateKey) || $privateKey !== $first->getAdditionalContentEntry('private_key'))
) { ) {
@ -165,7 +166,8 @@ public function get(int $id, string $visibility = null): Bookmark
} }
$bookmark = $this->bookmarks[$id]; $bookmark = $this->bookmarks[$id];
if (($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private') if (
($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private')
|| (! $bookmark->isPrivate() && $visibility != 'all' && $visibility != 'public') || (! $bookmark->isPrivate() && $visibility != 'all' && $visibility != 'public')
) { ) {
throw new Exception('Unauthorized'); throw new Exception('Unauthorized');
@ -265,7 +267,8 @@ public function exists(int $id, string $visibility = null): bool
} }
$bookmark = $this->bookmarks[$id]; $bookmark = $this->bookmarks[$id];
if (($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private') if (
($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private')
|| (! $bookmark->isPrivate() && $visibility != 'all' && $visibility != 'public') || (! $bookmark->isPrivate() && $visibility != 'all' && $visibility != 'public')
) { ) {
return false; return false;
@ -307,7 +310,8 @@ public function bookmarksCountPerTag(array $filteringTags = [], string $visibili
$caseMapping = []; $caseMapping = [];
foreach ($bookmarks as $bookmark) { foreach ($bookmarks as $bookmark) {
foreach ($bookmark->getTags() as $tag) { foreach ($bookmark->getTags() as $tag) {
if (empty($tag) if (
empty($tag)
|| (! $this->isLoggedIn && startsWith($tag, '.')) || (! $this->isLoggedIn && startsWith($tag, '.'))
|| $tag === BookmarkMarkdownFormatter::NO_MD_TAG || $tag === BookmarkMarkdownFormatter::NO_MD_TAG
|| in_array($tag, $filteringTags, true) || in_array($tag, $filteringTags, true)
@ -356,7 +360,7 @@ public function findByDate(
foreach ($this->search([], null, false, false, true) as $bookmark) { foreach ($this->search([], null, false, false, true) as $bookmark) {
if ($to < $bookmark->getCreated()) { if ($to < $bookmark->getCreated()) {
$next = $bookmark->getCreated(); $next = $bookmark->getCreated();
} else if ($from < $bookmark->getCreated() && $to > $bookmark->getCreated()) { } elseif ($from < $bookmark->getCreated() && $to > $bookmark->getCreated()) {
$out[] = $bookmark; $out[] = $bookmark;
} else { } else {
if ($previous !== null) { if ($previous !== null) {
@ -405,14 +409,14 @@ protected function migrate(): void
false false
); );
$updater = new LegacyUpdater( $updater = new LegacyUpdater(
UpdaterUtils::read_updates_file($this->conf->get('resource.updates')), UpdaterUtils::readUpdatesFile($this->conf->get('resource.updates')),
$bookmarkDb, $bookmarkDb,
$this->conf, $this->conf,
true true
); );
$newUpdates = $updater->update(); $newUpdates = $updater->update();
if (! empty($newUpdates)) { if (! empty($newUpdates)) {
UpdaterUtils::write_updates_file( UpdaterUtils::writeUpdatesFile(
$this->conf->get('resource.updates'), $this->conf->get('resource.updates'),
$updater->getDoneUpdates() $updater->getDoneUpdates()
); );

View file

@ -150,7 +150,7 @@ private function noFilter(string $visibility = 'all')
return $this->bookmarks; return $this->bookmarks;
} }
$out = array(); $out = [];
foreach ($this->bookmarks as $key => $value) { foreach ($this->bookmarks as $key => $value) {
if ($value->isPrivate() && $visibility === 'private') { if ($value->isPrivate() && $visibility === 'private') {
$out[$key] = $value; $out[$key] = $value;
@ -395,7 +395,7 @@ public function filterTags($tags, bool $casesensitive = false, string $visibilit
$search = $link->getTagsString($tagsSeparator); $search = $link->getTagsString($tagsSeparator);
if (strlen(trim($link->getDescription())) && strpos($link->getDescription(), '#') !== false) { if (strlen(trim($link->getDescription())) && strpos($link->getDescription(), '#') !== false) {
// description given and at least one possible tag found // description given and at least one possible tag found
$descTags = array(); $descTags = [];
// find all tags in the form of #tag in the description // find all tags in the form of #tag in the description
preg_match_all( preg_match_all(
'/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm', '/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm',
@ -552,10 +552,10 @@ protected function postProcessFoundPositions(array $fieldLengths, array $foundPo
protected function buildFullTextSearchableLink(Bookmark $link, array &$lengths): string protected function buildFullTextSearchableLink(Bookmark $link, array &$lengths): string
{ {
$tagString = $link->getTagsString($this->conf->get('general.tags_separator', ' ')); $tagString = $link->getTagsString($this->conf->get('general.tags_separator', ' '));
$content = mb_convert_case($link->getTitle(), MB_CASE_LOWER, 'UTF-8') .'\\'; $content = mb_convert_case($link->getTitle(), MB_CASE_LOWER, 'UTF-8') . '\\';
$content .= mb_convert_case($link->getDescription(), MB_CASE_LOWER, 'UTF-8') .'\\'; $content .= mb_convert_case($link->getDescription(), MB_CASE_LOWER, 'UTF-8') . '\\';
$content .= mb_convert_case($link->getUrl(), MB_CASE_LOWER, 'UTF-8') .'\\'; $content .= mb_convert_case($link->getUrl(), MB_CASE_LOWER, 'UTF-8') . '\\';
$content .= mb_convert_case($tagString, MB_CASE_LOWER, 'UTF-8') .'\\'; $content .= mb_convert_case($tagString, MB_CASE_LOWER, 'UTF-8') . '\\';
$lengths['title'] = ['start' => 0, 'end' => mb_strlen($link->getTitle())]; $lengths['title'] = ['start' => 0, 'end' => mb_strlen($link->getTitle())];
$nextField = $lengths['title']['end'] + 1; $nextField = $lengths['title']['end'] + 1;

View file

@ -112,12 +112,12 @@ public function write($links)
if (is_file($this->datastore) && !is_writeable($this->datastore)) { if (is_file($this->datastore) && !is_writeable($this->datastore)) {
// The datastore exists but is not writeable // The datastore exists but is not writeable
throw new NotWritableDataStoreException($this->datastore); throw new NotWritableDataStoreException($this->datastore);
} else if (!is_file($this->datastore) && !is_writeable(dirname($this->datastore))) { } elseif (!is_file($this->datastore) && !is_writeable(dirname($this->datastore))) {
// The datastore does not exist and its parent directory is not writeable // The datastore does not exist and its parent directory is not writeable
throw new NotWritableDataStoreException(dirname($this->datastore)); throw new NotWritableDataStoreException(dirname($this->datastore));
} }
$data = self::$phpPrefix.base64_encode(gzdeflate(serialize($links))).self::$phpSuffix; $data = self::$phpPrefix . base64_encode(gzdeflate(serialize($links))) . self::$phpSuffix;
$this->mutex->synchronized(function () use ($data) { $this->mutex->synchronized(function () use ($data) {
file_put_contents( file_put_contents(

View file

@ -13,6 +13,9 @@
* To prevent data corruption, it does not overwrite existing bookmarks, * To prevent data corruption, it does not overwrite existing bookmarks,
* even though there should not be any. * even though there should not be any.
* *
* We disable this because otherwise it creates indentation issues, and heredoc is not supported by PHP gettext.
* @phpcs:disable Generic.Files.LineLength.TooLong
*
* @package Shaarli\Bookmark * @package Shaarli\Bookmark
*/ */
class BookmarkInitializer class BookmarkInitializer
@ -39,7 +42,7 @@ public function initialize(): void
$bookmark->setTitle('Calm Jazz Music - YouTube ' . t('(private bookmark with thumbnail demo)')); $bookmark->setTitle('Calm Jazz Music - YouTube ' . t('(private bookmark with thumbnail demo)'));
$bookmark->setUrl('https://www.youtube.com/watch?v=DVEUcbPkb-c'); $bookmark->setUrl('https://www.youtube.com/watch?v=DVEUcbPkb-c');
$bookmark->setDescription(t( $bookmark->setDescription(t(
'Shaarli will automatically pick up the thumbnail for links to a variety of websites. 'Shaarli will automatically pick up the thumbnail for links to a variety of websites.
Explore your new Shaarli instance by trying out controls and menus. Explore your new Shaarli instance by trying out controls and menus.
Visit the project on [Github](https://github.com/shaarli/Shaarli) or [the documentation](https://shaarli.readthedocs.io/en/master/) to learn more about Shaarli. Visit the project on [Github](https://github.com/shaarli/Shaarli) or [the documentation](https://shaarli.readthedocs.io/en/master/) to learn more about Shaarli.
@ -54,7 +57,7 @@ public function initialize(): void
$bookmark = new Bookmark(); $bookmark = new Bookmark();
$bookmark->setTitle(t('Note: Shaare descriptions')); $bookmark->setTitle(t('Note: Shaare descriptions'));
$bookmark->setDescription(t( $bookmark->setDescription(t(
'Adding a shaare without entering a URL creates a text-only "note" post such as this one. 'Adding a shaare without entering a URL creates a text-only "note" post such as this one.
This note is private, so you are the only one able to see it while logged in. This note is private, so you are the only one able to see it while logged in.
You can use this to keep notes, post articles, code snippets, and much more. You can use this to keep notes, post articles, code snippets, and much more.
@ -91,7 +94,7 @@ public function initialize(): void
'Shaarli - ' . t('The personal, minimalist, super-fast, database free, bookmarking service') 'Shaarli - ' . t('The personal, minimalist, super-fast, database free, bookmarking service')
); );
$bookmark->setDescription(t( $bookmark->setDescription(t(
'Welcome to Shaarli! 'Welcome to Shaarli!
Shaarli allows you to bookmark your favorite pages, and share them with others or store them privately. Shaarli allows you to bookmark your favorite pages, and share them with others or store them privately.
You can add a description to your bookmarks, such as this one, and tag them. You can add a description to your bookmarks, such as this one, and tag them.

View file

@ -67,14 +67,15 @@ function html_extract_tag($tag, $html)
$propertiesKey = ['property', 'name', 'itemprop']; $propertiesKey = ['property', 'name', 'itemprop'];
$properties = implode('|', $propertiesKey); $properties = implode('|', $propertiesKey);
// We need a OR here to accept either 'property=og:noquote' or 'property="og:unrelated og:my-tag"' // We need a OR here to accept either 'property=og:noquote' or 'property="og:unrelated og:my-tag"'
$orCondition = '["\']?(?:og:)?'. $tag .'["\']?|["\'][^\'"]*?(?:og:)?' . $tag . '[^\'"]*?[\'"]'; $orCondition = '["\']?(?:og:)?' . $tag . '["\']?|["\'][^\'"]*?(?:og:)?' . $tag . '[^\'"]*?[\'"]';
// Try to retrieve OpenGraph tag. // Try to retrieve OpenGraph tag.
$ogRegex = '#<meta[^>]+(?:'. $properties .')=(?:'. $orCondition .')[^>]*content=(["\'])([^\1]*?)\1.*?>#'; $ogRegex = '#<meta[^>]+(?:' . $properties . ')=(?:' . $orCondition . ')[^>]*content=(["\'])([^\1]*?)\1.*?>#';
// If the attributes are not in the order property => content (e.g. Github) // If the attributes are not in the order property => content (e.g. Github)
// New regex to keep this readable... more or less. // New regex to keep this readable... more or less.
$ogRegexReverse = '#<meta[^>]+content=(["\'])([^\1]*?)\1[^>]+(?:'. $properties .')=(?:'. $orCondition .').*?>#'; $ogRegexReverse = '#<meta[^>]+content=(["\'])([^\1]*?)\1[^>]+(?:' . $properties . ')=(?:' . $orCondition . ').*?>#';
if (preg_match($ogRegex, $html, $matches) > 0 if (
preg_match($ogRegex, $html, $matches) > 0
|| preg_match($ogRegexReverse, $html, $matches) > 0 || preg_match($ogRegexReverse, $html, $matches) > 0
) { ) {
return $matches[2]; return $matches[2];
@ -116,7 +117,7 @@ function hashtag_autolink($description, $indexUrl = '')
* \p{Mn} - any non marking space (accents, umlauts, etc) * \p{Mn} - any non marking space (accents, umlauts, etc)
*/ */
$regex = '/(^|\s)#([\p{Pc}\p{N}\p{L}\p{Mn}]+)/mui'; $regex = '/(^|\s)#([\p{Pc}\p{N}\p{L}\p{Mn}]+)/mui';
$replacement = '$1<a href="'. $indexUrl .'./add-tag/$2" title="Hashtag $2">#$2</a>'; $replacement = '$1<a href="' . $indexUrl . './add-tag/$2" title="Hashtag $2">#$2</a>';
return preg_replace($regex, $replacement, $description); return preg_replace($regex, $replacement, $description);
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Bookmark\Exception; namespace Shaarli\Bookmark\Exception;
use Exception; use Exception;

View file

@ -1,7 +1,7 @@
<?php <?php
namespace Shaarli\Bookmark\Exception; namespace Shaarli\Bookmark\Exception;
class EmptyDataStoreException extends \Exception
class EmptyDataStoreException extends \Exception {} {
}

View file

@ -16,14 +16,14 @@ public function __construct($bookmark)
} else { } else {
$created = 'Not a DateTime object'; $created = 'Not a DateTime object';
} }
$this->message = 'This bookmark is not valid'. PHP_EOL; $this->message = 'This bookmark is not valid' . PHP_EOL;
$this->message .= ' - ID: '. $bookmark->getId() . PHP_EOL; $this->message .= ' - ID: ' . $bookmark->getId() . PHP_EOL;
$this->message .= ' - Title: '. $bookmark->getTitle() . PHP_EOL; $this->message .= ' - Title: ' . $bookmark->getTitle() . PHP_EOL;
$this->message .= ' - Url: '. $bookmark->getUrl() . PHP_EOL; $this->message .= ' - Url: ' . $bookmark->getUrl() . PHP_EOL;
$this->message .= ' - ShortUrl: '. $bookmark->getShortUrl() . PHP_EOL; $this->message .= ' - ShortUrl: ' . $bookmark->getShortUrl() . PHP_EOL;
$this->message .= ' - Created: '. $created . PHP_EOL; $this->message .= ' - Created: ' . $created . PHP_EOL;
} else { } else {
$this->message = 'The provided data is not a bookmark'. PHP_EOL; $this->message = 'The provided data is not a bookmark' . PHP_EOL;
$this->message .= var_export($bookmark, true); $this->message .= var_export($bookmark, true);
} }
} }

View file

@ -1,9 +1,7 @@
<?php <?php
namespace Shaarli\Bookmark\Exception; namespace Shaarli\Bookmark\Exception;
class NotWritableDataStoreException extends \Exception class NotWritableDataStoreException extends \Exception
{ {
/** /**
@ -13,7 +11,7 @@ class NotWritableDataStoreException extends \Exception
*/ */
public function __construct($dataStore) public function __construct($dataStore)
{ {
$this->message = 'Couldn\'t load data from the data store file "'. $dataStore .'". '. $this->message = 'Couldn\'t load data from the data store file "' . $dataStore . '". ' .
'Your data might be corrupted, or your file isn\'t readable.'; 'Your data might be corrupted, or your file isn\'t readable.';
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Config; namespace Shaarli\Config;
/** /**

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Config; namespace Shaarli\Config;
use Shaarli\Config\Exception\MissingFieldConfigException; use Shaarli\Config\Exception\MissingFieldConfigException;
@ -20,7 +21,7 @@ class ConfigManager
*/ */
protected static $NOT_FOUND = 'NOT_FOUND'; protected static $NOT_FOUND = 'NOT_FOUND';
public static $DEFAULT_PLUGINS = array('qrcode'); public static $DEFAULT_PLUGINS = ['qrcode'];
/** /**
* @var string Config folder. * @var string Config folder.
@ -133,7 +134,7 @@ public function get($setting, $default = '')
public function set($setting, $value, $write = false, $isLoggedIn = false) public function set($setting, $value, $write = false, $isLoggedIn = false)
{ {
if (empty($setting) || ! is_string($setting)) { if (empty($setting) || ! is_string($setting)) {
throw new \Exception(t('Invalid setting key parameter. String expected, got: '). gettype($setting)); throw new \Exception(t('Invalid setting key parameter. String expected, got: ') . gettype($setting));
} }
// During the ConfigIO transition, map legacy settings to the new ones. // During the ConfigIO transition, map legacy settings to the new ones.
@ -160,7 +161,7 @@ public function set($setting, $value, $write = false, $isLoggedIn = false)
public function remove($setting, $write = false, $isLoggedIn = false) public function remove($setting, $write = false, $isLoggedIn = false)
{ {
if (empty($setting) || ! is_string($setting)) { if (empty($setting) || ! is_string($setting)) {
throw new \Exception(t('Invalid setting key parameter. String expected, got: '). gettype($setting)); throw new \Exception(t('Invalid setting key parameter. String expected, got: ') . gettype($setting));
} }
// During the ConfigIO transition, map legacy settings to the new ones. // During the ConfigIO transition, map legacy settings to the new ones.
@ -213,7 +214,7 @@ public function exists($setting)
public function write($isLoggedIn) public function write($isLoggedIn)
{ {
// These fields are required in configuration. // These fields are required in configuration.
$mandatoryFields = array( $mandatoryFields = [
'credentials.login', 'credentials.login',
'credentials.hash', 'credentials.hash',
'credentials.salt', 'credentials.salt',
@ -222,7 +223,7 @@ public function write($isLoggedIn)
'general.title', 'general.title',
'general.header_link', 'general.header_link',
'privacy.default_private_links', 'privacy.default_private_links',
); ];
// Only logged in user can alter config. // Only logged in user can alter config.
if (is_file($this->getConfigFileExt()) && !$isLoggedIn) { if (is_file($this->getConfigFileExt()) && !$isLoggedIn) {
@ -392,7 +393,7 @@ protected function setDefaultValues()
$this->setEmpty('translation.mode', 'php'); $this->setEmpty('translation.mode', 'php');
$this->setEmpty('translation.extensions', []); $this->setEmpty('translation.extensions', []);
$this->setEmpty('plugins', array()); $this->setEmpty('plugins', []);
$this->setEmpty('formatter', 'markdown'); $this->setEmpty('formatter', 'markdown');
} }

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Config; namespace Shaarli\Config;
/** /**
@ -12,7 +13,7 @@ class ConfigPhp implements ConfigIO
/** /**
* @var array List of config key without group. * @var array List of config key without group.
*/ */
public static $ROOT_KEYS = array( public static $ROOT_KEYS = [
'login', 'login',
'hash', 'hash',
'salt', 'salt',
@ -22,7 +23,7 @@ class ConfigPhp implements ConfigIO
'redirector', 'redirector',
'disablesessionprotection', 'disablesessionprotection',
'privateLinkByDefault', 'privateLinkByDefault',
); ];
/** /**
* Map legacy config keys with the new ones. * Map legacy config keys with the new ones.
@ -31,7 +32,7 @@ class ConfigPhp implements ConfigIO
* *
* @var array current key => legacy key. * @var array current key => legacy key.
*/ */
public static $LEGACY_KEYS_MAPPING = array( public static $LEGACY_KEYS_MAPPING = [
'credentials.login' => 'login', 'credentials.login' => 'login',
'credentials.hash' => 'hash', 'credentials.hash' => 'hash',
'credentials.salt' => 'salt', 'credentials.salt' => 'salt',
@ -68,7 +69,7 @@ class ConfigPhp implements ConfigIO
'privacy.hide_public_links' => 'config.HIDE_PUBLIC_LINKS', 'privacy.hide_public_links' => 'config.HIDE_PUBLIC_LINKS',
'privacy.hide_timestamps' => 'config.HIDE_TIMESTAMPS', 'privacy.hide_timestamps' => 'config.HIDE_TIMESTAMPS',
'security.open_shaarli' => 'config.OPEN_SHAARLI', 'security.open_shaarli' => 'config.OPEN_SHAARLI',
); ];
/** /**
* @inheritdoc * @inheritdoc
@ -76,12 +77,12 @@ class ConfigPhp implements ConfigIO
public function read($filepath) public function read($filepath)
{ {
if (! file_exists($filepath) || ! is_readable($filepath)) { if (! file_exists($filepath) || ! is_readable($filepath)) {
return array(); return [];
} }
include $filepath; include $filepath;
$out = array(); $out = [];
foreach (self::$ROOT_KEYS as $key) { foreach (self::$ROOT_KEYS as $key) {
$out[$key] = isset($GLOBALS[$key]) ? $GLOBALS[$key] : ''; $out[$key] = isset($GLOBALS[$key]) ? $GLOBALS[$key] : '';
} }
@ -95,7 +96,7 @@ public function read($filepath)
*/ */
public function write($filepath, $conf) public function write($filepath, $conf)
{ {
$configStr = '<?php '. PHP_EOL; $configStr = '<?php ' . PHP_EOL;
foreach (self::$ROOT_KEYS as $key) { foreach (self::$ROOT_KEYS as $key) {
if (isset($conf[$key])) { if (isset($conf[$key])) {
$configStr .= '$GLOBALS[\'' . $key . '\'] = ' . var_export($conf[$key], true) . ';' . PHP_EOL; $configStr .= '$GLOBALS[\'' . $key . '\'] = ' . var_export($conf[$key], true) . ';' . PHP_EOL;
@ -106,8 +107,8 @@ public function write($filepath, $conf)
foreach ($conf['config'] as $key => $value) { foreach ($conf['config'] as $key => $value) {
$configStr .= '$GLOBALS[\'config\'][\'' $configStr .= '$GLOBALS[\'config\'][\''
. $key . $key
.'\'] = ' . '\'] = '
.var_export($conf['config'][$key], true).';' . var_export($conf['config'][$key], true) . ';'
. PHP_EOL; . PHP_EOL;
} }
@ -115,18 +116,19 @@ public function write($filepath, $conf)
foreach ($conf['plugins'] as $key => $value) { foreach ($conf['plugins'] as $key => $value) {
$configStr .= '$GLOBALS[\'plugins\'][\'' $configStr .= '$GLOBALS[\'plugins\'][\''
. $key . $key
.'\'] = ' . '\'] = '
.var_export($conf['plugins'][$key], true).';' . var_export($conf['plugins'][$key], true) . ';'
. PHP_EOL; . PHP_EOL;
} }
} }
if (!file_put_contents($filepath, $configStr) if (
!file_put_contents($filepath, $configStr)
|| strcmp(file_get_contents($filepath), $configStr) != 0 || strcmp(file_get_contents($filepath), $configStr) != 0
) { ) {
throw new \Shaarli\Exceptions\IOException( throw new \Shaarli\Exceptions\IOException(
$filepath, $filepath,
t('Shaarli could not create the config file. '. t('Shaarli could not create the config file. ' .
'Please make sure Shaarli has the right to write in the folder is it installed in.') 'Please make sure Shaarli has the right to write in the folder is it installed in.')
); );
} }

View file

@ -39,8 +39,8 @@ function ($value, string $key) use ($directories) {
throw new PluginConfigOrderException(); throw new PluginConfigOrderException();
} }
$plugins = array(); $plugins = [];
$newEnabledPlugins = array(); $newEnabledPlugins = [];
foreach ($formData as $key => $data) { foreach ($formData as $key => $data) {
if (startsWith($key, 'order')) { if (startsWith($key, 'order')) {
continue; continue;
@ -62,7 +62,7 @@ function ($value, string $key) use ($directories) {
throw new PluginConfigOrderException(); throw new PluginConfigOrderException();
} }
$finalPlugins = array(); $finalPlugins = [];
// Make plugins order continuous. // Make plugins order continuous.
foreach ($plugins as $plugin) { foreach ($plugins as $plugin) {
$finalPlugins[] = $plugin; $finalPlugins[] = $plugin;
@ -81,7 +81,7 @@ function ($value, string $key) use ($directories) {
*/ */
function validate_plugin_order($formData) function validate_plugin_order($formData)
{ {
$orders = array(); $orders = [];
foreach ($formData as $key => $value) { foreach ($formData as $key => $value) {
// No duplicate order allowed. // No duplicate order allowed.
if (in_array($value, $orders, true)) { if (in_array($value, $orders, true)) {

View file

@ -1,6 +1,5 @@
<?php <?php
namespace Shaarli\Config\Exception; namespace Shaarli\Config\Exception;
/** /**

View file

@ -1,6 +1,5 @@
<?php <?php
namespace Shaarli\Config\Exception; namespace Shaarli\Config\Exception;
/** /**

View file

@ -158,7 +158,7 @@ public function build(): ShaarliContainer
$container['updater'] = function (ShaarliContainer $container): Updater { $container['updater'] = function (ShaarliContainer $container): Updater {
return new Updater( return new Updater(
UpdaterUtils::read_updates_file($container->conf->get('resource.updates')), UpdaterUtils::readUpdatesFile($container->conf->get('resource.updates')),
$container->bookmarkService, $container->bookmarkService,
$container->conf, $container->conf,
$container->loginManager->isLoggedIn() $container->loginManager->isLoggedIn()

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Exceptions; namespace Shaarli\Exceptions;
use Exception; use Exception;

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Feed; namespace Shaarli\Feed;
use DateTime; use DateTime;
@ -107,14 +108,14 @@ public function buildData(string $feedType, ?array $userInput)
$nblinksToDisplay = $this->getNbLinks(count($linksToDisplay), $userInput); $nblinksToDisplay = $this->getNbLinks(count($linksToDisplay), $userInput);
// Can't use array_keys() because $link is a LinkDB instance and not a real array. // Can't use array_keys() because $link is a LinkDB instance and not a real array.
$keys = array(); $keys = [];
foreach ($linksToDisplay as $key => $value) { foreach ($linksToDisplay as $key => $value) {
$keys[] = $key; $keys[] = $key;
} }
$pageaddr = escape(index_url($this->serverInfo)); $pageaddr = escape(index_url($this->serverInfo));
$this->formatter->addContextData('index_url', $pageaddr); $this->formatter->addContextData('index_url', $pageaddr);
$linkDisplayed = array(); $linkDisplayed = [];
for ($i = 0; $i < $nblinksToDisplay && $i < count($keys); $i++) { for ($i = 0; $i < $nblinksToDisplay && $i < count($keys); $i++) {
$linkDisplayed[$keys[$i]] = $this->buildItem($feedType, $linksToDisplay[$keys[$i]], $pageaddr); $linkDisplayed[$keys[$i]] = $this->buildItem($feedType, $linksToDisplay[$keys[$i]], $pageaddr);
} }
@ -176,9 +177,9 @@ protected function buildItem(string $feedType, $link, $pageaddr)
$data = $this->formatter->format($link); $data = $this->formatter->format($link);
$data['guid'] = rtrim($pageaddr, '/') . '/shaare/' . $data['shorturl']; $data['guid'] = rtrim($pageaddr, '/') . '/shaare/' . $data['shorturl'];
if ($this->usePermalinks === true) { if ($this->usePermalinks === true) {
$permalink = '<a href="'. $data['url'] .'" title="'. t('Direct link') .'">'. t('Direct link') .'</a>'; $permalink = '<a href="' . $data['url'] . '" title="' . t('Direct link') . '">' . t('Direct link') . '</a>';
} else { } else {
$permalink = '<a href="'. $data['guid'] .'" title="'. t('Permalink') .'">'. t('Permalink') .'</a>'; $permalink = '<a href="' . $data['guid'] . '" title="' . t('Permalink') . '">' . t('Permalink') . '</a>';
} }
$data['description'] .= PHP_EOL . PHP_EOL . '<br>&#8212; ' . $permalink; $data['description'] .= PHP_EOL . PHP_EOL . '<br>&#8212; ' . $permalink;

View file

@ -12,8 +12,8 @@
*/ */
class BookmarkDefaultFormatter extends BookmarkFormatter class BookmarkDefaultFormatter extends BookmarkFormatter
{ {
const SEARCH_HIGHLIGHT_OPEN = '|@@HIGHLIGHT'; protected const SEARCH_HIGHLIGHT_OPEN = '|@@HIGHLIGHT';
const SEARCH_HIGHLIGHT_CLOSE = 'HIGHLIGHT@@|'; protected const SEARCH_HIGHLIGHT_CLOSE = 'HIGHLIGHT@@|';
/** /**
* @inheritdoc * @inheritdoc

View file

@ -16,7 +16,7 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter
/** /**
* When this tag is present in a bookmark, its description should not be processed with Markdown * When this tag is present in a bookmark, its description should not be processed with Markdown
*/ */
const NO_MD_TAG = 'nomarkdown'; public const NO_MD_TAG = 'nomarkdown';
/** @var \Parsedown instance */ /** @var \Parsedown instance */
protected $parsedown; protected $parsedown;
@ -71,7 +71,7 @@ public function formatDescription($bookmark)
$processedDescription = $this->replaceTokens($processedDescription); $processedDescription = $this->replaceTokens($processedDescription);
if (!empty($processedDescription)) { if (!empty($processedDescription)) {
$processedDescription = '<div class="markdown">'. $processedDescription . '</div>'; $processedDescription = '<div class="markdown">' . $processedDescription . '</div>';
} }
return $processedDescription; return $processedDescription;
@ -110,7 +110,7 @@ protected function filterProtocols($description)
function ($match) use ($allowedProtocols, $indexUrl) { function ($match) use ($allowedProtocols, $indexUrl) {
$link = startsWith($match[1], '?') || startsWith($match[1], '/') ? $indexUrl : ''; $link = startsWith($match[1], '?') || startsWith($match[1], '/') ? $indexUrl : '';
$link .= whitelist_protocols($match[1], $allowedProtocols); $link .= whitelist_protocols($match[1], $allowedProtocols);
return ']('. $link.')'; return '](' . $link . ')';
}, },
$description $description
); );
@ -137,7 +137,7 @@ protected function formatHashTags($description)
* \p{Mn} - any non marking space (accents, umlauts, etc) * \p{Mn} - any non marking space (accents, umlauts, etc)
*/ */
$regex = '/(^|\s)#([\p{Pc}\p{N}\p{L}\p{Mn}]+)/mui'; $regex = '/(^|\s)#([\p{Pc}\p{N}\p{L}\p{Mn}]+)/mui';
$replacement = '$1[#$2]('. $indexUrl .'./add-tag/$2)'; $replacement = '$1[#$2](' . $indexUrl . './add-tag/$2)';
$descriptionLines = explode(PHP_EOL, $description); $descriptionLines = explode(PHP_EOL, $description);
$descriptionOut = ''; $descriptionOut = '';
@ -178,17 +178,17 @@ protected function formatHashTags($description)
*/ */
protected function sanitizeHtml($description) protected function sanitizeHtml($description)
{ {
$escapeTags = array( $escapeTags = [
'script', 'script',
'style', 'style',
'link', 'link',
'iframe', 'iframe',
'frameset', 'frameset',
'frame', 'frame',
); ];
foreach ($escapeTags as $tag) { foreach ($escapeTags as $tag) {
$description = preg_replace_callback( $description = preg_replace_callback(
'#<\s*'. $tag .'[^>]*>(.*</\s*'. $tag .'[^>]*>)?#is', '#<\s*' . $tag . '[^>]*>(.*</\s*' . $tag . '[^>]*>)?#is',
function ($match) { function ($match) {
return escape($match[0]); return escape($match[0]);
}, },

View file

@ -10,4 +10,6 @@
* *
* @package Shaarli\Formatter * @package Shaarli\Formatter
*/ */
class BookmarkRawFormatter extends BookmarkFormatter {} class BookmarkRawFormatter extends BookmarkFormatter
{
}

View file

@ -41,7 +41,7 @@ public function __construct(ConfigManager $conf, bool $isLoggedIn)
public function getFormatter(string $type = null): BookmarkFormatter public function getFormatter(string $type = null): BookmarkFormatter
{ {
$type = $type ? $type : $this->conf->get('formatter', 'default'); $type = $type ? $type : $this->conf->get('formatter', 'default');
$className = '\\Shaarli\\Formatter\\Bookmark'. ucfirst($type) .'Formatter'; $className = '\\Shaarli\\Formatter\\Bookmark' . ucfirst($type) . 'Formatter';
if (!class_exists($className)) { if (!class_exists($className)) {
$className = '\\Shaarli\\Formatter\\BookmarkDefaultFormatter'; $className = '\\Shaarli\\Formatter\\BookmarkDefaultFormatter';
} }

View file

@ -42,7 +42,8 @@ public function __invoke(Request $request, Response $response, callable $next):
$this->initBasePath($request); $this->initBasePath($request);
try { try {
if (!is_file($this->container->conf->getConfigFileExt()) if (
!is_file($this->container->conf->getConfigFileExt())
&& !in_array($next->getName(), ['displayInstall', 'saveInstall'], true) && !in_array($next->getName(), ['displayInstall', 'saveInstall'], true)
) { ) {
return $response->withRedirect($this->container->basePath . '/install'); return $response->withRedirect($this->container->basePath . '/install');
@ -86,7 +87,8 @@ protected function runUpdates(): void
*/ */
protected function checkOpenShaarli(Request $request, Response $response, callable $next): bool protected function checkOpenShaarli(Request $request, Response $response, callable $next): bool
{ {
if (// if the user isn't logged in if (
// if the user isn't logged in
!$this->container->loginManager->isLoggedIn() !$this->container->loginManager->isLoggedIn()
// and Shaarli doesn't have public content... // and Shaarli doesn't have public content...
&& $this->container->conf->get('privacy.hide_public_links') && $this->container->conf->get('privacy.hide_public_links')

View file

@ -51,7 +51,10 @@ public function index(Request $request, Response $response): Response
$this->assignView('languages', Languages::getAvailableLanguages()); $this->assignView('languages', Languages::getAvailableLanguages());
$this->assignView('gd_enabled', extension_loaded('gd')); $this->assignView('gd_enabled', extension_loaded('gd'));
$this->assignView('thumbnails_mode', $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE)); $this->assignView('thumbnails_mode', $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE));
$this->assignView('pagetitle', t('Configure') .' - '. $this->container->conf->get('general.title', 'Shaarli')); $this->assignView(
'pagetitle',
t('Configure') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
);
return $response->write($this->render(TemplatePage::CONFIGURE)); return $response->write($this->render(TemplatePage::CONFIGURE));
} }
@ -95,12 +98,15 @@ public function save(Request $request, Response $response): Response
} }
$thumbnailsMode = extension_loaded('gd') ? $request->getParam('enableThumbnails') : Thumbnailer::MODE_NONE; $thumbnailsMode = extension_loaded('gd') ? $request->getParam('enableThumbnails') : Thumbnailer::MODE_NONE;
if ($thumbnailsMode !== Thumbnailer::MODE_NONE if (
$thumbnailsMode !== Thumbnailer::MODE_NONE
&& $thumbnailsMode !== $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) && $thumbnailsMode !== $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE)
) { ) {
$this->saveWarningMessage( $this->saveWarningMessage(
t('You have enabled or changed thumbnails mode.') . t('You have enabled or changed thumbnails mode.') .
'<a href="'. $this->container->basePath .'/admin/thumbnails">' . t('Please synchronize them.') .'</a>' '<a href="' . $this->container->basePath . '/admin/thumbnails">' .
t('Please synchronize them.') .
'</a>'
); );
} }
$this->container->conf->set('thumbnails.mode', $thumbnailsMode); $this->container->conf->set('thumbnails.mode', $thumbnailsMode);

View file

@ -23,7 +23,7 @@ class ExportController extends ShaarliAdminController
*/ */
public function index(Request $request, Response $response): Response public function index(Request $request, Response $response): Response
{ {
$this->assignView('pagetitle', t('Export') .' - '. $this->container->conf->get('general.title', 'Shaarli')); $this->assignView('pagetitle', t('Export') . ' - ' . $this->container->conf->get('general.title', 'Shaarli'));
return $response->write($this->render(TemplatePage::EXPORT)); return $response->write($this->render(TemplatePage::EXPORT));
} }
@ -68,7 +68,7 @@ public function export(Request $request, Response $response): Response
$response = $response->withHeader('Content-Type', 'text/html; charset=utf-8'); $response = $response->withHeader('Content-Type', 'text/html; charset=utf-8');
$response = $response->withHeader( $response = $response->withHeader(
'Content-disposition', 'Content-disposition',
'attachment; filename=bookmarks_'.$selection.'_'.$now->format(Bookmark::LINK_DATE_FORMAT).'.html' 'attachment; filename=bookmarks_' . $selection . '_' . $now->format(Bookmark::LINK_DATE_FORMAT) . '.html'
); );
$this->assignView('date', $now->format(DateTime::RFC822)); $this->assignView('date', $now->format(DateTime::RFC822));

View file

@ -38,7 +38,7 @@ public function index(Request $request, Response $response): Response
true true
) )
); );
$this->assignView('pagetitle', t('Import') .' - '. $this->container->conf->get('general.title', 'Shaarli')); $this->assignView('pagetitle', t('Import') . ' - ' . $this->container->conf->get('general.title', 'Shaarli'));
return $response->write($this->render(TemplatePage::IMPORT)); return $response->write($this->render(TemplatePage::IMPORT));
} }
@ -64,7 +64,7 @@ public function import(Request $request, Response $response): Response
$msg = sprintf( $msg = sprintf(
t( t(
'The file you are trying to upload is probably bigger than what this webserver can accept' 'The file you are trying to upload is probably bigger than what this webserver can accept'
.' (%s). Please upload in smaller chunks.' . ' (%s). Please upload in smaller chunks.'
), ),
get_max_upload_size(ini_get('post_max_size'), ini_get('upload_max_filesize')) get_max_upload_size(ini_get('post_max_size'), ini_get('upload_max_filesize'))
); );

View file

@ -32,7 +32,7 @@ public function index(Request $request, Response $response): Response
$this->assignView('tags_separator', $separator); $this->assignView('tags_separator', $separator);
$this->assignView( $this->assignView(
'pagetitle', 'pagetitle',
t('Manage tags') .' - '. $this->container->conf->get('general.title', 'Shaarli') t('Manage tags') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
); );
return $response->write($this->render(TemplatePage::CHANGE_TAG)); return $response->write($this->render(TemplatePage::CHANGE_TAG));
@ -87,7 +87,7 @@ public function save(Request $request, Response $response): Response
$this->saveSuccessMessage($alert); $this->saveSuccessMessage($alert);
$redirect = true === $isDelete ? '/admin/tags' : '/?searchtags='. urlencode($toTag); $redirect = true === $isDelete ? '/admin/tags' : '/?searchtags=' . urlencode($toTag);
return $this->redirect($response, $redirect); return $this->redirect($response, $redirect);
} }

View file

@ -25,7 +25,7 @@ public function __construct(ShaarliContainer $container)
$this->assignView( $this->assignView(
'pagetitle', 'pagetitle',
t('Change password') .' - '. $this->container->conf->get('general.title', 'Shaarli') t('Change password') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
); );
} }
@ -78,7 +78,7 @@ public function change(Request $request, Response $response): Response
// Save new password // Save new password
// Salt renders rainbow-tables attacks useless. // Salt renders rainbow-tables attacks useless.
$this->container->conf->set('credentials.salt', sha1(uniqid('', true) .'_'. mt_rand())); $this->container->conf->set('credentials.salt', sha1(uniqid('', true) . '_' . mt_rand()));
$this->container->conf->set( $this->container->conf->set(
'credentials.hash', 'credentials.hash',
sha1( sha1(

View file

@ -42,7 +42,7 @@ function ($a, $b) {
$this->assignView('disabledPlugins', $disabledPlugins); $this->assignView('disabledPlugins', $disabledPlugins);
$this->assignView( $this->assignView(
'pagetitle', 'pagetitle',
t('Plugin Administration') .' - '. $this->container->conf->get('general.title', 'Shaarli') t('Plugin Administration') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
); );
return $response->write($this->render(TemplatePage::PLUGINS_ADMIN)); return $response->write($this->render(TemplatePage::PLUGINS_ADMIN));
@ -64,7 +64,7 @@ public function save(Request $request, Response $response): Response
unset($parameters['parameters_form']); unset($parameters['parameters_form']);
unset($parameters['token']); unset($parameters['token']);
foreach ($parameters as $param => $value) { foreach ($parameters as $param => $value) {
$this->container->conf->set('plugins.'. $param, escape($value)); $this->container->conf->set('plugins.' . $param, escape($value));
} }
} else { } else {
$this->container->conf->set('general.enabled_plugins', save_plugin_config($parameters)); $this->container->conf->set('general.enabled_plugins', save_plugin_config($parameters));

View file

@ -72,7 +72,9 @@ public function clearCache(Request $request, Response $response): Response
$this->saveWarningMessage( $this->saveWarningMessage(
t('Thumbnails cache has been cleared.') . ' ' . t('Thumbnails cache has been cleared.') . ' ' .
'<a href="'. $this->container->basePath .'/admin/thumbnails">' . t('Please synchronize them.') .'</a>' '<a href="' . $this->container->basePath . '/admin/thumbnails">' .
t('Please synchronize them.') .
'</a>'
); );
} else { } else {
$folders = [ $folders = [

View file

@ -45,6 +45,4 @@ public function visibility(Request $request, Response $response, array $args): R
return $this->redirectFromReferer($request, $response, ['visibility']); return $this->redirectFromReferer($request, $response, ['visibility']);
} }
} }

View file

@ -23,7 +23,7 @@ public function addShaare(Request $request, Response $response): Response
$this->assignView( $this->assignView(
'pagetitle', 'pagetitle',
t('Shaare a new link') .' - '. $this->container->conf->get('general.title', 'Shaarli') t('Shaare a new link') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
); );
$this->assignView('tags', $tags); $this->assignView('tags', $tags);
$this->assignView('default_private_links', $this->container->conf->get('privacy.default_private_links', false)); $this->assignView('default_private_links', $this->container->conf->get('privacy.default_private_links', false));

View file

@ -54,7 +54,7 @@ public function deleteBookmark(Request $request, Response $response): Response
$data = $formatter->format($bookmark); $data = $formatter->format($bookmark);
$this->executePageHooks('delete_link', $data); $this->executePageHooks('delete_link', $data);
$this->container->bookmarkService->remove($bookmark, false); $this->container->bookmarkService->remove($bookmark, false);
++ $count; ++$count;
} }
if ($count > 0) { if ($count > 0) {

View file

@ -118,7 +118,8 @@ public function save(Request $request, Response $response): Response
$this->container->conf->get('general.tags_separator', ' ') $this->container->conf->get('general.tags_separator', ' ')
); );
if ($this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE if (
$this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
&& true !== $this->container->conf->get('general.enable_async_metadata', true) && true !== $this->container->conf->get('general.enable_async_metadata', true)
&& $bookmark->shouldUpdateThumbnail() && $bookmark->shouldUpdateThumbnail()
) { ) {
@ -148,7 +149,8 @@ public function save(Request $request, Response $response): Response
return $this->redirectFromReferer( return $this->redirectFromReferer(
$request, $request,
$response, $response,
['/admin/add-shaare', '/admin/shaare'], ['addlink', 'post', 'edit_link'], ['/admin/add-shaare', '/admin/shaare'],
['addlink', 'post', 'edit_link'],
$bookmark->getShortUrl() $bookmark->getShortUrl()
); );
} }
@ -168,10 +170,10 @@ protected function displayForm(array $link, bool $isNew, Request $request, Respo
$this->assignView($key, $value); $this->assignView($key, $value);
} }
$editLabel = false === $isNew ? t('Edit') .' ' : ''; $editLabel = false === $isNew ? t('Edit') . ' ' : '';
$this->assignView( $this->assignView(
'pagetitle', 'pagetitle',
$editLabel . t('Shaare') .' - '. $this->container->conf->get('general.title', 'Shaarli') $editLabel . t('Shaare') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
); );
return $response->write($this->render(TemplatePage::EDIT_LINK)); return $response->write($this->render(TemplatePage::EDIT_LINK));
@ -194,7 +196,8 @@ protected function buildLinkDataFromUrl(Request $request, string $url): array
// If this is an HTTP(S) link, we try go get the page to extract // If this is an HTTP(S) link, we try go get the page to extract
// the title (otherwise we will to straight to the edit form.) // the title (otherwise we will to straight to the edit form.)
if (true !== $this->container->conf->get('general.enable_async_metadata', true) if (
true !== $this->container->conf->get('general.enable_async_metadata', true)
&& empty($title) && empty($title)
&& strpos(get_url_scheme($url) ?: '', 'http') !== false && strpos(get_url_scheme($url) ?: '', 'http') !== false
) { ) {

View file

@ -34,7 +34,7 @@ public function index(Request $request, Response $response): Response
$this->assignView('ids', $ids); $this->assignView('ids', $ids);
$this->assignView( $this->assignView(
'pagetitle', 'pagetitle',
t('Thumbnails update') .' - '. $this->container->conf->get('general.title', 'Shaarli') t('Thumbnails update') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
); );
return $response->write($this->render(TemplatePage::THUMBNAILS)); return $response->write($this->render(TemplatePage::THUMBNAILS));

View file

@ -28,7 +28,7 @@ public function index(Request $request, Response $response): Response
$this->assignView($key, $value); $this->assignView($key, $value);
} }
$this->assignView('pagetitle', t('Tools') .' - '. $this->container->conf->get('general.title', 'Shaarli')); $this->assignView('pagetitle', t('Tools') . ' - ' . $this->container->conf->get('general.title', 'Shaarli'));
return $response->write($this->render(TemplatePage::TOOLS)); return $response->write($this->render(TemplatePage::TOOLS));
} }

View file

@ -35,7 +35,8 @@ public function index(Request $request, Response $response): Response
$formatter->addContextData('base_path', $this->container->basePath); $formatter->addContextData('base_path', $this->container->basePath);
$searchTags = normalize_spaces($request->getParam('searchtags') ?? ''); $searchTags = normalize_spaces($request->getParam('searchtags') ?? '');
$searchTerm = escape(normalize_spaces($request->getParam('searchterm') ?? ''));; $searchTerm = escape(normalize_spaces($request->getParam('searchterm') ?? ''));
;
// Filter bookmarks according search parameters. // Filter bookmarks according search parameters.
$visibility = $this->container->sessionManager->getSessionParameter('visibility'); $visibility = $this->container->sessionManager->getSessionParameter('visibility');
@ -160,7 +161,7 @@ public function permalink(Request $request, Response $response, array $args): Re
$data = array_merge( $data = array_merge(
$this->initializeTemplateVars(), $this->initializeTemplateVars(),
[ [
'pagetitle' => $bookmark->getTitle() .' - '. $this->container->conf->get('general.title', 'Shaarli'), 'pagetitle' => $bookmark->getTitle() . ' - ' . $this->container->conf->get('general.title', 'Shaarli'),
'links' => [$formatter->format($bookmark)], 'links' => [$formatter->format($bookmark)],
] ]
); );
@ -185,7 +186,8 @@ protected function updateThumbnail(Bookmark $bookmark, bool $writeDatastore = tr
$bookmark->setThumbnail(null); $bookmark->setThumbnail(null);
// Requires an update, not async retrieval, thumbnails enabled // Requires an update, not async retrieval, thumbnails enabled
if ($bookmark->shouldUpdateThumbnail() if (
$bookmark->shouldUpdateThumbnail()
&& true !== $this->container->conf->get('general.enable_async_metadata', true) && true !== $this->container->conf->get('general.enable_async_metadata', true)
&& $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE && $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
) { ) {

View file

@ -132,7 +132,7 @@ public function rss(Request $request, Response $response): Response
'date' => $endDateTime, 'date' => $endDateTime,
'date_rss' => $endDateTime->format(DateTime::RSS), 'date_rss' => $endDateTime->format(DateTime::RSS),
'date_human' => DailyPageHelper::getDescriptionByType($type, $dayDateTime), 'date_human' => DailyPageHelper::getDescriptionByType($type, $dayDateTime),
'absolute_url' => $indexUrl . 'daily?'. $type .'=' . $day, 'absolute_url' => $indexUrl . 'daily?' . $type . '=' . $day,
'links' => [], 'links' => [],
]; ];

View file

@ -27,7 +27,7 @@ public function rss(Request $request, Response $response): Response
protected function processRequest(string $feedType, Request $request, Response $response): Response protected function processRequest(string $feedType, Request $request, Response $response): Response
{ {
$response = $response->withHeader('Content-Type', 'application/'. $feedType .'+xml; charset=utf-8'); $response = $response->withHeader('Content-Type', 'application/' . $feedType . '+xml; charset=utf-8');
$pageUrl = page_url($this->container->environment); $pageUrl = page_url($this->container->environment);
$cache = $this->container->pageCacheManager->getCachePage($pageUrl); $cache = $this->container->pageCacheManager->getCachePage($pageUrl);

View file

@ -39,7 +39,8 @@ public function index(Request $request, Response $response): Response
// Before installation, we'll make sure that permissions are set properly, and sessions are working. // Before installation, we'll make sure that permissions are set properly, and sessions are working.
$this->checkPermissions(); $this->checkPermissions();
if (static::SESSION_TEST_VALUE if (
static::SESSION_TEST_VALUE
!== $this->container->sessionManager->getSessionParameter(static::SESSION_TEST_KEY) !== $this->container->sessionManager->getSessionParameter(static::SESSION_TEST_KEY)
) { ) {
$this->container->sessionManager->setSessionParameter(static::SESSION_TEST_KEY, static::SESSION_TEST_VALUE); $this->container->sessionManager->setSessionParameter(static::SESSION_TEST_KEY, static::SESSION_TEST_VALUE);
@ -75,17 +76,18 @@ public function sessionTest(Request $request, Response $response): Response
// This part makes sure sessions works correctly. // This part makes sure sessions works correctly.
// (Because on some hosts, session.save_path may not be set correctly, // (Because on some hosts, session.save_path may not be set correctly,
// or we may not have write access to it.) // or we may not have write access to it.)
if (static::SESSION_TEST_VALUE if (
static::SESSION_TEST_VALUE
!== $this->container->sessionManager->getSessionParameter(static::SESSION_TEST_KEY) !== $this->container->sessionManager->getSessionParameter(static::SESSION_TEST_KEY)
) { ) {
// Step 2: Check if data in session is correct. // Step 2: Check if data in session is correct.
$msg = t( $msg = t(
'<pre>Sessions do not seem to work correctly on your server.<br>'. '<pre>Sessions do not seem to work correctly on your server.<br>' .
'Make sure the variable "session.save_path" is set correctly in your PHP config, '. 'Make sure the variable "session.save_path" is set correctly in your PHP config, ' .
'and that you have write access to it.<br>'. 'and that you have write access to it.<br>' .
'It currently points to %s.<br>'. 'It currently points to %s.<br>' .
'On some browsers, accessing your server via a hostname like \'localhost\' '. 'On some browsers, accessing your server via a hostname like \'localhost\' ' .
'or any custom hostname without a dot causes cookie storage to fail. '. 'or any custom hostname without a dot causes cookie storage to fail. ' .
'We recommend accessing your server via it\'s IP address or Fully Qualified Domain Name.<br>' 'We recommend accessing your server via it\'s IP address or Fully Qualified Domain Name.<br>'
); );
$msg = sprintf($msg, $this->container->sessionManager->getSavePath()); $msg = sprintf($msg, $this->container->sessionManager->getSavePath());
@ -104,7 +106,8 @@ public function sessionTest(Request $request, Response $response): Response
public function save(Request $request, Response $response): Response public function save(Request $request, Response $response): Response
{ {
$timezone = 'UTC'; $timezone = 'UTC';
if (!empty($request->getParam('continent')) if (
!empty($request->getParam('continent'))
&& !empty($request->getParam('city')) && !empty($request->getParam('city'))
&& isTimeZoneValid($request->getParam('continent'), $request->getParam('city')) && isTimeZoneValid($request->getParam('continent'), $request->getParam('city'))
) { ) {
@ -114,7 +117,7 @@ public function save(Request $request, Response $response): Response
$login = $request->getParam('setlogin'); $login = $request->getParam('setlogin');
$this->container->conf->set('credentials.login', $login); $this->container->conf->set('credentials.login', $login);
$salt = sha1(uniqid('', true) .'_'. mt_rand()); $salt = sha1(uniqid('', true) . '_' . mt_rand());
$this->container->conf->set('credentials.salt', $salt); $this->container->conf->set('credentials.salt', $salt);
$this->container->conf->set('credentials.hash', sha1($request->getParam('setpassword') . $login . $salt)); $this->container->conf->set('credentials.hash', sha1($request->getParam('setpassword') . $login . $salt));
@ -123,7 +126,7 @@ public function save(Request $request, Response $response): Response
} else { } else {
$this->container->conf->set( $this->container->conf->set(
'general.title', 'general.title',
'Shared bookmarks on '.escape(index_url($this->container->environment)) 'Shared bookmarks on ' . escape(index_url($this->container->environment))
); );
} }

View file

@ -43,7 +43,7 @@ public function index(Request $request, Response $response): Response
$this $this
->assignView('returnurl', escape($returnUrl)) ->assignView('returnurl', escape($returnUrl))
->assignView('remember_user_default', $this->container->conf->get('privacy.remember_user_default', true)) ->assignView('remember_user_default', $this->container->conf->get('privacy.remember_user_default', true))
->assignView('pagetitle', t('Login') .' - '. $this->container->conf->get('general.title', 'Shaarli')) ->assignView('pagetitle', t('Login') . ' - ' . $this->container->conf->get('general.title', 'Shaarli'))
; ;
return $response->write($this->render(TemplatePage::LOGIN)); return $response->write($this->render(TemplatePage::LOGIN));
@ -64,7 +64,8 @@ public function login(Request $request, Response $response): Response
return $this->redirect($response, '/'); return $this->redirect($response, '/');
} }
if (!$this->container->loginManager->checkCredentials( if (
!$this->container->loginManager->checkCredentials(
client_ip_id($this->container->environment), client_ip_id($this->container->environment),
$request->getParam('login'), $request->getParam('login'),
$request->getParam('password') $request->getParam('password')
@ -101,7 +102,8 @@ public function login(Request $request, Response $response): Response
*/ */
protected function checkLoginState(): bool protected function checkLoginState(): bool
{ {
if ($this->container->loginManager->isLoggedIn() if (
$this->container->loginManager->isLoggedIn()
|| $this->container->conf->get('security.open_shaarli', false) || $this->container->conf->get('security.open_shaarli', false)
) { ) {
throw new CantLoginException(); throw new CantLoginException();

View file

@ -26,7 +26,7 @@ public function index(Request $request, Response $response): Response
$this->assignView( $this->assignView(
'pagetitle', 'pagetitle',
t('Picture wall') .' - '. $this->container->conf->get('general.title', 'Shaarli') t('Picture wall') . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
); );
// Optionally filter the results: // Optionally filter the results:

View file

@ -144,7 +144,8 @@ protected function redirectFromReferer(
if (null !== $referer) { if (null !== $referer) {
$currentUrl = parse_url($referer); $currentUrl = parse_url($referer);
// If the referer is not related to Shaarli instance, redirect to default // If the referer is not related to Shaarli instance, redirect to default
if (isset($currentUrl['host']) if (
isset($currentUrl['host'])
&& strpos(index_url($this->container->environment), $currentUrl['host']) === false && strpos(index_url($this->container->environment), $currentUrl['host']) === false
) { ) {
return $response->withRedirect($defaultPath); return $response->withRedirect($defaultPath);
@ -173,7 +174,7 @@ protected function redirectFromReferer(
} }
} }
$queryString = count($params) > 0 ? '?'. http_build_query($params) : ''; $queryString = count($params) > 0 ? '?' . http_build_query($params) : '';
$anchor = $anchor ? '#' . $anchor : ''; $anchor = $anchor ? '#' . $anchor : '';
return $response->withRedirect($path . $queryString . $anchor); return $response->withRedirect($path . $queryString . $anchor);

View file

@ -84,10 +84,10 @@ protected function processRequest(string $type, Request $request, Response $resp
$this->executePageHooks('render_tag' . $type, $data, 'tag.' . $type); $this->executePageHooks('render_tag' . $type, $data, 'tag.' . $type);
$this->assignAllView($data); $this->assignAllView($data);
$searchTags = !empty($searchTags) ? trim(str_replace($tagsSeparator, ' ', $searchTags)) .' - ' : ''; $searchTags = !empty($searchTags) ? trim(str_replace($tagsSeparator, ' ', $searchTags)) . ' - ' : '';
$this->assignView( $this->assignView(
'pagetitle', 'pagetitle',
$searchTags . t('Tag '. $type) .' - '. $this->container->conf->get('general.title', 'Shaarli') $searchTags . t('Tag ' . $type) . ' - ' . $this->container->conf->get('general.title', 'Shaarli')
); );
return $response->write($this->render('tag.' . $type)); return $response->write($this->render('tag.' . $type));

View file

@ -27,7 +27,7 @@ public function addTag(Request $request, Response $response, array $args): Respo
// In case browser does not send HTTP_REFERER, we search a single tag // In case browser does not send HTTP_REFERER, we search a single tag
if (null === $referer) { if (null === $referer) {
if (null !== $newTag) { if (null !== $newTag) {
return $this->redirect($response, '/?searchtags='. urlencode($newTag)); return $this->redirect($response, '/?searchtags=' . urlencode($newTag));
} }
return $this->redirect($response, '/'); return $this->redirect($response, '/');
@ -37,7 +37,7 @@ public function addTag(Request $request, Response $response, array $args): Respo
parse_str($currentUrl['query'] ?? '', $params); parse_str($currentUrl['query'] ?? '', $params);
if (null === $newTag) { if (null === $newTag) {
return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params)); return $response->withRedirect(($currentUrl['path'] ?? './') . '?' . http_build_query($params));
} }
// Prevent redirection loop // Prevent redirection loop
@ -68,7 +68,7 @@ public function addTag(Request $request, Response $response, array $args): Respo
// We also remove page (keeping the same page has no sense, since the results are different) // We also remove page (keeping the same page has no sense, since the results are different)
unset($params['page']); unset($params['page']);
return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params)); return $response->withRedirect(($currentUrl['path'] ?? './') . '?' . http_build_query($params));
} }
/** /**
@ -90,7 +90,7 @@ public function removeTag(Request $request, Response $response, array $args): Re
parse_str($currentUrl['query'] ?? '', $params); parse_str($currentUrl['query'] ?? '', $params);
if (null === $tagToRemove) { if (null === $tagToRemove) {
return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params)); return $response->withRedirect(($currentUrl['path'] ?? './') . '?' . http_build_query($params));
} }
// Prevent redirection loop // Prevent redirection loop

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Helper; namespace Shaarli\Helper;
use Exception; use Exception;
@ -16,7 +17,7 @@ class ApplicationUtils
public static $GITHUB_URL = 'https://github.com/shaarli/Shaarli'; public static $GITHUB_URL = 'https://github.com/shaarli/Shaarli';
public static $GIT_RAW_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli'; public static $GIT_RAW_URL = 'https://raw.githubusercontent.com/shaarli/Shaarli';
public static $GIT_BRANCHES = array('latest', 'stable'); public static $GIT_BRANCHES = ['latest', 'stable'];
private static $VERSION_START_TAG = '<?php /* '; private static $VERSION_START_TAG = '<?php /* ';
private static $VERSION_END_TAG = ' */ ?>'; private static $VERSION_END_TAG = ' */ ?>';
@ -64,8 +65,8 @@ public static function getVersion($remote, $timeout = 2)
} }
return str_replace( return str_replace(
array(self::$VERSION_START_TAG, self::$VERSION_END_TAG, PHP_EOL), [self::$VERSION_START_TAG, self::$VERSION_END_TAG, PHP_EOL],
array('', '', ''), ['', '', ''],
$data $data
); );
} }
@ -184,13 +185,15 @@ public static function checkResourcePermissions(ConfigManager $conf, bool $minim
$rainTplDir = rtrim($conf->get('resource.raintpl_tpl'), '/'); $rainTplDir = rtrim($conf->get('resource.raintpl_tpl'), '/');
// Check script and template directories are readable // Check script and template directories are readable
foreach ([ foreach (
[
'application', 'application',
'inc', 'inc',
'plugins', 'plugins',
$rainTplDir, $rainTplDir,
$rainTplDir . '/' . $conf->get('resource.theme'), $rainTplDir . '/' . $conf->get('resource.theme'),
] as $path) { ] as $path
) {
if (!is_readable(realpath($path))) { if (!is_readable(realpath($path))) {
$errors[] = '"' . $path . '" ' . t('directory is not readable'); $errors[] = '"' . $path . '" ' . t('directory is not readable');
} }
@ -224,13 +227,15 @@ public static function checkResourcePermissions(ConfigManager $conf, bool $minim
} }
// Check configuration files are readable and writable // Check configuration files are readable and writable
foreach (array( foreach (
[
$conf->getConfigFileExt(), $conf->getConfigFileExt(),
$conf->get('resource.datastore'), $conf->get('resource.datastore'),
$conf->get('resource.ban_file'), $conf->get('resource.ban_file'),
$conf->get('resource.log'), $conf->get('resource.log'),
$conf->get('resource.update_check'), $conf->get('resource.update_check'),
) as $path) { ] as $path
) {
if (!is_file(realpath($path))) { if (!is_file(realpath($path))) {
# the file may not exist yet # the file may not exist yet
continue; continue;

View file

@ -105,7 +105,7 @@ public static function clearFolder(string $path, bool $selfDelete, array $exclud
} }
foreach (new \DirectoryIterator($path) as $file) { foreach (new \DirectoryIterator($path) as $file) {
if($file->isDot()) { if ($file->isDot()) {
continue; continue;
} }
@ -116,7 +116,7 @@ public static function clearFolder(string $path, bool $selfDelete, array $exclud
if ($file->isFile()) { if ($file->isFile()) {
unlink($file->getPathname()); unlink($file->getPathname());
} elseif($file->isDir()) { } elseif ($file->isDir()) {
$skipped = static::clearFolder($file->getRealPath(), true, $exclude) || $skipped; $skipped = static::clearFolder($file->getRealPath(), true, $exclude) || $skipped;
} }
} }

View file

@ -48,7 +48,7 @@ function get_http_response(
$cleanUrl = $urlObj->idnToAscii(); $cleanUrl = $urlObj->idnToAscii();
if (!filter_var($cleanUrl, FILTER_VALIDATE_URL) || !$urlObj->isHttp()) { if (!filter_var($cleanUrl, FILTER_VALIDATE_URL) || !$urlObj->isHttp()) {
return array(array(0 => 'Invalid HTTP UrlUtils'), false); return [[0 => 'Invalid HTTP UrlUtils'], false];
} }
$userAgent = $userAgent =
@ -71,7 +71,7 @@ function get_http_response(
$ch = curl_init($cleanUrl); $ch = curl_init($cleanUrl);
if ($ch === false) { if ($ch === false) {
return array(array(0 => 'curl_init() error'), false); return [[0 => 'curl_init() error'], false];
} }
// General cURL settings // General cURL settings
@ -82,7 +82,7 @@ function get_http_response(
curl_setopt( curl_setopt(
$ch, $ch,
CURLOPT_HTTPHEADER, CURLOPT_HTTPHEADER,
array('Accept-Language: ' . $acceptLanguage) ['Accept-Language: ' . $acceptLanguage]
); );
curl_setopt($ch, CURLOPT_MAXREDIRS, $maxRedirs); curl_setopt($ch, CURLOPT_MAXREDIRS, $maxRedirs);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@ -90,7 +90,7 @@ function get_http_response(
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent); curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
// Max download size management // Max download size management
curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024*16); curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024 * 16);
curl_setopt($ch, CURLOPT_NOPROGRESS, false); curl_setopt($ch, CURLOPT_NOPROGRESS, false);
if (is_callable($curlHeaderFunction)) { if (is_callable($curlHeaderFunction)) {
curl_setopt($ch, CURLOPT_HEADERFUNCTION, $curlHeaderFunction); curl_setopt($ch, CURLOPT_HEADERFUNCTION, $curlHeaderFunction);
@ -122,9 +122,9 @@ function ($arg0, $arg1, $arg2, $arg3, $arg4) use ($maxBytes) {
* Removing this would require updating * Removing this would require updating
* GetHttpUrlTest::testGetInvalidRemoteUrl() * GetHttpUrlTest::testGetInvalidRemoteUrl()
*/ */
return array(false, false); return [false, false];
} }
return array(array(0 => 'curl_exec() error: ' . $errorStr), false); return [[0 => 'curl_exec() error: ' . $errorStr], false];
} }
// Formatting output like the fallback method // Formatting output like the fallback method
@ -135,7 +135,7 @@ function ($arg0, $arg1, $arg2, $arg3, $arg4) use ($maxBytes) {
$rawHeadersLastRedir = end($rawHeadersArrayRedirs); $rawHeadersLastRedir = end($rawHeadersArrayRedirs);
$content = substr($response, $headSize); $content = substr($response, $headSize);
$headers = array(); $headers = [];
foreach (preg_split('~[\r\n]+~', $rawHeadersLastRedir) as $line) { foreach (preg_split('~[\r\n]+~', $rawHeadersLastRedir) as $line) {
if (empty($line) || ctype_space($line)) { if (empty($line) || ctype_space($line)) {
continue; continue;
@ -146,7 +146,7 @@ function ($arg0, $arg1, $arg2, $arg3, $arg4) use ($maxBytes) {
$value = $splitLine[1]; $value = $splitLine[1];
if (array_key_exists($key, $headers)) { if (array_key_exists($key, $headers)) {
if (!is_array($headers[$key])) { if (!is_array($headers[$key])) {
$headers[$key] = array(0 => $headers[$key]); $headers[$key] = [0 => $headers[$key]];
} }
$headers[$key][] = $value; $headers[$key][] = $value;
} else { } else {
@ -157,7 +157,7 @@ function ($arg0, $arg1, $arg2, $arg3, $arg4) use ($maxBytes) {
} }
} }
return array($headers, $content); return [$headers, $content];
} }
/** /**
@ -188,15 +188,15 @@ function get_http_response_fallback(
$acceptLanguage, $acceptLanguage,
$maxRedr $maxRedr
) { ) {
$options = array( $options = [
'http' => array( 'http' => [
'method' => 'GET', 'method' => 'GET',
'timeout' => $timeout, 'timeout' => $timeout,
'user_agent' => $userAgent, 'user_agent' => $userAgent,
'header' => "Accept: */*\r\n" 'header' => "Accept: */*\r\n"
. 'Accept-Language: ' . $acceptLanguage . 'Accept-Language: ' . $acceptLanguage
) ]
); ];
stream_context_set_default($options); stream_context_set_default($options);
list($headers, $finalUrl) = get_redirected_headers($cleanUrl, $maxRedr); list($headers, $finalUrl) = get_redirected_headers($cleanUrl, $maxRedr);
@ -207,7 +207,7 @@ function get_http_response_fallback(
} }
if (! $headers) { if (! $headers) {
return array($headers, false); return [$headers, false];
} }
try { try {
@ -215,10 +215,10 @@ function get_http_response_fallback(
$context = stream_context_create($options); $context = stream_context_create($options);
$content = file_get_contents($finalUrl, false, $context, -1, $maxBytes); $content = file_get_contents($finalUrl, false, $context, -1, $maxBytes);
} catch (Exception $exc) { } catch (Exception $exc) {
return array(array(0 => 'HTTP Error'), $exc->getMessage()); return [[0 => 'HTTP Error'], $exc->getMessage()];
} }
return array($headers, $content); return [$headers, $content];
} }
/** /**
@ -237,10 +237,12 @@ function get_redirected_headers($url, $redirectionLimit = 3)
} }
// Headers found, redirection found, and limit not reached. // Headers found, redirection found, and limit not reached.
if ($redirectionLimit-- > 0 if (
$redirectionLimit-- > 0
&& !empty($headers) && !empty($headers)
&& (strpos($headers[0], '301') !== false || strpos($headers[0], '302') !== false) && (strpos($headers[0], '301') !== false || strpos($headers[0], '302') !== false)
&& !empty($headers['Location'])) { && !empty($headers['Location'])
) {
$redirection = is_array($headers['Location']) ? end($headers['Location']) : $headers['Location']; $redirection = is_array($headers['Location']) ? end($headers['Location']) : $headers['Location'];
if ($redirection != $url) { if ($redirection != $url) {
$redirection = getAbsoluteUrl($url, $redirection); $redirection = getAbsoluteUrl($url, $redirection);
@ -248,7 +250,7 @@ function get_redirected_headers($url, $redirectionLimit = 3)
} }
} }
return array($headers, $url); return [$headers, $url];
} }
/** /**
@ -270,7 +272,7 @@ function getAbsoluteUrl($originalUrl, $newUrl)
} }
$parts = parse_url($originalUrl); $parts = parse_url($originalUrl);
$final = $parts['scheme'] .'://'. $parts['host']; $final = $parts['scheme'] . '://' . $parts['host'];
$final .= (!empty($parts['port'])) ? $parts['port'] : ''; $final .= (!empty($parts['port'])) ? $parts['port'] : '';
$final .= '/'; $final .= '/';
if ($newUrl[0] != '/') { if ($newUrl[0] != '/') {
@ -323,7 +325,8 @@ function server_url($server)
$scheme = 'https'; $scheme = 'https';
} }
if (($scheme == 'http' && $port != '80') if (
($scheme == 'http' && $port != '80')
|| ($scheme == 'https' && $port != '443') || ($scheme == 'https' && $port != '443')
) { ) {
$port = ':' . $port; $port = ':' . $port;
@ -344,22 +347,26 @@ function server_url($server)
$host = $server['SERVER_NAME']; $host = $server['SERVER_NAME'];
} }
return $scheme.'://'.$host.$port; return $scheme . '://' . $host . $port;
} }
// SSL detection // SSL detection
if ((! empty($server['HTTPS']) && strtolower($server['HTTPS']) == 'on') if (
|| (isset($server['SERVER_PORT']) && $server['SERVER_PORT'] == '443')) { (! empty($server['HTTPS']) && strtolower($server['HTTPS']) == 'on')
|| (isset($server['SERVER_PORT']) && $server['SERVER_PORT'] == '443')
) {
$scheme = 'https'; $scheme = 'https';
} }
// Do not append standard port values // Do not append standard port values
if (($scheme == 'http' && $server['SERVER_PORT'] != '80') if (
|| ($scheme == 'https' && $server['SERVER_PORT'] != '443')) { ($scheme == 'http' && $server['SERVER_PORT'] != '80')
$port = ':'.$server['SERVER_PORT']; || ($scheme == 'https' && $server['SERVER_PORT'] != '443')
) {
$port = ':' . $server['SERVER_PORT'];
} }
return $scheme.'://'.$server['SERVER_NAME'].$port; return $scheme . '://' . $server['SERVER_NAME'] . $port;
} }
/** /**
@ -567,7 +574,10 @@ function get_curl_download_callback(
* *
* @return int|bool length of $data or false if we need to stop the download * @return int|bool length of $data or false if we need to stop the download
*/ */
return function ($ch, $data) use ( return function (
$ch,
$data
) use (
$retrieveDescription, $retrieveDescription,
$tagsSeparator, $tagsSeparator,
&$charset, &$charset,
@ -601,7 +611,7 @@ function get_curl_download_callback(
$foundChunk = $currentChunk; $foundChunk = $currentChunk;
// Keywords use the format tag1, tag2 multiple words, tag // Keywords use the format tag1, tag2 multiple words, tag
// So we split the result with `,`, then if a tag contains the separator we replace it by `-`. // So we split the result with `,`, then if a tag contains the separator we replace it by `-`.
$keywords = tags_array2str(array_map(function(string $keyword) use ($tagsSeparator): string { $keywords = tags_array2str(array_map(function (string $keyword) use ($tagsSeparator): string {
return tags_array2str(tags_str2array($keyword, $tagsSeparator), '-'); return tags_array2str(tags_str2array($keyword, $tagsSeparator), '-');
}, tags_str2array($keywords, ',')), $tagsSeparator); }, tags_str2array($keywords, ',')), $tagsSeparator);
} }
@ -611,7 +621,8 @@ function get_curl_download_callback(
// If we already found either the title, description or keywords, // If we already found either the title, description or keywords,
// it's highly unlikely that we'll found the other metas further than // it's highly unlikely that we'll found the other metas further than
// in the same chunk of data or the next one. So we also stop the download after that. // in the same chunk of data or the next one. So we also stop the download after that.
if ((!empty($responseCode) && !empty($contentType) && !empty($charset)) && $foundChunk !== null if (
(!empty($responseCode) && !empty($contentType) && !empty($charset)) && $foundChunk !== null
&& (! $retrieveDescription && (! $retrieveDescription
|| $foundChunk < $currentChunk || $foundChunk < $currentChunk
|| (!empty($title) && !empty($description) && !empty($keywords)) || (!empty($title) && !empty($description) && !empty($keywords))

View file

@ -17,7 +17,7 @@
*/ */
class Url class Url
{ {
private static $annoyingQueryParams = array( private static $annoyingQueryParams = [
// Facebook // Facebook
'action_object_map=', 'action_object_map=',
'action_ref_map=', 'action_ref_map=',
@ -37,15 +37,15 @@ class Url
// Other // Other
'campaign_' 'campaign_'
); ];
private static $annoyingFragments = array( private static $annoyingFragments = [
// ATInternet // ATInternet
'xtor=RSS-', 'xtor=RSS-',
// Misc. // Misc.
'tk.rss_all' 'tk.rss_all'
); ];
/* /*
* URL parts represented as an array * URL parts represented as an array
@ -120,7 +120,7 @@ protected function cleanupQuery()
foreach (self::$annoyingQueryParams as $annoying) { foreach (self::$annoyingQueryParams as $annoying) {
foreach ($queryParams as $param) { foreach ($queryParams as $param) {
if (startsWith($param, $annoying)) { if (startsWith($param, $annoying)) {
$queryParams = array_diff($queryParams, array($param)); $queryParams = array_diff($queryParams, [$param]);
continue; continue;
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Converts an array-represented URL to a string * Converts an array-represented URL to a string
* *
@ -12,15 +13,15 @@
*/ */
function unparse_url($parsedUrl) function unparse_url($parsedUrl)
{ {
$scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'].'://' : ''; $scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'] . '://' : '';
$host = isset($parsedUrl['host']) ? $parsedUrl['host'] : ''; $host = isset($parsedUrl['host']) ? $parsedUrl['host'] : '';
$port = isset($parsedUrl['port']) ? ':'.$parsedUrl['port'] : ''; $port = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : '';
$user = isset($parsedUrl['user']) ? $parsedUrl['user'] : ''; $user = isset($parsedUrl['user']) ? $parsedUrl['user'] : '';
$pass = isset($parsedUrl['pass']) ? ':'.$parsedUrl['pass'] : ''; $pass = isset($parsedUrl['pass']) ? ':' . $parsedUrl['pass'] : '';
$pass = ($user || $pass) ? "$pass@" : ''; $pass = ($user || $pass) ? "$pass@" : '';
$path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : '';
$query = isset($parsedUrl['query']) ? '?'.$parsedUrl['query'] : ''; $query = isset($parsedUrl['query']) ? '?' . $parsedUrl['query'] : '';
$fragment = isset($parsedUrl['fragment']) ? '#'.$parsedUrl['fragment'] : ''; $fragment = isset($parsedUrl['fragment']) ? '#' . $parsedUrl['fragment'] : '';
return "$scheme$user$pass$host$port$path$query$fragment"; return "$scheme$user$pass$host$port$path$query$fragment";
} }

View file

@ -51,7 +51,7 @@ public function post(Request $request, Response $response): Response
if (!$this->container->loginManager->isLoggedIn()) { if (!$this->container->loginManager->isLoggedIn()) {
$parameters = $buildParameters($request->getQueryParams(), true); $parameters = $buildParameters($request->getQueryParams(), true);
return $this->redirect($response, '/login?returnurl='. $this->getBasePath() . $route . $parameters); return $this->redirect($response, '/login?returnurl=' . $this->getBasePath() . $route . $parameters);
} }
$parameters = $buildParameters($request->getQueryParams(), false); $parameters = $buildParameters($request->getQueryParams(), false);

View file

@ -62,7 +62,7 @@ class LegacyLinkDB implements Iterator, Countable, ArrayAccess
private $datastore; private $datastore;
// Link date storage format // Link date storage format
const LINK_DATE_FORMAT = 'Ymd_His'; public const LINK_DATE_FORMAT = 'Ymd_His';
// List of bookmarks (associative array) // List of bookmarks (associative array)
// - key: link date (e.g. "20110823_124546"), // - key: link date (e.g. "20110823_124546"),
@ -240,8 +240,8 @@ private function check()
} }
// Create a dummy database for example // Create a dummy database for example
$this->links = array(); $this->links = [];
$link = array( $link = [
'id' => 1, 'id' => 1,
'title' => t('The personal, minimalist, super-fast, database free, bookmarking service'), 'title' => t('The personal, minimalist, super-fast, database free, bookmarking service'),
'url' => 'https://shaarli.readthedocs.io', 'url' => 'https://shaarli.readthedocs.io',
@ -257,11 +257,11 @@ private function check()
'created' => new DateTime(), 'created' => new DateTime(),
'tags' => 'opensource software', 'tags' => 'opensource software',
'sticky' => false, 'sticky' => false,
); ];
$link['shorturl'] = link_small_hash($link['created'], $link['id']); $link['shorturl'] = link_small_hash($link['created'], $link['id']);
$this->links[1] = $link; $this->links[1] = $link;
$link = array( $link = [
'id' => 0, 'id' => 0,
'title' => t('My secret stuff... - Pastebin.com'), 'title' => t('My secret stuff... - Pastebin.com'),
'url' => 'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=', 'url' => 'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=',
@ -270,7 +270,7 @@ private function check()
'created' => new DateTime('1 minute ago'), 'created' => new DateTime('1 minute ago'),
'tags' => 'secretstuff', 'tags' => 'secretstuff',
'sticky' => false, 'sticky' => false,
); ];
$link['shorturl'] = link_small_hash($link['created'], $link['id']); $link['shorturl'] = link_small_hash($link['created'], $link['id']);
$this->links[0] = $link; $this->links[0] = $link;
@ -285,7 +285,7 @@ private function read()
{ {
// Public bookmarks are hidden and user not logged in => nothing to show // Public bookmarks are hidden and user not logged in => nothing to show
if ($this->hidePublicLinks && !$this->loggedIn) { if ($this->hidePublicLinks && !$this->loggedIn) {
$this->links = array(); $this->links = [];
return; return;
} }
@ -293,7 +293,7 @@ private function read()
$this->ids = []; $this->ids = [];
$this->links = FileUtils::readFlatDB($this->datastore, []); $this->links = FileUtils::readFlatDB($this->datastore, []);
$toremove = array(); $toremove = [];
foreach ($this->links as $key => &$link) { foreach ($this->links as $key => &$link) {
if (!$this->loggedIn && $link['private'] != 0) { if (!$this->loggedIn && $link['private'] != 0) {
// Transition for not upgraded databases. // Transition for not upgraded databases.
@ -414,7 +414,7 @@ public function filterDay($request)
* @return array filtered bookmarks, all bookmarks if no suitable filter was provided. * @return array filtered bookmarks, all bookmarks if no suitable filter was provided.
*/ */
public function filterSearch( public function filterSearch(
$filterRequest = array(), $filterRequest = [],
$casesensitive = false, $casesensitive = false,
$visibility = 'all', $visibility = 'all',
$untaggedonly = false $untaggedonly = false
@ -512,7 +512,7 @@ public function renameTag($from, $to)
*/ */
public function days() public function days()
{ {
$linkDays = array(); $linkDays = [];
foreach ($this->links as $link) { foreach ($this->links as $link) {
$linkDays[$link['created']->format('Ymd')] = 0; $linkDays[$link['created']->format('Ymd')] = 0;
} }

View file

@ -120,7 +120,7 @@ private function noFilter($visibility = 'all')
return $this->links; return $this->links;
} }
$out = array(); $out = [];
foreach ($this->links as $key => $value) { foreach ($this->links as $key => $value) {
if ($value['private'] && $visibility === 'private') { if ($value['private'] && $visibility === 'private') {
$out[$key] = $value; $out[$key] = $value;
@ -143,7 +143,7 @@ private function noFilter($visibility = 'all')
*/ */
private function filterSmallHash($smallHash) private function filterSmallHash($smallHash)
{ {
$filtered = array(); $filtered = [];
foreach ($this->links as $key => $l) { foreach ($this->links as $key => $l) {
if ($smallHash == $l['shorturl']) { if ($smallHash == $l['shorturl']) {
// Yes, this is ugly and slow // Yes, this is ugly and slow
@ -186,7 +186,7 @@ private function filterFulltext($searchterms, $visibility = 'all')
return $this->noFilter($visibility); return $this->noFilter($visibility);
} }
$filtered = array(); $filtered = [];
$search = mb_convert_case(html_entity_decode($searchterms), MB_CASE_LOWER, 'UTF-8'); $search = mb_convert_case(html_entity_decode($searchterms), MB_CASE_LOWER, 'UTF-8');
$exactRegex = '/"([^"]+)"/'; $exactRegex = '/"([^"]+)"/';
// Retrieve exact search terms. // Retrieve exact search terms.
@ -198,8 +198,8 @@ private function filterFulltext($searchterms, $visibility = 'all')
$explodedSearchAnd = array_values(array_filter($explodedSearchAnd)); $explodedSearchAnd = array_values(array_filter($explodedSearchAnd));
// Filter excluding terms and update andSearch. // Filter excluding terms and update andSearch.
$excludeSearch = array(); $excludeSearch = [];
$andSearch = array(); $andSearch = [];
foreach ($explodedSearchAnd as $needle) { foreach ($explodedSearchAnd as $needle) {
if ($needle[0] == '-' && strlen($needle) > 1) { if ($needle[0] == '-' && strlen($needle) > 1) {
$excludeSearch[] = substr($needle, 1); $excludeSearch[] = substr($needle, 1);
@ -208,7 +208,7 @@ private function filterFulltext($searchterms, $visibility = 'all')
} }
} }
$keys = array('title', 'description', 'url', 'tags'); $keys = ['title', 'description', 'url', 'tags'];
// Iterate over every stored link. // Iterate over every stored link.
foreach ($this->links as $id => $link) { foreach ($this->links as $id => $link) {
@ -336,7 +336,7 @@ public function filterTags($tags, $casesensitive = false, $visibility = 'all')
} }
// create resulting array // create resulting array
$filtered = array(); $filtered = [];
// iterate over each link // iterate over each link
foreach ($this->links as $key => $link) { foreach ($this->links as $key => $link) {
@ -352,7 +352,7 @@ public function filterTags($tags, $casesensitive = false, $visibility = 'all')
$search = $link['tags']; // build search string, start with tags of current link $search = $link['tags']; // build search string, start with tags of current link
if (strlen(trim($link['description'])) && strpos($link['description'], '#') !== false) { if (strlen(trim($link['description'])) && strpos($link['description'], '#') !== false) {
// description given and at least one possible tag found // description given and at least one possible tag found
$descTags = array(); $descTags = [];
// find all tags in the form of #tag in the description // find all tags in the form of #tag in the description
preg_match_all( preg_match_all(
'/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm', '/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm',
@ -419,7 +419,7 @@ public function filterDay($day)
throw new Exception('Invalid date format'); throw new Exception('Invalid date format');
} }
$filtered = array(); $filtered = [];
foreach ($this->links as $key => $l) { foreach ($this->links as $key => $l) {
if ($l['created']->format('Ymd') == $day) { if ($l['created']->format('Ymd') == $day) {
$filtered[$key] = $l; $filtered[$key] = $l;

View file

@ -93,7 +93,7 @@ public function __construct($doneUpdates, $linkDB, $conf, $isLoggedIn, &$session
*/ */
public function update() public function update()
{ {
$updatesRan = array(); $updatesRan = [];
// If the user isn't logged in, exit without updating. // If the user isn't logged in, exit without updating.
if ($this->isLoggedIn !== true) { if ($this->isLoggedIn !== true) {
@ -106,7 +106,8 @@ public function update()
foreach ($this->methods as $method) { foreach ($this->methods as $method) {
// Not an update method or already done, pass. // Not an update method or already done, pass.
if (!startsWith($method->getName(), 'updateMethod') if (
!startsWith($method->getName(), 'updateMethod')
|| in_array($method->getName(), $this->doneUpdates) || in_array($method->getName(), $this->doneUpdates)
) { ) {
continue; continue;
@ -189,7 +190,7 @@ public function updateMethodConfigToJson()
} }
// Set sub config keys (config and plugins) // Set sub config keys (config and plugins)
$subConfig = array('config', 'plugins'); $subConfig = ['config', 'plugins'];
foreach ($subConfig as $sub) { foreach ($subConfig as $sub) {
foreach ($oldConfig[$sub] as $key => $value) { foreach ($oldConfig[$sub] as $key => $value) {
if (isset($legacyMap[$sub . '.' . $key])) { if (isset($legacyMap[$sub . '.' . $key])) {
@ -259,7 +260,7 @@ public function updateMethodDatastoreIds()
$save = $this->conf->get('resource.data_dir') . '/datastore.' . date('YmdHis') . '.php'; $save = $this->conf->get('resource.data_dir') . '/datastore.' . date('YmdHis') . '.php';
copy($this->conf->get('resource.datastore'), $save); copy($this->conf->get('resource.datastore'), $save);
$links = array(); $links = [];
foreach ($this->linkDB as $offset => $value) { foreach ($this->linkDB as $offset => $value) {
$links[] = $value; $links[] = $value;
unset($this->linkDB[$offset]); unset($this->linkDB[$offset]);
@ -498,7 +499,8 @@ public function updateMethodVisibilitySession()
*/ */
public function updateMethodDownloadSizeAndTimeoutConf() public function updateMethodDownloadSizeAndTimeoutConf()
{ {
if ($this->conf->exists('general.download_max_size') if (
$this->conf->exists('general.download_max_size')
&& $this->conf->exists('general.download_timeout') && $this->conf->exists('general.download_timeout')
) { ) {
return true; return true;

View file

@ -59,11 +59,11 @@ public function filterAndFormat(
$indexUrl $indexUrl
) { ) {
// see tpl/export.html for possible values // see tpl/export.html for possible values
if (!in_array($selection, array('all', 'public', 'private'))) { if (!in_array($selection, ['all', 'public', 'private'])) {
throw new Exception(t('Invalid export selection:') . ' "' . $selection . '"'); throw new Exception(t('Invalid export selection:') . ' "' . $selection . '"');
} }
$bookmarkLinks = array(); $bookmarkLinks = [];
foreach ($this->bookmarkService->search([], $selection) as $bookmark) { foreach ($this->bookmarkService->search([], $selection) as $bookmark) {
$link = $formatter->format($bookmark); $link = $formatter->format($bookmark);
$link['taglist'] = implode(',', $bookmark->getTags()); $link['taglist'] = implode(',', $bookmark->getTags());

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Plugin; namespace Shaarli\Plugin;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
@ -23,7 +24,7 @@ class PluginManager
* *
* @var array $loadedPlugins * @var array $loadedPlugins
*/ */
private $loadedPlugins = array(); private $loadedPlugins = [];
/** /**
* @var ConfigManager Configuration Manager instance. * @var ConfigManager Configuration Manager instance.
@ -57,7 +58,7 @@ class PluginManager
public function __construct(&$conf) public function __construct(&$conf)
{ {
$this->conf = $conf; $this->conf = $conf;
$this->errors = array(); $this->errors = [];
} }
/** /**
@ -98,7 +99,7 @@ public function load($authorizedPlugins)
* *
* @return void * @return void
*/ */
public function executeHooks($hook, &$data, $params = array()) public function executeHooks($hook, &$data, $params = [])
{ {
$metadataParameters = [ $metadataParameters = [
'target' => '_PAGE_', 'target' => '_PAGE_',
@ -196,7 +197,7 @@ public function buildHookName($hook, $pluginName)
*/ */
public function getPluginsMeta() public function getPluginsMeta()
{ {
$metaData = array(); $metaData = [];
$dirs = glob(self::$PLUGINS_PATH . '/*', GLOB_ONLYDIR | GLOB_MARK); $dirs = glob(self::$PLUGINS_PATH . '/*', GLOB_ONLYDIR | GLOB_MARK);
// Browse all plugin directories. // Browse all plugin directories.
@ -217,9 +218,9 @@ public function getPluginsMeta()
if (isset($metaData[$plugin]['parameters'])) { if (isset($metaData[$plugin]['parameters'])) {
$params = explode(';', $metaData[$plugin]['parameters']); $params = explode(';', $metaData[$plugin]['parameters']);
} else { } else {
$params = array(); $params = [];
} }
$metaData[$plugin]['parameters'] = array(); $metaData[$plugin]['parameters'] = [];
foreach ($params as $param) { foreach ($params as $param) {
if (empty($param)) { if (empty($param)) {
continue; continue;

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Plugin\Exception; namespace Shaarli\Plugin\Exception;
use Exception; use Exception;

View file

@ -23,10 +23,10 @@ class ThemeUtils
public static function getThemes($tplDir) public static function getThemes($tplDir)
{ {
$tplDir = rtrim($tplDir, '/'); $tplDir = rtrim($tplDir, '/');
$allTheme = glob($tplDir.'/*', GLOB_ONLYDIR); $allTheme = glob($tplDir . '/*', GLOB_ONLYDIR);
$themes = []; $themes = [];
foreach ($allTheme as $value) { foreach ($allTheme as $value) {
$themes[] = str_replace($tplDir.'/', '', $value); $themes[] = str_replace($tplDir . '/', '', $value);
} }
return $themes; return $themes;

View file

@ -1,6 +1,5 @@
<?php <?php
namespace Shaarli\Security; namespace Shaarli\Security;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -47,7 +46,8 @@ class BanManager
* @param string $banFile Path to the file containing IP bans and failures * @param string $banFile Path to the file containing IP bans and failures
* @param LoggerInterface $logger PSR-3 logger to save login attempts in log directory * @param LoggerInterface $logger PSR-3 logger to save login attempts in log directory
*/ */
public function __construct($trustedProxies, $nbAttempts, $banDuration, $banFile, LoggerInterface $logger) { public function __construct($trustedProxies, $nbAttempts, $banDuration, $banFile, LoggerInterface $logger)
{
$this->trustedProxies = $trustedProxies; $this->trustedProxies = $trustedProxies;
$this->nbAttempts = $nbAttempts; $this->nbAttempts = $nbAttempts;
$this->banDuration = $banDuration; $this->banDuration = $banDuration;
@ -80,7 +80,7 @@ public function handleFailedAttempt($server)
if ($this->failures[$ip] >= $this->nbAttempts) { if ($this->failures[$ip] >= $this->nbAttempts) {
$this->bans[$ip] = time() + $this->banDuration; $this->bans[$ip] = time() + $this->banDuration;
$this->logger->info(format_log('IP address banned from login: '. $ip, $ip)); $this->logger->info(format_log('IP address banned from login: ' . $ip, $ip));
} }
$this->writeBanFile(); $this->writeBanFile();
} }
@ -136,7 +136,7 @@ public function isBanned($server)
unset($this->failures[$ip]); unset($this->failures[$ip]);
} }
unset($this->bans[$ip]); unset($this->bans[$ip]);
$this->logger->info(format_log('Ban lifted for: '. $ip, $ip)); $this->logger->info(format_log('Ban lifted for: ' . $ip, $ip));
$this->writeBanFile(); $this->writeBanFile();
return false; return false;

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Security; namespace Shaarli\Security;
use Exception; use Exception;
@ -106,7 +107,8 @@ public function checkLoginState($clientIpId)
// The user client has a valid stay-signed-in cookie // The user client has a valid stay-signed-in cookie
// Session information is updated with the current client information // Session information is updated with the current client information
$this->sessionManager->storeLoginInfo($clientIpId); $this->sessionManager->storeLoginInfo($clientIpId);
} elseif ($this->sessionManager->hasSessionExpired() } elseif (
$this->sessionManager->hasSessionExpired()
|| $this->sessionManager->hasClientIpChanged($clientIpId) || $this->sessionManager->hasClientIpChanged($clientIpId)
) { ) {
$this->sessionManager->logout(); $this->sessionManager->logout();
@ -145,7 +147,8 @@ public function checkCredentials($clientIpId, $login, $password)
// Check credentials // Check credentials
try { try {
$useLdapLogin = !empty($this->configManager->get('ldap.host')); $useLdapLogin = !empty($this->configManager->get('ldap.host'));
if ($login === $this->configManager->get('credentials.login') if (
$login === $this->configManager->get('credentials.login')
&& ( && (
(false === $useLdapLogin && $this->checkCredentialsFromLocalConfig($login, $password)) (false === $useLdapLogin && $this->checkCredentialsFromLocalConfig($login, $password))
|| (true === $useLdapLogin && $this->checkCredentialsFromLdap($login, $password)) || (true === $useLdapLogin && $this->checkCredentialsFromLdap($login, $password))
@ -156,7 +159,7 @@ public function checkCredentials($clientIpId, $login, $password)
return true; return true;
} }
} catch(Exception $exception) { } catch (Exception $exception) {
$this->logger->info(format_log('Exception while checking credentials: ' . $exception, $clientIpId)); $this->logger->info(format_log('Exception while checking credentials: ' . $exception, $clientIpId));
} }
@ -174,7 +177,8 @@ public function checkCredentials($clientIpId, $login, $password)
* *
* @return bool true if the provided credentials are valid, false otherwise * @return bool true if the provided credentials are valid, false otherwise
*/ */
public function checkCredentialsFromLocalConfig($login, $password) { public function checkCredentialsFromLocalConfig($login, $password)
{
$hash = sha1($password . $login . $this->configManager->get('credentials.salt')); $hash = sha1($password . $login . $this->configManager->get('credentials.salt'));
return $login == $this->configManager->get('credentials.login') return $login == $this->configManager->get('credentials.login')
@ -193,14 +197,14 @@ public function checkCredentialsFromLocalConfig($login, $password) {
*/ */
public function checkCredentialsFromLdap($login, $password, $connect = null, $bind = null) public function checkCredentialsFromLdap($login, $password, $connect = null, $bind = null)
{ {
$connect = $connect ?? function($host) { $connect = $connect ?? function ($host) {
$resource = ldap_connect($host); $resource = ldap_connect($host);
ldap_set_option($resource, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($resource, LDAP_OPT_PROTOCOL_VERSION, 3);
return $resource; return $resource;
}; };
$bind = $bind ?? function($handle, $dn, $password) { $bind = $bind ?? function ($handle, $dn, $password) {
return ldap_bind($handle, $dn, $password); return ldap_bind($handle, $dn, $password);
}; };

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Security; namespace Shaarli\Security;
use Shaarli\Config\ConfigManager; use Shaarli\Config\ConfigManager;
@ -79,7 +80,7 @@ public function setStaySignedIn($staySignedIn)
*/ */
public function generateToken() public function generateToken()
{ {
$token = sha1(uniqid('', true) .'_'. mt_rand() . $this->conf->get('credentials.salt')); $token = sha1(uniqid('', true) . '_' . mt_rand() . $this->conf->get('credentials.salt'));
$this->session['tokens'][$token] = 1; $this->session['tokens'][$token] = 1;
return $token; return $token;
} }

View file

@ -88,7 +88,8 @@ public function update(string $basePath = null)
foreach ($this->methods as $method) { foreach ($this->methods as $method) {
// Not an update method or already done, pass. // Not an update method or already done, pass.
if (! startsWith($method->getName(), 'updateMethod') if (
! startsWith($method->getName(), 'updateMethod')
|| in_array($method->getName(), $this->doneUpdates) || in_array($method->getName(), $this->doneUpdates)
) { ) {
continue; continue;
@ -121,12 +122,12 @@ public function getDoneUpdates()
public function readUpdates(string $updatesFilepath): array public function readUpdates(string $updatesFilepath): array
{ {
return UpdaterUtils::read_updates_file($updatesFilepath); return UpdaterUtils::readUpdatesFile($updatesFilepath);
} }
public function writeUpdates(string $updatesFilepath, array $updates): void public function writeUpdates(string $updatesFilepath, array $updates): void
{ {
UpdaterUtils::write_updates_file($updatesFilepath, $updates); UpdaterUtils::writeUpdatesFile($updatesFilepath, $updates);
} }
/** /**
@ -152,7 +153,8 @@ public function updateMethodMigrateExistingNotesUrl(): bool
$updated = false; $updated = false;
foreach ($this->bookmarkService->search() as $bookmark) { foreach ($this->bookmarkService->search() as $bookmark) {
if ($bookmark->isNote() if (
$bookmark->isNote()
&& startsWith($bookmark->getUrl(), '?') && startsWith($bookmark->getUrl(), '?')
&& 1 === preg_match('/^\?([a-zA-Z0-9-_@]{6})($|&|#)/', $bookmark->getUrl(), $match) && 1 === preg_match('/^\?([a-zA-Z0-9-_@]{6})($|&|#)/', $bookmark->getUrl(), $match)
) { ) {

View file

@ -11,7 +11,7 @@ class UpdaterUtils
* *
* @return array Already done update methods. * @return array Already done update methods.
*/ */
public static function read_updates_file($updatesFilepath) public static function readUpdatesFile($updatesFilepath)
{ {
if (! empty($updatesFilepath) && is_file($updatesFilepath)) { if (! empty($updatesFilepath) && is_file($updatesFilepath)) {
$content = file_get_contents($updatesFilepath); $content = file_get_contents($updatesFilepath);
@ -19,7 +19,7 @@ public static function read_updates_file($updatesFilepath)
return explode(';', $content); return explode(';', $content);
} }
} }
return array(); return [];
} }
/** /**
@ -30,7 +30,7 @@ public static function read_updates_file($updatesFilepath)
* *
* @throws \Exception Couldn't write version number. * @throws \Exception Couldn't write version number.
*/ */
public static function write_updates_file($updatesFilepath, $updates) public static function writeUpdatesFile($updatesFilepath, $updates)
{ {
if (empty($updatesFilepath)) { if (empty($updatesFilepath)) {
throw new \Exception('Updates file path is not set, can\'t write updates.'); throw new \Exception('Updates file path is not set, can\'t write updates.');
@ -38,7 +38,7 @@ public static function write_updates_file($updatesFilepath, $updates)
$res = file_put_contents($updatesFilepath, implode(';', $updates)); $res = file_put_contents($updatesFilepath, implode(';', $updates));
if ($res === false) { if ($res === false) {
throw new \Exception('Unable to write updates in '. $updatesFilepath . '.'); throw new \Exception('Unable to write updates in ' . $updatesFilepath . '.');
} }
} }
} }

View file

@ -163,11 +163,13 @@ See [`.travis.yml`](https://github.com/shaarli/Shaarli/blob/master/.travis.yml).
## Static analysis ## Static analysis
Patches should try to stick to the [PHP Standard Recommendations](http://www.php-fig.org/psr/) (PSR), especially: Patches should try to stick to the [PHP Standard Recommendations](http://www.php-fig.org/psr/) (PSR), and must follow:
- [PSR-1](http://www.php-fig.org/psr/psr-1/) - Basic Coding Standard - [PSR-1](http://www.php-fig.org/psr/psr-1/) - Basic Coding Standard
- [PSR-2](http://www.php-fig.org/psr/psr-2/) - Coding Style Guide - [PSR-2](http://www.php-fig.org/psr/psr-2/) - Coding Style Guide
- [PSR-12](http://www.php-fig.org/psr/psr-12/) - Extended Coding Style Guide
These are enforced on pull requests using our Continuous Integration tools.
**Work in progress:** Static analysis is currently being discussed here: in [#95 - Fix coding style (static analysis)](https://github.com/shaarli/Shaarli/issues/95), [#130 - Continuous Integration tools & features](https://github.com/shaarli/Shaarli/issues/130) **Work in progress:** Static analysis is currently being discussed here: in [#95 - Fix coding style (static analysis)](https://github.com/shaarli/Shaarli/issues/95), [#130 - Continuous Integration tools & features](https://github.com/shaarli/Shaarli/issues/130)

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Shaarli - The personal, minimalist, super-fast, database free, bookmarking service. * Shaarli - The personal, minimalist, super-fast, database free, bookmarking service.
* *
@ -77,9 +78,9 @@
new Languages(setlocale(LC_MESSAGES, 0), $conf); new Languages(setlocale(LC_MESSAGES, 0), $conf);
$conf->setEmpty('general.timezone', date_default_timezone_get()); $conf->setEmpty('general.timezone', date_default_timezone_get());
$conf->setEmpty('general.title', t('Shared bookmarks on '). escape(index_url($_SERVER))); $conf->setEmpty('general.title', t('Shared bookmarks on ') . escape(index_url($_SERVER)));
RainTPL::$tpl_dir = $conf->get('resource.raintpl_tpl').'/'.$conf->get('resource.theme').'/'; // template directory RainTPL::$tpl_dir = $conf->get('resource.raintpl_tpl') . '/' . $conf->get('resource.theme') . '/'; // template directory
RainTPL::$cache_dir = $conf->get('resource.raintpl_tmp'); // cache directory RainTPL::$cache_dir = $conf->get('resource.raintpl_tmp'); // cache directory
date_default_timezone_set($conf->get('general.timezone', 'UTC')); date_default_timezone_set($conf->get('general.timezone', 'UTC'));

View file

@ -5,13 +5,18 @@
<file>index.php</file> <file>index.php</file>
<file>application</file> <file>application</file>
<file>plugins</file> <file>plugins</file>
<file>tests</file> <!-- <file>tests</file>-->
<exclude-pattern>*/*.css</exclude-pattern> <exclude-pattern>*/*.css</exclude-pattern>
<exclude-pattern>*/*.js</exclude-pattern> <exclude-pattern>*/*.js</exclude-pattern>
<arg name="colors"/> <arg name="colors"/>
<rule ref="PSR1"/> <rule ref="PSR12"/>
<rule ref="PSR2"/> <rule ref="Generic.Arrays.DisallowLongArraySyntax"/>
<rule ref="PSR1.Files.SideEffects.FoundWithSymbols">
<!-- index.php bootstraps everything, so yes mixed symbols with side effects -->
<exclude-pattern>index.php</exclude-pattern>
</rule>
</ruleset> </ruleset>

View file

@ -17,26 +17,26 @@
function hook_addlink_toolbar_render_header($data) function hook_addlink_toolbar_render_header($data)
{ {
if ($data['_PAGE_'] == TemplatePage::LINKLIST && $data['_LOGGEDIN_'] === true) { if ($data['_PAGE_'] == TemplatePage::LINKLIST && $data['_LOGGEDIN_'] === true) {
$form = array( $form = [
'attr' => array( 'attr' => [
'method' => 'GET', 'method' => 'GET',
'action' => $data['_BASE_PATH_'] . '/admin/shaare', 'action' => $data['_BASE_PATH_'] . '/admin/shaare',
'name' => 'addform', 'name' => 'addform',
'class' => 'addform', 'class' => 'addform',
), ],
'inputs' => array( 'inputs' => [
array( [
'type' => 'text', 'type' => 'text',
'name' => 'post', 'name' => 'post',
'placeholder' => t('URI'), 'placeholder' => t('URI'),
), ],
array( [
'type' => 'submit', 'type' => 'submit',
'value' => t('Add link'), 'value' => t('Add link'),
'class' => 'bigbutton', 'class' => 'bigbutton',
), ],
), ],
); ];
$data['fields_toolbar'][] = $form; $data['fields_toolbar'][] = $form;
} }

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Plugin Archive.org. * Plugin Archive.org.
* *

View file

@ -28,14 +28,14 @@ function default_colors_init($conf)
{ {
$params = []; $params = [];
foreach (DEFAULT_COLORS_PLACEHOLDERS as $placeholder) { foreach (DEFAULT_COLORS_PLACEHOLDERS as $placeholder) {
$value = trim($conf->get('plugins.'. $placeholder, '')); $value = trim($conf->get('plugins.' . $placeholder, ''));
if (strlen($value) > 0) { if (strlen($value) > 0) {
$params[$placeholder] = $value; $params[$placeholder] = $value;
} }
} }
if (empty($params)) { if (empty($params)) {
$error = t('Default colors plugin error: '. $error = t('Default colors plugin error: ' .
'This plugin is active and no custom color is configured.'); 'This plugin is active and no custom color is configured.');
return [$error]; return [$error];
} }
@ -56,7 +56,7 @@ function default_colors_init($conf)
function hook_default_colors_render_includes($data) function hook_default_colors_render_includes($data)
{ {
$file = PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css'; $file = PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css';
if (file_exists($file )) { if (file_exists($file)) {
$data['css_files'][] = $file ; $data['css_files'][] = $file ;
} }
@ -75,7 +75,7 @@ function default_colors_generate_css_file($params): void
$content = ''; $content = '';
foreach (DEFAULT_COLORS_PLACEHOLDERS as $rule) { foreach (DEFAULT_COLORS_PLACEHOLDERS as $rule) {
$content .= !empty($params[$rule]) $content .= !empty($params[$rule])
? default_colors_format_css_rule($params, $rule) .';'. PHP_EOL ? default_colors_format_css_rule($params, $rule) . ';' . PHP_EOL
: ''; : '';
} }
@ -99,8 +99,8 @@ function default_colors_format_css_rule($data, $parameter)
} }
$key = str_replace('DEFAULT_COLORS_', '', $parameter); $key = str_replace('DEFAULT_COLORS_', '', $parameter);
$key = str_replace('_', '-', strtolower($key)) .'-color'; $key = str_replace('_', '-', strtolower($key)) . '-color';
return ' --'. $key .': '. $data[$parameter]; return ' --' . $key . ': ' . $data[$parameter];
} }

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Demo Plugin. * Demo Plugin.
* *
@ -82,14 +83,14 @@ function hook_demo_plugin_render_header($data)
* A link is an array of its attributes (key="value"), * A link is an array of its attributes (key="value"),
* and a mandatory `html` key, which contains its value. * and a mandatory `html` key, which contains its value.
*/ */
$button = array( $button = [
'attr' => array ( 'attr' => [
'href' => '#', 'href' => '#',
'class' => 'mybutton', 'class' => 'mybutton',
'title' => 'hover me', 'title' => 'hover me',
), ],
'html' => 'DEMO buttons toolbar', 'html' => 'DEMO buttons toolbar',
); ];
$data['buttons_toolbar'][] = $button; $data['buttons_toolbar'][] = $button;
} }
@ -115,29 +116,29 @@ function hook_demo_plugin_render_header($data)
* <input input-2-attribute-1="input 2 attribute 1 value"> * <input input-2-attribute-1="input 2 attribute 1 value">
* </form> * </form>
*/ */
$form = array( $form = [
'attr' => array( 'attr' => [
'method' => 'GET', 'method' => 'GET',
'action' => $data['_BASE_PATH_'] . '/', 'action' => $data['_BASE_PATH_'] . '/',
'class' => 'addform', 'class' => 'addform',
), ],
'inputs' => array( 'inputs' => [
array( [
'type' => 'text', 'type' => 'text',
'name' => 'demo', 'name' => 'demo',
'placeholder' => 'demo', 'placeholder' => 'demo',
) ]
) ]
); ];
$data['fields_toolbar'][] = $form; $data['fields_toolbar'][] = $form;
} }
// Another button always displayed // Another button always displayed
$button = array( $button = [
'attr' => array( 'attr' => [
'href' => '#', 'href' => '#',
), ],
'html' => 'Demo', 'html' => 'Demo',
); ];
$data['buttons_toolbar'][] = $button; $data['buttons_toolbar'][] = $button;
return $data; return $data;
@ -187,7 +188,7 @@ function hook_demo_plugin_render_includes($data)
function hook_demo_plugin_render_footer($data) function hook_demo_plugin_render_footer($data)
{ {
// Footer text // Footer text
$data['text'][] = '<br>'. demo_plugin_t('Shaarli is now enhanced by the awesome demo_plugin.'); $data['text'][] = '<br>' . demo_plugin_t('Shaarli is now enhanced by the awesome demo_plugin.');
// Free elements at the end of the page. // Free elements at the end of the page.
$data['endofpage'][] = '<marquee id="demo_marquee">' . $data['endofpage'][] = '<marquee id="demo_marquee">' .
@ -229,13 +230,13 @@ function hook_demo_plugin_render_linklist($data)
* and a mandatory `html` key, which contains its value. * and a mandatory `html` key, which contains its value.
* It's also recommended to add key 'on' or 'off' for theme rendering. * It's also recommended to add key 'on' or 'off' for theme rendering.
*/ */
$action = array( $action = [
'attr' => array( 'attr' => [
'href' => '?up', 'href' => '?up',
'title' => 'Uppercase!', 'title' => 'Uppercase!',
), ],
'html' => '←', 'html' => '←',
); ];
if (isset($_GET['up'])) { if (isset($_GET['up'])) {
// Manipulate link data // Manipulate link data
@ -275,7 +276,7 @@ function hook_demo_plugin_render_linklist($data)
function hook_demo_plugin_render_editlink($data) function hook_demo_plugin_render_editlink($data)
{ {
// Load HTML into a string // Load HTML into a string
$html = file_get_contents(PluginManager::$PLUGINS_PATH .'/demo_plugin/field.html'); $html = file_get_contents(PluginManager::$PLUGINS_PATH . '/demo_plugin/field.html');
// Replace value in HTML if it exists in $data // Replace value in HTML if it exists in $data
if (!empty($data['link']['stuff'])) { if (!empty($data['link']['stuff'])) {

View file

@ -19,9 +19,9 @@ function isso_init($conf)
{ {
$issoUrl = $conf->get('plugins.ISSO_SERVER'); $issoUrl = $conf->get('plugins.ISSO_SERVER');
if (empty($issoUrl)) { if (empty($issoUrl)) {
$error = t('Isso plugin error: '. $error = t('Isso plugin error: ' .
'Please define the "ISSO_SERVER" setting in the plugin administration page.'); 'Please define the "ISSO_SERVER" setting in the plugin administration page.');
return array($error); return [$error];
} }
} }
@ -49,12 +49,12 @@ function hook_isso_render_linklist($data, $conf)
$isso = sprintf($issoHtml, $issoUrl, $issoUrl, $link['id'], $link['id']); $isso = sprintf($issoHtml, $issoUrl, $issoUrl, $link['id'], $link['id']);
$data['plugin_end_zone'][] = $isso; $data['plugin_end_zone'][] = $isso;
} else { } else {
$button = '<span><a href="'. ($data['_BASE_PATH_'] ?? '') . '/shaare/%s#isso-thread">'; $button = '<span><a href="' . ($data['_BASE_PATH_'] ?? '') . '/shaare/%s#isso-thread">';
// For the default theme we use a FontAwesome icon which is better than an image // For the default theme we use a FontAwesome icon which is better than an image
if ($conf->get('resource.theme') === 'default') { if ($conf->get('resource.theme') === 'default') {
$button .= '<i class="linklist-plugin-icon fa fa-comment"></i>'; $button .= '<i class="linklist-plugin-icon fa fa-comment"></i>';
} else { } else {
$button .= '<img class="linklist-plugin-icon" src="'. $data['_ROOT_PATH_'].'/plugins/isso/comment.png" '; $button .= '<img class="linklist-plugin-icon" src="' . $data['_ROOT_PATH_'] . '/plugins/isso/comment.png" ';
$button .= 'title="Comment on this shaare" alt="Comments" />'; $button .= 'title="Comment on this shaare" alt="Comments" />';
} }
$button .= '</a></span>'; $button .= '</a></span>';

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Piwik plugin. * Piwik plugin.
* Adds tracking code on each page. * Adds tracking code on each page.
@ -22,7 +23,7 @@ function piwik_init($conf)
if (empty($piwikUrl) || empty($piwikSiteid)) { if (empty($piwikUrl) || empty($piwikSiteid)) {
$error = t('Piwik plugin error: ' . $error = t('Piwik plugin error: ' .
'Please define PIWIK_URL and PIWIK_SITEID in the plugin administration page.'); 'Please define PIWIK_URL and PIWIK_SITEID in the plugin administration page.');
return array($error); return [$error];
} }
} }

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Plugin PlayVideos * Plugin PlayVideos
* *
@ -19,14 +20,14 @@
function hook_playvideos_render_header($data) function hook_playvideos_render_header($data)
{ {
if ($data['_PAGE_'] == TemplatePage::LINKLIST) { if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
$playvideo = array( $playvideo = [
'attr' => array( 'attr' => [
'href' => '#', 'href' => '#',
'title' => t('Video player'), 'title' => t('Video player'),
'id' => 'playvideos', 'id' => 'playvideos',
), ],
'html' => '► '. t('Play Videos') 'html' => '► ' . t('Play Videos')
); ];
$data['buttons_toolbar'][] = $playvideo; $data['buttons_toolbar'][] = $playvideo;
} }

View file

@ -42,7 +42,7 @@ function pubsubhubbub_init($conf)
function hook_pubsubhubbub_render_feed($data, $conf) function hook_pubsubhubbub_render_feed($data, $conf)
{ {
$feedType = $data['_PAGE_'] == TemplatePage::FEED_RSS ? FeedBuilder::$FEED_RSS : FeedBuilder::$FEED_ATOM; $feedType = $data['_PAGE_'] == TemplatePage::FEED_RSS ? FeedBuilder::$FEED_RSS : FeedBuilder::$FEED_ATOM;
$template = file_get_contents(PluginManager::$PLUGINS_PATH . '/pubsubhubbub/hub.'. $feedType .'.xml'); $template = file_get_contents(PluginManager::$PLUGINS_PATH . '/pubsubhubbub/hub.' . $feedType . '.xml');
$data['feed_plugins_header'][] = sprintf($template, $conf->get('plugins.PUBSUBHUB_URL')); $data['feed_plugins_header'][] = sprintf($template, $conf->get('plugins.PUBSUBHUB_URL'));
return $data; return $data;
@ -59,10 +59,10 @@ function hook_pubsubhubbub_render_feed($data, $conf)
*/ */
function hook_pubsubhubbub_save_link($data, $conf) function hook_pubsubhubbub_save_link($data, $conf)
{ {
$feeds = array( $feeds = [
index_url($_SERVER) .'feed/atom', index_url($_SERVER) . 'feed/atom',
index_url($_SERVER) .'feed/rss', index_url($_SERVER) . 'feed/rss',
); ];
$httpPost = function_exists('curl_version') ? false : 'nocurl_http_post'; $httpPost = function_exists('curl_version') ? false : 'nocurl_http_post';
try { try {
@ -87,11 +87,11 @@ function hook_pubsubhubbub_save_link($data, $conf)
*/ */
function nocurl_http_post($url, $postString) function nocurl_http_post($url, $postString)
{ {
$params = array('http' => array( $params = ['http' => [
'method' => 'POST', 'method' => 'POST',
'content' => $postString, 'content' => $postString,
'user_agent' => 'PubSubHubbub-Publisher-PHP/1.0', 'user_agent' => 'PubSubHubbub-Publisher-PHP/1.0',
)); ]];
$context = stream_context_create($params); $context = stream_context_create($params);
$fp = @fopen($url, 'rb', false, $context); $fp = @fopen($url, 'rb', false, $context);

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Plugin qrcode * Plugin qrcode
* Add QRCode containing URL for each links. * Add QRCode containing URL for each links.

View file

@ -1,4 +1,5 @@
<?php <?php
namespace Shaarli\Plugin\Wallabag; namespace Shaarli\Plugin\Wallabag;
/** /**
@ -11,20 +12,20 @@ class WallabagInstance
* - key: version ID, must match plugin settings. * - key: version ID, must match plugin settings.
* - value: version name. * - value: version name.
*/ */
private static $wallabagVersions = array( private static $wallabagVersions = [
1 => '1.x', 1 => '1.x',
2 => '2.x', 2 => '2.x',
); ];
/** /**
* @var array Static reference to WB endpoint according to the API version. * @var array Static reference to WB endpoint according to the API version.
* - key: version name. * - key: version name.
* - value: endpoint. * - value: endpoint.
*/ */
private static $wallabagEndpoints = array( private static $wallabagEndpoints = [
'1.x' => '?plainurl=', '1.x' => '?plainurl=',
'2.x' => 'bookmarklet?url=', '2.x' => 'bookmarklet?url=',
); ];
/** /**
* @var string Wallabag user instance URL. * @var string Wallabag user instance URL.

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Wallabag plugin * Wallabag plugin
*/ */
@ -18,9 +19,9 @@ function wallabag_init($conf)
{ {
$wallabagUrl = $conf->get('plugins.WALLABAG_URL'); $wallabagUrl = $conf->get('plugins.WALLABAG_URL');
if (empty($wallabagUrl)) { if (empty($wallabagUrl)) {
$error = t('Wallabag plugin error: '. $error = t('Wallabag plugin error: ' .
'Please define the "WALLABAG_URL" setting in the plugin administration page.'); 'Please define the "WALLABAG_URL" setting in the plugin administration page.');
return array($error); return [$error];
} }
$conf->setEmpty('plugins.WALLABAG_URL', '2'); $conf->setEmpty('plugins.WALLABAG_URL', '2');
} }

View file

@ -51,10 +51,10 @@ protected function setUp(): void
*/ */
public function testReadEmptyUpdatesFile() public function testReadEmptyUpdatesFile()
{ {
$this->assertEquals(array(), UpdaterUtils::read_updates_file('')); $this->assertEquals(array(), UpdaterUtils::readUpdatesFile(''));
$updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt'; $updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt';
touch($updatesFile); touch($updatesFile);
$this->assertEquals(array(), UpdaterUtils::read_updates_file($updatesFile)); $this->assertEquals(array(), UpdaterUtils::readUpdatesFile($updatesFile));
unlink($updatesFile); unlink($updatesFile);
} }
@ -66,14 +66,14 @@ public function testReadWriteUpdatesFile()
$updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt'; $updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt';
$updatesMethods = array('m1', 'm2', 'm3'); $updatesMethods = array('m1', 'm2', 'm3');
UpdaterUtils::write_updates_file($updatesFile, $updatesMethods); UpdaterUtils::writeUpdatesFile($updatesFile, $updatesMethods);
$readMethods = UpdaterUtils::read_updates_file($updatesFile); $readMethods = UpdaterUtils::readUpdatesFile($updatesFile);
$this->assertEquals($readMethods, $updatesMethods); $this->assertEquals($readMethods, $updatesMethods);
// Update // Update
$updatesMethods[] = 'm4'; $updatesMethods[] = 'm4';
UpdaterUtils::write_updates_file($updatesFile, $updatesMethods); UpdaterUtils::writeUpdatesFile($updatesFile, $updatesMethods);
$readMethods = UpdaterUtils::read_updates_file($updatesFile); $readMethods = UpdaterUtils::readUpdatesFile($updatesFile);
$this->assertEquals($readMethods, $updatesMethods); $this->assertEquals($readMethods, $updatesMethods);
unlink($updatesFile); unlink($updatesFile);
} }
@ -86,7 +86,7 @@ public function testWriteEmptyUpdatesFile()
$this->expectException(\Exception::class); $this->expectException(\Exception::class);
$this->expectExceptionMessageRegExp('/Updates file path is not set(.*)/'); $this->expectExceptionMessageRegExp('/Updates file path is not set(.*)/');
UpdaterUtils::write_updates_file('', array('test')); UpdaterUtils::writeUpdatesFile('', array('test'));
} }
/** /**
@ -101,7 +101,7 @@ public function testWriteUpdatesFileNotWritable()
touch($updatesFile); touch($updatesFile);
chmod($updatesFile, 0444); chmod($updatesFile, 0444);
try { try {
@UpdaterUtils::write_updates_file($updatesFile, array('test')); @UpdaterUtils::writeUpdatesFile($updatesFile, array('test'));
} catch (Exception $e) { } catch (Exception $e) {
unlink($updatesFile); unlink($updatesFile);
throw $e; throw $e;

View file

@ -60,10 +60,10 @@ protected function setUp(): void
*/ */
public function testReadEmptyUpdatesFile() public function testReadEmptyUpdatesFile()
{ {
$this->assertEquals(array(), UpdaterUtils::read_updates_file('')); $this->assertEquals(array(), UpdaterUtils::readUpdatesFile(''));
$updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt'; $updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt';
touch($updatesFile); touch($updatesFile);
$this->assertEquals(array(), UpdaterUtils::read_updates_file($updatesFile)); $this->assertEquals(array(), UpdaterUtils::readUpdatesFile($updatesFile));
unlink($updatesFile); unlink($updatesFile);
} }
@ -75,14 +75,14 @@ public function testReadWriteUpdatesFile()
$updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt'; $updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt';
$updatesMethods = array('m1', 'm2', 'm3'); $updatesMethods = array('m1', 'm2', 'm3');
UpdaterUtils::write_updates_file($updatesFile, $updatesMethods); UpdaterUtils::writeUpdatesFile($updatesFile, $updatesMethods);
$readMethods = UpdaterUtils::read_updates_file($updatesFile); $readMethods = UpdaterUtils::readUpdatesFile($updatesFile);
$this->assertEquals($readMethods, $updatesMethods); $this->assertEquals($readMethods, $updatesMethods);
// Update // Update
$updatesMethods[] = 'm4'; $updatesMethods[] = 'm4';
UpdaterUtils::write_updates_file($updatesFile, $updatesMethods); UpdaterUtils::writeUpdatesFile($updatesFile, $updatesMethods);
$readMethods = UpdaterUtils::read_updates_file($updatesFile); $readMethods = UpdaterUtils::readUpdatesFile($updatesFile);
$this->assertEquals($readMethods, $updatesMethods); $this->assertEquals($readMethods, $updatesMethods);
unlink($updatesFile); unlink($updatesFile);
} }
@ -95,7 +95,7 @@ public function testWriteEmptyUpdatesFile()
$this->expectException(\Exception::class); $this->expectException(\Exception::class);
$this->expectExceptionMessageRegExp('/Updates file path is not set(.*)/'); $this->expectExceptionMessageRegExp('/Updates file path is not set(.*)/');
UpdaterUtils::write_updates_file('', array('test')); UpdaterUtils::writeUpdatesFile('', array('test'));
} }
/** /**
@ -110,7 +110,7 @@ public function testWriteUpdatesFileNotWritable()
touch($updatesFile); touch($updatesFile);
chmod($updatesFile, 0444); chmod($updatesFile, 0444);
try { try {
@UpdaterUtils::write_updates_file($updatesFile, array('test')); @UpdaterUtils::writeUpdatesFile($updatesFile, array('test'));
} catch (Exception $e) { } catch (Exception $e) {
unlink($updatesFile); unlink($updatesFile);
throw $e; throw $e;