Merge pull request #1635 from ArthurHoaro/feature/phpcs
This commit is contained in:
commit
302662797c
95 changed files with 480 additions and 386 deletions
|
@ -49,6 +49,10 @@ cache:
|
|||
directories:
|
||||
- $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/update composer and php dependencies
|
||||
- composer config --unset platform && composer config platform.php $TRAVIS_PHP_VERSION
|
||||
|
@ -60,4 +64,5 @@ before_script:
|
|||
script:
|
||||
- make clean
|
||||
- make check_permissions
|
||||
- make code_sniffer
|
||||
- make all_tests
|
||||
|
|
4
Makefile
4
Makefile
|
@ -27,10 +27,6 @@ PHPCS := $(BIN)/phpcs
|
|||
code_sniffer:
|
||||
@$(PHPCS)
|
||||
|
||||
### - errors filtered by coding standard: PEAR, PSR1, PSR2, Zend...
|
||||
PHPCS_%:
|
||||
@$(PHPCS) --report-full --report-width=200 --standard=$*
|
||||
|
||||
### - errors by Git author
|
||||
code_sniffer_blame:
|
||||
@$(PHPCS) --report-gitblame
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli;
|
||||
|
||||
use DateTime;
|
||||
|
@ -31,27 +32,27 @@ class History
|
|||
/**
|
||||
* @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.
|
||||
*/
|
||||
const UPDATED = 'UPDATED';
|
||||
public const UPDATED = 'UPDATED';
|
||||
|
||||
/**
|
||||
* @var string Action key: a link has been deleted.
|
||||
*/
|
||||
const DELETED = 'DELETED';
|
||||
public const DELETED = 'DELETED';
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
const IMPORT = 'IMPORT';
|
||||
public const IMPORT = 'IMPORT';
|
||||
|
||||
/**
|
||||
* @var string History file path.
|
||||
|
|
|
@ -41,7 +41,7 @@ class Languages
|
|||
/**
|
||||
* Core translations domain
|
||||
*/
|
||||
const DEFAULT_DOMAIN = 'shaarli';
|
||||
public const DEFAULT_DOMAIN = 'shaarli';
|
||||
|
||||
/**
|
||||
* @var TranslatorInterface
|
||||
|
@ -76,7 +76,8 @@ public function __construct($language, $conf)
|
|||
$this->language = $confLanguage;
|
||||
}
|
||||
|
||||
if (! extension_loaded('gettext')
|
||||
if (
|
||||
! extension_loaded('gettext')
|
||||
|| in_array($this->conf->get('translation.mode', 'auto'), ['auto', 'php'])
|
||||
) {
|
||||
$this->initPhpTranslator();
|
||||
|
@ -98,7 +99,7 @@ protected function initGettextTranslator()
|
|||
$this->translator->loadDomain(self::DEFAULT_DOMAIN, 'inc/languages');
|
||||
|
||||
// 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)) {
|
||||
$this->translator->loadDomain($this->conf->get('theme'), $themeTransFolder, false);
|
||||
}
|
||||
|
@ -121,7 +122,9 @@ protected function initPhpTranslator()
|
|||
$translations = new Translations();
|
||||
// Core translations
|
||||
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');
|
||||
$this->translator->loadTranslations($translations);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
|
@ -129,11 +132,11 @@ protected function initPhpTranslator()
|
|||
|
||||
// Default extension translation from the current 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)) {
|
||||
try {
|
||||
$translations = Translations::fromPoFile(
|
||||
$themeTransFolder .'/'. $this->language .'/LC_MESSAGES/'. $theme .'.po'
|
||||
$themeTransFolder . '/' . $this->language . '/LC_MESSAGES/' . $theme . '.po'
|
||||
);
|
||||
$translations->setDomain($theme);
|
||||
$this->translator->loadTranslations($translations);
|
||||
|
@ -149,7 +152,7 @@ protected function initPhpTranslator()
|
|||
|
||||
try {
|
||||
$extension = Translations::fromPoFile(
|
||||
$translationPath . $this->language .'/LC_MESSAGES/'. $domain .'.po'
|
||||
$translationPath . $this->language . '/LC_MESSAGES/' . $domain . '.po'
|
||||
);
|
||||
$extension->setDomain($domain);
|
||||
$this->translator->loadTranslations($extension);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
*/
|
||||
class Thumbnailer
|
||||
{
|
||||
const COMMON_MEDIA_DOMAINS = [
|
||||
protected const COMMON_MEDIA_DOMAINS = [
|
||||
'imgur.com',
|
||||
'flickr.com',
|
||||
'youtube.com',
|
||||
|
@ -31,9 +31,9 @@ class Thumbnailer
|
|||
'deviantart.com',
|
||||
];
|
||||
|
||||
const MODE_ALL = 'all';
|
||||
const MODE_COMMON = 'common';
|
||||
const MODE_NONE = 'none';
|
||||
public const MODE_ALL = 'all';
|
||||
public const MODE_COMMON = 'common';
|
||||
public const MODE_NONE = 'none';
|
||||
|
||||
/**
|
||||
* @var WebThumbnailer instance.
|
||||
|
@ -60,7 +60,7 @@ public function __construct($conf)
|
|||
// TODO: create a proper error handling system able to catch exceptions...
|
||||
die(t(
|
||||
'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)
|
||||
{
|
||||
if ($this->conf->get('thumbnails.mode') === self::MODE_COMMON
|
||||
if (
|
||||
$this->conf->get('thumbnails.mode') === self::MODE_COMMON
|
||||
&& ! $this->isCommonMediaOrImage($url)
|
||||
) {
|
||||
return false;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Generates a list of available timezone continents and cities.
|
||||
*
|
||||
|
@ -43,7 +44,7 @@ function generateTimeZoneData($installedTimeZones, $preselectedTimezone = '')
|
|||
// Try to split the provided timezone
|
||||
$spos = strpos($preselectedTimezone, '/');
|
||||
$pcontinent = substr($preselectedTimezone, 0, $spos);
|
||||
$pcity = substr($preselectedTimezone, $spos+1);
|
||||
$pcity = substr($preselectedTimezone, $spos + 1);
|
||||
}
|
||||
|
||||
$continents = [];
|
||||
|
@ -60,7 +61,7 @@ function generateTimeZoneData($installedTimeZones, $preselectedTimezone = '')
|
|||
}
|
||||
|
||||
$continent = substr($tz, 0, $spos);
|
||||
$city = substr($tz, $spos+1);
|
||||
$city = substr($tz, $spos + 1);
|
||||
$cities[] = ['continent' => $continent, 'city' => $city];
|
||||
$continents[$continent] = true;
|
||||
}
|
||||
|
@ -85,7 +86,7 @@ function generateTimeZoneData($installedTimeZones, $preselectedTimezone = '')
|
|||
function isTimeZoneValid($continent, $city)
|
||||
{
|
||||
return in_array(
|
||||
$continent.'/'.$city,
|
||||
$continent . '/' . $city,
|
||||
timezone_identifiers_list()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Shaarli utilities
|
||||
*/
|
||||
|
@ -102,7 +103,7 @@ function escape($input)
|
|||
}
|
||||
|
||||
if (is_array($input)) {
|
||||
$out = array();
|
||||
$out = [];
|
||||
foreach ($input as $key => $value) {
|
||||
$out[escape($key)] = escape($value);
|
||||
}
|
||||
|
@ -163,7 +164,7 @@ function checkDateFormat($format, $string)
|
|||
*
|
||||
* @return string $referer - final referer.
|
||||
*/
|
||||
function generateLocation($referer, $host, $loopTerms = array())
|
||||
function generateLocation($referer, $host, $loopTerms = [])
|
||||
{
|
||||
$finalReferer = './?';
|
||||
|
||||
|
@ -196,7 +197,7 @@ function generateLocation($referer, $host, $loopTerms = array())
|
|||
function autoLocale($headerLocale)
|
||||
{
|
||||
// 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 (preg_match_all('/([a-z]{2,3})[-_]?([a-z]{2})?,?/i', $headerLocale, $matches, PREG_SET_ORDER)) {
|
||||
$attempts = [];
|
||||
|
@ -376,13 +377,15 @@ function return_bytes($val)
|
|||
return $val;
|
||||
}
|
||||
$val = trim($val);
|
||||
$last = strtolower($val[strlen($val)-1]);
|
||||
$last = strtolower($val[strlen($val) - 1]);
|
||||
$val = intval(substr($val, 0, -1));
|
||||
switch ($last) {
|
||||
case 'g':
|
||||
$val *= 1024;
|
||||
// do no break in order 1024^2 for each unit
|
||||
case 'm':
|
||||
$val *= 1024;
|
||||
// do no break in order 1024^2 for each unit
|
||||
case 'k':
|
||||
$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)
|
||||
{
|
||||
$postFunction = $fixCase ? 'ucfirst' : function ($input) { return $input; };
|
||||
$postFunction = $fixCase ? 'ucfirst' : function ($input) {
|
||||
return $input;
|
||||
};
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Api;
|
||||
|
||||
use malkusch\lock\mutex\FlockMutex;
|
||||
|
@ -108,7 +109,8 @@ protected function checkRequest($request)
|
|||
*/
|
||||
protected function checkToken($request)
|
||||
{
|
||||
if (!$request->hasHeader('Authorization')
|
||||
if (
|
||||
!$request->hasHeader('Authorization')
|
||||
&& !isset($this->container->environment['REDIRECT_HTTP_AUTHORIZATION'])
|
||||
) {
|
||||
throw new ApiAuthorizationException('JWT token not provided');
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Api;
|
||||
|
||||
use Shaarli\Api\Exceptions\ApiAuthorizationException;
|
||||
|
@ -27,7 +28,7 @@ public static function validateJwtToken($token, $secret)
|
|||
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) {
|
||||
throw new ApiAuthorizationException('Invalid JWT signature');
|
||||
}
|
||||
|
@ -42,7 +43,8 @@ public static function validateJwtToken($token, $secret)
|
|||
throw new ApiAuthorizationException('Invalid JWT payload');
|
||||
}
|
||||
|
||||
if (empty($payload->iat)
|
||||
if (
|
||||
empty($payload->iat)
|
||||
|| $payload->iat > time()
|
||||
|| time() - $payload->iat > ApiMiddleware::$TOKEN_DURATION
|
||||
) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Shaarli\Api\Controllers;
|
||||
|
||||
use Shaarli\Api\Exceptions\ApiBadParametersException;
|
||||
|
|
|
@ -29,13 +29,13 @@ public function getInfo($request, $response)
|
|||
$info = [
|
||||
'global_counter' => $this->bookmarkService->count(),
|
||||
'private_counter' => $this->bookmarkService->count(BookmarkFilter::$PRIVATE),
|
||||
'settings' => array(
|
||||
'settings' => [
|
||||
'title' => $this->conf->get('general.title', 'Shaarli'),
|
||||
'header_link' => $this->conf->get('general.header_link', '?'),
|
||||
'timezone' => $this->conf->get('general.timezone', 'UTC'),
|
||||
'enabled_plugins' => $this->conf->get('general.enabled_plugins', []),
|
||||
'default_private_links' => $this->conf->get('privacy.default_private_links', false),
|
||||
),
|
||||
],
|
||||
];
|
||||
|
||||
return $response->withJson($info, 200, $this->jsonStyle);
|
||||
|
|
|
@ -119,7 +119,8 @@ public function postLink($request, $response)
|
|||
$data = (array) ($request->getParsedBody() ?? []);
|
||||
$bookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links'));
|
||||
// duplicate by URL, return 409 Conflict
|
||||
if (! empty($bookmark->getUrl())
|
||||
if (
|
||||
! empty($bookmark->getUrl())
|
||||
&& ! empty($dup = $this->bookmarkService->findByUrl($bookmark->getUrl()))
|
||||
) {
|
||||
return $response->withJson(
|
||||
|
@ -159,7 +160,8 @@ public function putLink($request, $response, $args)
|
|||
|
||||
$requestBookmark = ApiUtils::buildBookmarkFromRequest($data, $this->conf->get('privacy.default_private_links'));
|
||||
// duplicate URL on a different link, return 409 Conflict
|
||||
if (! empty($requestBookmark->getUrl())
|
||||
if (
|
||||
! empty($requestBookmark->getUrl())
|
||||
&& ! empty($dup = $this->bookmarkService->findByUrl($requestBookmark->getUrl()))
|
||||
&& $dup->getId() != $id
|
||||
) {
|
||||
|
|
|
@ -28,7 +28,7 @@ public function getApiResponse()
|
|||
*/
|
||||
public function setMessage($message)
|
||||
{
|
||||
$original = $this->debug === true ? ': '. $this->getMessage() : '';
|
||||
$original = $this->debug === true ? ': ' . $this->getMessage() : '';
|
||||
$this->message = $message . $original;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ protected function getApiResponseBody()
|
|||
}
|
||||
return [
|
||||
'message' => $this->getMessage(),
|
||||
'stacktrace' => get_class($this) .': '. $this->getTraceAsString()
|
||||
'stacktrace' => get_class($this) . ': ' . $this->getTraceAsString()
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
class Bookmark
|
||||
{
|
||||
/** @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 */
|
||||
protected $id;
|
||||
|
@ -106,7 +106,8 @@ public function fromArray(array $data, string $tagsSeparator = ' '): Bookmark
|
|||
*/
|
||||
public function validate(): void
|
||||
{
|
||||
if ($this->id === null
|
||||
if (
|
||||
$this->id === null
|
||||
|| ! is_int($this->id)
|
||||
|| empty($this->shortUrl)
|
||||
|| empty($this->created)
|
||||
|
@ -114,7 +115,7 @@ public function validate(): void
|
|||
throw new InvalidBookmarkException($this);
|
||||
}
|
||||
if (empty($this->url)) {
|
||||
$this->url = '/shaare/'. $this->shortUrl;
|
||||
$this->url = '/shaare/' . $this->shortUrl;
|
||||
}
|
||||
if (empty($this->title)) {
|
||||
$this->title = $this->url;
|
||||
|
|
|
@ -72,7 +72,8 @@ public function count()
|
|||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
if (! $value instanceof Bookmark
|
||||
if (
|
||||
! $value instanceof Bookmark
|
||||
|| $value->getId() === null || empty($value->getUrl())
|
||||
|| ($offset !== null && ! is_int($offset)) || ! is_int($value->getId())
|
||||
|| $offset !== null && $offset !== $value->getId()
|
||||
|
@ -222,7 +223,8 @@ public function getNextId(): int
|
|||
*/
|
||||
public function getByUrl(string $url): ?Bookmark
|
||||
{
|
||||
if (! empty($url)
|
||||
if (
|
||||
! empty($url)
|
||||
&& isset($this->urls[$url])
|
||||
&& isset($this->bookmarks[$this->urls[$url]])
|
||||
) {
|
||||
|
|
|
@ -69,7 +69,7 @@ public function __construct(ConfigManager $conf, History $history, Mutex $mutex,
|
|||
} else {
|
||||
try {
|
||||
$this->bookmarks = $this->bookmarksIO->read();
|
||||
} catch (EmptyDataStoreException|DatastoreNotInitializedException $e) {
|
||||
} catch (EmptyDataStoreException | DatastoreNotInitializedException $e) {
|
||||
$this->bookmarks = new BookmarkArray();
|
||||
|
||||
if ($this->isLoggedIn) {
|
||||
|
@ -85,7 +85,7 @@ public function __construct(ConfigManager $conf, History $history, Mutex $mutex,
|
|||
if (! $this->bookmarks instanceof BookmarkArray) {
|
||||
$this->migrate();
|
||||
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.'
|
||||
);
|
||||
}
|
||||
|
@ -102,7 +102,8 @@ public function findByHash(string $hash, string $privateKey = null): Bookmark
|
|||
$bookmark = $this->bookmarkFilter->filter(BookmarkFilter::$FILTER_HASH, $hash);
|
||||
// PHP 7.3 introduced array_key_first() to avoid this hack
|
||||
$first = reset($bookmark);
|
||||
if (!$this->isLoggedIn
|
||||
if (
|
||||
!$this->isLoggedIn
|
||||
&& $first->isPrivate()
|
||||
&& (empty($privateKey) || $privateKey !== $first->getAdditionalContentEntry('private_key'))
|
||||
) {
|
||||
|
@ -165,7 +166,8 @@ public function get(int $id, string $visibility = null): Bookmark
|
|||
}
|
||||
|
||||
$bookmark = $this->bookmarks[$id];
|
||||
if (($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private')
|
||||
if (
|
||||
($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private')
|
||||
|| (! $bookmark->isPrivate() && $visibility != 'all' && $visibility != 'public')
|
||||
) {
|
||||
throw new Exception('Unauthorized');
|
||||
|
@ -265,7 +267,8 @@ public function exists(int $id, string $visibility = null): bool
|
|||
}
|
||||
|
||||
$bookmark = $this->bookmarks[$id];
|
||||
if (($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private')
|
||||
if (
|
||||
($bookmark->isPrivate() && $visibility != 'all' && $visibility != 'private')
|
||||
|| (! $bookmark->isPrivate() && $visibility != 'all' && $visibility != 'public')
|
||||
) {
|
||||
return false;
|
||||
|
@ -307,7 +310,8 @@ public function bookmarksCountPerTag(array $filteringTags = [], string $visibili
|
|||
$caseMapping = [];
|
||||
foreach ($bookmarks as $bookmark) {
|
||||
foreach ($bookmark->getTags() as $tag) {
|
||||
if (empty($tag)
|
||||
if (
|
||||
empty($tag)
|
||||
|| (! $this->isLoggedIn && startsWith($tag, '.'))
|
||||
|| $tag === BookmarkMarkdownFormatter::NO_MD_TAG
|
||||
|| in_array($tag, $filteringTags, true)
|
||||
|
@ -356,7 +360,7 @@ public function findByDate(
|
|||
foreach ($this->search([], null, false, false, true) as $bookmark) {
|
||||
if ($to < $bookmark->getCreated()) {
|
||||
$next = $bookmark->getCreated();
|
||||
} else if ($from < $bookmark->getCreated() && $to > $bookmark->getCreated()) {
|
||||
} elseif ($from < $bookmark->getCreated() && $to > $bookmark->getCreated()) {
|
||||
$out[] = $bookmark;
|
||||
} else {
|
||||
if ($previous !== null) {
|
||||
|
@ -405,14 +409,14 @@ protected function migrate(): void
|
|||
false
|
||||
);
|
||||
$updater = new LegacyUpdater(
|
||||
UpdaterUtils::read_updates_file($this->conf->get('resource.updates')),
|
||||
UpdaterUtils::readUpdatesFile($this->conf->get('resource.updates')),
|
||||
$bookmarkDb,
|
||||
$this->conf,
|
||||
true
|
||||
);
|
||||
$newUpdates = $updater->update();
|
||||
if (! empty($newUpdates)) {
|
||||
UpdaterUtils::write_updates_file(
|
||||
UpdaterUtils::writeUpdatesFile(
|
||||
$this->conf->get('resource.updates'),
|
||||
$updater->getDoneUpdates()
|
||||
);
|
||||
|
|
|
@ -150,7 +150,7 @@ private function noFilter(string $visibility = 'all')
|
|||
return $this->bookmarks;
|
||||
}
|
||||
|
||||
$out = array();
|
||||
$out = [];
|
||||
foreach ($this->bookmarks as $key => $value) {
|
||||
if ($value->isPrivate() && $visibility === 'private') {
|
||||
$out[$key] = $value;
|
||||
|
@ -395,7 +395,7 @@ public function filterTags($tags, bool $casesensitive = false, string $visibilit
|
|||
$search = $link->getTagsString($tagsSeparator);
|
||||
if (strlen(trim($link->getDescription())) && strpos($link->getDescription(), '#') !== false) {
|
||||
// description given and at least one possible tag found
|
||||
$descTags = array();
|
||||
$descTags = [];
|
||||
// find all tags in the form of #tag in the description
|
||||
preg_match_all(
|
||||
'/(?<![' . 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
|
||||
{
|
||||
$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->getDescription(), 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($link->getTitle(), 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($tagString, MB_CASE_LOWER, 'UTF-8') . '\\';
|
||||
|
||||
$lengths['title'] = ['start' => 0, 'end' => mb_strlen($link->getTitle())];
|
||||
$nextField = $lengths['title']['end'] + 1;
|
||||
|
|
|
@ -112,12 +112,12 @@ public function write($links)
|
|||
if (is_file($this->datastore) && !is_writeable($this->datastore)) {
|
||||
// The datastore exists but is not writeable
|
||||
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
|
||||
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) {
|
||||
file_put_contents(
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
* To prevent data corruption, it does not overwrite existing bookmarks,
|
||||
* 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
|
||||
*/
|
||||
class BookmarkInitializer
|
||||
|
@ -39,7 +42,7 @@ public function initialize(): void
|
|||
$bookmark->setTitle('Calm Jazz Music - YouTube ' . t('(private bookmark with thumbnail demo)'));
|
||||
$bookmark->setUrl('https://www.youtube.com/watch?v=DVEUcbPkb-c');
|
||||
$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.
|
||||
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->setTitle(t('Note: Shaare descriptions'));
|
||||
$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.
|
||||
|
||||
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')
|
||||
);
|
||||
$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.
|
||||
You can add a description to your bookmarks, such as this one, and tag them.
|
||||
|
|
|
@ -67,14 +67,15 @@ function html_extract_tag($tag, $html)
|
|||
$propertiesKey = ['property', 'name', 'itemprop'];
|
||||
$properties = implode('|', $propertiesKey);
|
||||
// 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.
|
||||
$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)
|
||||
// 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
|
||||
) {
|
||||
return $matches[2];
|
||||
|
@ -116,7 +117,7 @@ function hashtag_autolink($description, $indexUrl = '')
|
|||
* \p{Mn} - any non marking space (accents, umlauts, etc)
|
||||
*/
|
||||
$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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Bookmark\Exception;
|
||||
|
||||
use Exception;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Shaarli\Bookmark\Exception;
|
||||
|
||||
|
||||
class EmptyDataStoreException extends \Exception {}
|
||||
class EmptyDataStoreException extends \Exception
|
||||
{
|
||||
}
|
||||
|
|
|
@ -16,14 +16,14 @@ public function __construct($bookmark)
|
|||
} else {
|
||||
$created = 'Not a DateTime object';
|
||||
}
|
||||
$this->message = 'This bookmark is not valid'. PHP_EOL;
|
||||
$this->message .= ' - ID: '. $bookmark->getId() . PHP_EOL;
|
||||
$this->message .= ' - Title: '. $bookmark->getTitle() . PHP_EOL;
|
||||
$this->message .= ' - Url: '. $bookmark->getUrl() . PHP_EOL;
|
||||
$this->message .= ' - ShortUrl: '. $bookmark->getShortUrl() . PHP_EOL;
|
||||
$this->message .= ' - Created: '. $created . PHP_EOL;
|
||||
$this->message = 'This bookmark is not valid' . PHP_EOL;
|
||||
$this->message .= ' - ID: ' . $bookmark->getId() . PHP_EOL;
|
||||
$this->message .= ' - Title: ' . $bookmark->getTitle() . PHP_EOL;
|
||||
$this->message .= ' - Url: ' . $bookmark->getUrl() . PHP_EOL;
|
||||
$this->message .= ' - ShortUrl: ' . $bookmark->getShortUrl() . PHP_EOL;
|
||||
$this->message .= ' - Created: ' . $created . PHP_EOL;
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Shaarli\Bookmark\Exception;
|
||||
|
||||
|
||||
class NotWritableDataStoreException extends \Exception
|
||||
{
|
||||
/**
|
||||
|
@ -13,7 +11,7 @@ class NotWritableDataStoreException extends \Exception
|
|||
*/
|
||||
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.';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Config;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Config;
|
||||
|
||||
use Shaarli\Config\Exception\MissingFieldConfigException;
|
||||
|
@ -20,7 +21,7 @@ class ConfigManager
|
|||
*/
|
||||
protected static $NOT_FOUND = 'NOT_FOUND';
|
||||
|
||||
public static $DEFAULT_PLUGINS = array('qrcode');
|
||||
public static $DEFAULT_PLUGINS = ['qrcode'];
|
||||
|
||||
/**
|
||||
* @var string Config folder.
|
||||
|
@ -133,7 +134,7 @@ public function get($setting, $default = '')
|
|||
public function set($setting, $value, $write = false, $isLoggedIn = false)
|
||||
{
|
||||
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.
|
||||
|
@ -160,7 +161,7 @@ public function set($setting, $value, $write = false, $isLoggedIn = false)
|
|||
public function remove($setting, $write = false, $isLoggedIn = false)
|
||||
{
|
||||
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.
|
||||
|
@ -213,7 +214,7 @@ public function exists($setting)
|
|||
public function write($isLoggedIn)
|
||||
{
|
||||
// These fields are required in configuration.
|
||||
$mandatoryFields = array(
|
||||
$mandatoryFields = [
|
||||
'credentials.login',
|
||||
'credentials.hash',
|
||||
'credentials.salt',
|
||||
|
@ -222,7 +223,7 @@ public function write($isLoggedIn)
|
|||
'general.title',
|
||||
'general.header_link',
|
||||
'privacy.default_private_links',
|
||||
);
|
||||
];
|
||||
|
||||
// Only logged in user can alter config.
|
||||
if (is_file($this->getConfigFileExt()) && !$isLoggedIn) {
|
||||
|
@ -392,7 +393,7 @@ protected function setDefaultValues()
|
|||
$this->setEmpty('translation.mode', 'php');
|
||||
$this->setEmpty('translation.extensions', []);
|
||||
|
||||
$this->setEmpty('plugins', array());
|
||||
$this->setEmpty('plugins', []);
|
||||
|
||||
$this->setEmpty('formatter', 'markdown');
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Config;
|
||||
|
||||
/**
|
||||
|
@ -12,7 +13,7 @@ class ConfigPhp implements ConfigIO
|
|||
/**
|
||||
* @var array List of config key without group.
|
||||
*/
|
||||
public static $ROOT_KEYS = array(
|
||||
public static $ROOT_KEYS = [
|
||||
'login',
|
||||
'hash',
|
||||
'salt',
|
||||
|
@ -22,7 +23,7 @@ class ConfigPhp implements ConfigIO
|
|||
'redirector',
|
||||
'disablesessionprotection',
|
||||
'privateLinkByDefault',
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* Map legacy config keys with the new ones.
|
||||
|
@ -31,7 +32,7 @@ class ConfigPhp implements ConfigIO
|
|||
*
|
||||
* @var array current key => legacy key.
|
||||
*/
|
||||
public static $LEGACY_KEYS_MAPPING = array(
|
||||
public static $LEGACY_KEYS_MAPPING = [
|
||||
'credentials.login' => 'login',
|
||||
'credentials.hash' => 'hash',
|
||||
'credentials.salt' => 'salt',
|
||||
|
@ -68,7 +69,7 @@ class ConfigPhp implements ConfigIO
|
|||
'privacy.hide_public_links' => 'config.HIDE_PUBLIC_LINKS',
|
||||
'privacy.hide_timestamps' => 'config.HIDE_TIMESTAMPS',
|
||||
'security.open_shaarli' => 'config.OPEN_SHAARLI',
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
|
@ -76,12 +77,12 @@ class ConfigPhp implements ConfigIO
|
|||
public function read($filepath)
|
||||
{
|
||||
if (! file_exists($filepath) || ! is_readable($filepath)) {
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
include $filepath;
|
||||
|
||||
$out = array();
|
||||
$out = [];
|
||||
foreach (self::$ROOT_KEYS as $key) {
|
||||
$out[$key] = isset($GLOBALS[$key]) ? $GLOBALS[$key] : '';
|
||||
}
|
||||
|
@ -95,7 +96,7 @@ public function read($filepath)
|
|||
*/
|
||||
public function write($filepath, $conf)
|
||||
{
|
||||
$configStr = '<?php '. PHP_EOL;
|
||||
$configStr = '<?php ' . PHP_EOL;
|
||||
foreach (self::$ROOT_KEYS as $key) {
|
||||
if (isset($conf[$key])) {
|
||||
$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) {
|
||||
$configStr .= '$GLOBALS[\'config\'][\''
|
||||
. $key
|
||||
.'\'] = '
|
||||
.var_export($conf['config'][$key], true).';'
|
||||
. '\'] = '
|
||||
. var_export($conf['config'][$key], true) . ';'
|
||||
. PHP_EOL;
|
||||
}
|
||||
|
||||
|
@ -115,18 +116,19 @@ public function write($filepath, $conf)
|
|||
foreach ($conf['plugins'] as $key => $value) {
|
||||
$configStr .= '$GLOBALS[\'plugins\'][\''
|
||||
. $key
|
||||
.'\'] = '
|
||||
.var_export($conf['plugins'][$key], true).';'
|
||||
. '\'] = '
|
||||
. var_export($conf['plugins'][$key], true) . ';'
|
||||
. PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!file_put_contents($filepath, $configStr)
|
||||
if (
|
||||
!file_put_contents($filepath, $configStr)
|
||||
|| strcmp(file_get_contents($filepath), $configStr) != 0
|
||||
) {
|
||||
throw new \Shaarli\Exceptions\IOException(
|
||||
$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.')
|
||||
);
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@ function ($value, string $key) use ($directories) {
|
|||
throw new PluginConfigOrderException();
|
||||
}
|
||||
|
||||
$plugins = array();
|
||||
$newEnabledPlugins = array();
|
||||
$plugins = [];
|
||||
$newEnabledPlugins = [];
|
||||
foreach ($formData as $key => $data) {
|
||||
if (startsWith($key, 'order')) {
|
||||
continue;
|
||||
|
@ -62,7 +62,7 @@ function ($value, string $key) use ($directories) {
|
|||
throw new PluginConfigOrderException();
|
||||
}
|
||||
|
||||
$finalPlugins = array();
|
||||
$finalPlugins = [];
|
||||
// Make plugins order continuous.
|
||||
foreach ($plugins as $plugin) {
|
||||
$finalPlugins[] = $plugin;
|
||||
|
@ -81,7 +81,7 @@ function ($value, string $key) use ($directories) {
|
|||
*/
|
||||
function validate_plugin_order($formData)
|
||||
{
|
||||
$orders = array();
|
||||
$orders = [];
|
||||
foreach ($formData as $key => $value) {
|
||||
// No duplicate order allowed.
|
||||
if (in_array($value, $orders, true)) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Shaarli\Config\Exception;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Shaarli\Config\Exception;
|
||||
|
||||
/**
|
||||
|
|
|
@ -158,7 +158,7 @@ public function build(): ShaarliContainer
|
|||
|
||||
$container['updater'] = function (ShaarliContainer $container): Updater {
|
||||
return new Updater(
|
||||
UpdaterUtils::read_updates_file($container->conf->get('resource.updates')),
|
||||
UpdaterUtils::readUpdatesFile($container->conf->get('resource.updates')),
|
||||
$container->bookmarkService,
|
||||
$container->conf,
|
||||
$container->loginManager->isLoggedIn()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Feed;
|
||||
|
||||
use DateTime;
|
||||
|
@ -107,14 +108,14 @@ public function buildData(string $feedType, ?array $userInput)
|
|||
$nblinksToDisplay = $this->getNbLinks(count($linksToDisplay), $userInput);
|
||||
|
||||
// Can't use array_keys() because $link is a LinkDB instance and not a real array.
|
||||
$keys = array();
|
||||
$keys = [];
|
||||
foreach ($linksToDisplay as $key => $value) {
|
||||
$keys[] = $key;
|
||||
}
|
||||
|
||||
$pageaddr = escape(index_url($this->serverInfo));
|
||||
$this->formatter->addContextData('index_url', $pageaddr);
|
||||
$linkDisplayed = array();
|
||||
$linkDisplayed = [];
|
||||
for ($i = 0; $i < $nblinksToDisplay && $i < count($keys); $i++) {
|
||||
$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['guid'] = rtrim($pageaddr, '/') . '/shaare/' . $data['shorturl'];
|
||||
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 {
|
||||
$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>— ' . $permalink;
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
*/
|
||||
class BookmarkDefaultFormatter extends BookmarkFormatter
|
||||
{
|
||||
const SEARCH_HIGHLIGHT_OPEN = '|@@HIGHLIGHT';
|
||||
const SEARCH_HIGHLIGHT_CLOSE = 'HIGHLIGHT@@|';
|
||||
protected const SEARCH_HIGHLIGHT_OPEN = '|@@HIGHLIGHT';
|
||||
protected const SEARCH_HIGHLIGHT_CLOSE = 'HIGHLIGHT@@|';
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
|
|
|
@ -16,7 +16,7 @@ class BookmarkMarkdownFormatter extends BookmarkDefaultFormatter
|
|||
/**
|
||||
* 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 */
|
||||
protected $parsedown;
|
||||
|
@ -71,7 +71,7 @@ public function formatDescription($bookmark)
|
|||
$processedDescription = $this->replaceTokens($processedDescription);
|
||||
|
||||
if (!empty($processedDescription)) {
|
||||
$processedDescription = '<div class="markdown">'. $processedDescription . '</div>';
|
||||
$processedDescription = '<div class="markdown">' . $processedDescription . '</div>';
|
||||
}
|
||||
|
||||
return $processedDescription;
|
||||
|
@ -110,7 +110,7 @@ protected function filterProtocols($description)
|
|||
function ($match) use ($allowedProtocols, $indexUrl) {
|
||||
$link = startsWith($match[1], '?') || startsWith($match[1], '/') ? $indexUrl : '';
|
||||
$link .= whitelist_protocols($match[1], $allowedProtocols);
|
||||
return ']('. $link.')';
|
||||
return '](' . $link . ')';
|
||||
},
|
||||
$description
|
||||
);
|
||||
|
@ -137,7 +137,7 @@ protected function formatHashTags($description)
|
|||
* \p{Mn} - any non marking space (accents, umlauts, etc)
|
||||
*/
|
||||
$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);
|
||||
$descriptionOut = '';
|
||||
|
@ -178,17 +178,17 @@ protected function formatHashTags($description)
|
|||
*/
|
||||
protected function sanitizeHtml($description)
|
||||
{
|
||||
$escapeTags = array(
|
||||
$escapeTags = [
|
||||
'script',
|
||||
'style',
|
||||
'link',
|
||||
'iframe',
|
||||
'frameset',
|
||||
'frame',
|
||||
);
|
||||
];
|
||||
foreach ($escapeTags as $tag) {
|
||||
$description = preg_replace_callback(
|
||||
'#<\s*'. $tag .'[^>]*>(.*</\s*'. $tag .'[^>]*>)?#is',
|
||||
'#<\s*' . $tag . '[^>]*>(.*</\s*' . $tag . '[^>]*>)?#is',
|
||||
function ($match) {
|
||||
return escape($match[0]);
|
||||
},
|
||||
|
|
|
@ -10,4 +10,6 @@
|
|||
*
|
||||
* @package Shaarli\Formatter
|
||||
*/
|
||||
class BookmarkRawFormatter extends BookmarkFormatter {}
|
||||
class BookmarkRawFormatter extends BookmarkFormatter
|
||||
{
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public function __construct(ConfigManager $conf, bool $isLoggedIn)
|
|||
public function getFormatter(string $type = null): BookmarkFormatter
|
||||
{
|
||||
$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)) {
|
||||
$className = '\\Shaarli\\Formatter\\BookmarkDefaultFormatter';
|
||||
}
|
||||
|
|
|
@ -42,7 +42,8 @@ public function __invoke(Request $request, Response $response, callable $next):
|
|||
$this->initBasePath($request);
|
||||
|
||||
try {
|
||||
if (!is_file($this->container->conf->getConfigFileExt())
|
||||
if (
|
||||
!is_file($this->container->conf->getConfigFileExt())
|
||||
&& !in_array($next->getName(), ['displayInstall', 'saveInstall'], true)
|
||||
) {
|
||||
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
|
||||
{
|
||||
if (// if the user isn't logged in
|
||||
if (
|
||||
// if the user isn't logged in
|
||||
!$this->container->loginManager->isLoggedIn()
|
||||
// and Shaarli doesn't have public content...
|
||||
&& $this->container->conf->get('privacy.hide_public_links')
|
||||
|
|
|
@ -51,7 +51,10 @@ public function index(Request $request, Response $response): Response
|
|||
$this->assignView('languages', Languages::getAvailableLanguages());
|
||||
$this->assignView('gd_enabled', extension_loaded('gd'));
|
||||
$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));
|
||||
}
|
||||
|
@ -95,12 +98,15 @@ public function save(Request $request, Response $response): Response
|
|||
}
|
||||
|
||||
$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)
|
||||
) {
|
||||
$this->saveWarningMessage(
|
||||
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);
|
||||
|
|
|
@ -23,7 +23,7 @@ class ExportController extends ShaarliAdminController
|
|||
*/
|
||||
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));
|
||||
}
|
||||
|
@ -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-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));
|
||||
|
|
|
@ -38,7 +38,7 @@ public function index(Request $request, Response $response): Response
|
|||
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));
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ public function import(Request $request, Response $response): Response
|
|||
$msg = sprintf(
|
||||
t(
|
||||
'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'))
|
||||
);
|
||||
|
|
|
@ -32,7 +32,7 @@ public function index(Request $request, Response $response): Response
|
|||
$this->assignView('tags_separator', $separator);
|
||||
$this->assignView(
|
||||
'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));
|
||||
|
@ -87,7 +87,7 @@ public function save(Request $request, Response $response): Response
|
|||
|
||||
$this->saveSuccessMessage($alert);
|
||||
|
||||
$redirect = true === $isDelete ? '/admin/tags' : '/?searchtags='. urlencode($toTag);
|
||||
$redirect = true === $isDelete ? '/admin/tags' : '/?searchtags=' . urlencode($toTag);
|
||||
|
||||
return $this->redirect($response, $redirect);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public function __construct(ShaarliContainer $container)
|
|||
|
||||
$this->assignView(
|
||||
'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
|
||||
// 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(
|
||||
'credentials.hash',
|
||||
sha1(
|
||||
|
|
|
@ -42,7 +42,7 @@ function ($a, $b) {
|
|||
$this->assignView('disabledPlugins', $disabledPlugins);
|
||||
$this->assignView(
|
||||
'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));
|
||||
|
@ -64,7 +64,7 @@ public function save(Request $request, Response $response): Response
|
|||
unset($parameters['parameters_form']);
|
||||
unset($parameters['token']);
|
||||
foreach ($parameters as $param => $value) {
|
||||
$this->container->conf->set('plugins.'. $param, escape($value));
|
||||
$this->container->conf->set('plugins.' . $param, escape($value));
|
||||
}
|
||||
} else {
|
||||
$this->container->conf->set('general.enabled_plugins', save_plugin_config($parameters));
|
||||
|
|
|
@ -72,7 +72,9 @@ public function clearCache(Request $request, Response $response): Response
|
|||
|
||||
$this->saveWarningMessage(
|
||||
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 {
|
||||
$folders = [
|
||||
|
|
|
@ -45,6 +45,4 @@ public function visibility(Request $request, Response $response, array $args): R
|
|||
|
||||
return $this->redirectFromReferer($request, $response, ['visibility']);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public function addShaare(Request $request, Response $response): Response
|
|||
|
||||
$this->assignView(
|
||||
'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('default_private_links', $this->container->conf->get('privacy.default_private_links', false));
|
||||
|
|
|
@ -54,7 +54,7 @@ public function deleteBookmark(Request $request, Response $response): Response
|
|||
$data = $formatter->format($bookmark);
|
||||
$this->executePageHooks('delete_link', $data);
|
||||
$this->container->bookmarkService->remove($bookmark, false);
|
||||
++ $count;
|
||||
++$count;
|
||||
}
|
||||
|
||||
if ($count > 0) {
|
||||
|
|
|
@ -118,7 +118,8 @@ public function save(Request $request, Response $response): Response
|
|||
$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)
|
||||
&& $bookmark->shouldUpdateThumbnail()
|
||||
) {
|
||||
|
@ -148,7 +149,8 @@ public function save(Request $request, Response $response): Response
|
|||
return $this->redirectFromReferer(
|
||||
$request,
|
||||
$response,
|
||||
['/admin/add-shaare', '/admin/shaare'], ['addlink', 'post', 'edit_link'],
|
||||
['/admin/add-shaare', '/admin/shaare'],
|
||||
['addlink', 'post', 'edit_link'],
|
||||
$bookmark->getShortUrl()
|
||||
);
|
||||
}
|
||||
|
@ -168,10 +170,10 @@ protected function displayForm(array $link, bool $isNew, Request $request, Respo
|
|||
$this->assignView($key, $value);
|
||||
}
|
||||
|
||||
$editLabel = false === $isNew ? t('Edit') .' ' : '';
|
||||
$editLabel = false === $isNew ? t('Edit') . ' ' : '';
|
||||
$this->assignView(
|
||||
'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));
|
||||
|
@ -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
|
||||
// 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)
|
||||
&& strpos(get_url_scheme($url) ?: '', 'http') !== false
|
||||
) {
|
||||
|
|
|
@ -34,7 +34,7 @@ public function index(Request $request, Response $response): Response
|
|||
$this->assignView('ids', $ids);
|
||||
$this->assignView(
|
||||
'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));
|
||||
|
|
|
@ -28,7 +28,7 @@ public function index(Request $request, Response $response): Response
|
|||
$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));
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ public function index(Request $request, Response $response): Response
|
|||
$formatter->addContextData('base_path', $this->container->basePath);
|
||||
|
||||
$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.
|
||||
$visibility = $this->container->sessionManager->getSessionParameter('visibility');
|
||||
|
@ -160,7 +161,7 @@ public function permalink(Request $request, Response $response, array $args): Re
|
|||
$data = array_merge(
|
||||
$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)],
|
||||
]
|
||||
);
|
||||
|
@ -185,7 +186,8 @@ protected function updateThumbnail(Bookmark $bookmark, bool $writeDatastore = tr
|
|||
$bookmark->setThumbnail(null);
|
||||
|
||||
// Requires an update, not async retrieval, thumbnails enabled
|
||||
if ($bookmark->shouldUpdateThumbnail()
|
||||
if (
|
||||
$bookmark->shouldUpdateThumbnail()
|
||||
&& true !== $this->container->conf->get('general.enable_async_metadata', true)
|
||||
&& $this->container->conf->get('thumbnails.mode', Thumbnailer::MODE_NONE) !== Thumbnailer::MODE_NONE
|
||||
) {
|
||||
|
|
|
@ -132,7 +132,7 @@ public function rss(Request $request, Response $response): Response
|
|||
'date' => $endDateTime,
|
||||
'date_rss' => $endDateTime->format(DateTime::RSS),
|
||||
'date_human' => DailyPageHelper::getDescriptionByType($type, $dayDateTime),
|
||||
'absolute_url' => $indexUrl . 'daily?'. $type .'=' . $day,
|
||||
'absolute_url' => $indexUrl . 'daily?' . $type . '=' . $day,
|
||||
'links' => [],
|
||||
];
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public function rss(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);
|
||||
$cache = $this->container->pageCacheManager->getCachePage($pageUrl);
|
||||
|
|
|
@ -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.
|
||||
$this->checkPermissions();
|
||||
|
||||
if (static::SESSION_TEST_VALUE
|
||||
if (
|
||||
static::SESSION_TEST_VALUE
|
||||
!== $this->container->sessionManager->getSessionParameter(static::SESSION_TEST_KEY)
|
||||
) {
|
||||
$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.
|
||||
// (Because on some hosts, session.save_path may not be set correctly,
|
||||
// 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)
|
||||
) {
|
||||
// Step 2: Check if data in session is correct.
|
||||
$msg = t(
|
||||
'<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, '.
|
||||
'and that you have write access to it.<br>'.
|
||||
'It currently points to %s.<br>'.
|
||||
'On some browsers, accessing your server via a hostname like \'localhost\' '.
|
||||
'or any custom hostname without a dot causes cookie storage to fail. '.
|
||||
'<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, ' .
|
||||
'and that you have write access to it.<br>' .
|
||||
'It currently points to %s.<br>' .
|
||||
'On some browsers, accessing your server via a hostname like \'localhost\' ' .
|
||||
'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>'
|
||||
);
|
||||
$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
|
||||
{
|
||||
$timezone = 'UTC';
|
||||
if (!empty($request->getParam('continent'))
|
||||
if (
|
||||
!empty($request->getParam('continent'))
|
||||
&& !empty($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');
|
||||
$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.hash', sha1($request->getParam('setpassword') . $login . $salt));
|
||||
|
||||
|
@ -123,7 +126,7 @@ public function save(Request $request, Response $response): Response
|
|||
} else {
|
||||
$this->container->conf->set(
|
||||
'general.title',
|
||||
'Shared bookmarks on '.escape(index_url($this->container->environment))
|
||||
'Shared bookmarks on ' . escape(index_url($this->container->environment))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public function index(Request $request, Response $response): Response
|
|||
$this
|
||||
->assignView('returnurl', escape($returnUrl))
|
||||
->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));
|
||||
|
@ -64,7 +64,8 @@ public function login(Request $request, Response $response): Response
|
|||
return $this->redirect($response, '/');
|
||||
}
|
||||
|
||||
if (!$this->container->loginManager->checkCredentials(
|
||||
if (
|
||||
!$this->container->loginManager->checkCredentials(
|
||||
client_ip_id($this->container->environment),
|
||||
$request->getParam('login'),
|
||||
$request->getParam('password')
|
||||
|
@ -101,7 +102,8 @@ public function login(Request $request, Response $response): Response
|
|||
*/
|
||||
protected function checkLoginState(): bool
|
||||
{
|
||||
if ($this->container->loginManager->isLoggedIn()
|
||||
if (
|
||||
$this->container->loginManager->isLoggedIn()
|
||||
|| $this->container->conf->get('security.open_shaarli', false)
|
||||
) {
|
||||
throw new CantLoginException();
|
||||
|
|
|
@ -26,7 +26,7 @@ public function index(Request $request, Response $response): Response
|
|||
|
||||
$this->assignView(
|
||||
'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:
|
||||
|
|
|
@ -144,7 +144,8 @@ protected function redirectFromReferer(
|
|||
if (null !== $referer) {
|
||||
$currentUrl = parse_url($referer);
|
||||
// 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
|
||||
) {
|
||||
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 : '';
|
||||
|
||||
return $response->withRedirect($path . $queryString . $anchor);
|
||||
|
|
|
@ -84,10 +84,10 @@ protected function processRequest(string $type, Request $request, Response $resp
|
|||
$this->executePageHooks('render_tag' . $type, $data, 'tag.' . $type);
|
||||
$this->assignAllView($data);
|
||||
|
||||
$searchTags = !empty($searchTags) ? trim(str_replace($tagsSeparator, ' ', $searchTags)) .' - ' : '';
|
||||
$searchTags = !empty($searchTags) ? trim(str_replace($tagsSeparator, ' ', $searchTags)) . ' - ' : '';
|
||||
$this->assignView(
|
||||
'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));
|
||||
|
|
|
@ -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
|
||||
if (null === $referer) {
|
||||
if (null !== $newTag) {
|
||||
return $this->redirect($response, '/?searchtags='. urlencode($newTag));
|
||||
return $this->redirect($response, '/?searchtags=' . urlencode($newTag));
|
||||
}
|
||||
|
||||
return $this->redirect($response, '/');
|
||||
|
@ -37,7 +37,7 @@ public function addTag(Request $request, Response $response, array $args): Respo
|
|||
parse_str($currentUrl['query'] ?? '', $params);
|
||||
|
||||
if (null === $newTag) {
|
||||
return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params));
|
||||
return $response->withRedirect(($currentUrl['path'] ?? './') . '?' . http_build_query($params));
|
||||
}
|
||||
|
||||
// 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)
|
||||
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);
|
||||
|
||||
if (null === $tagToRemove) {
|
||||
return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params));
|
||||
return $response->withRedirect(($currentUrl['path'] ?? './') . '?' . http_build_query($params));
|
||||
}
|
||||
|
||||
// Prevent redirection loop
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Helper;
|
||||
|
||||
use Exception;
|
||||
|
@ -16,7 +17,7 @@ class ApplicationUtils
|
|||
|
||||
public static $GITHUB_URL = 'https://github.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_END_TAG = ' */ ?>';
|
||||
|
||||
|
@ -64,8 +65,8 @@ public static function getVersion($remote, $timeout = 2)
|
|||
}
|
||||
|
||||
return str_replace(
|
||||
array(self::$VERSION_START_TAG, self::$VERSION_END_TAG, PHP_EOL),
|
||||
array('', '', ''),
|
||||
[self::$VERSION_START_TAG, self::$VERSION_END_TAG, PHP_EOL],
|
||||
['', '', ''],
|
||||
$data
|
||||
);
|
||||
}
|
||||
|
@ -184,13 +185,15 @@ public static function checkResourcePermissions(ConfigManager $conf, bool $minim
|
|||
$rainTplDir = rtrim($conf->get('resource.raintpl_tpl'), '/');
|
||||
|
||||
// Check script and template directories are readable
|
||||
foreach ([
|
||||
'application',
|
||||
'inc',
|
||||
'plugins',
|
||||
$rainTplDir,
|
||||
$rainTplDir . '/' . $conf->get('resource.theme'),
|
||||
] as $path) {
|
||||
foreach (
|
||||
[
|
||||
'application',
|
||||
'inc',
|
||||
'plugins',
|
||||
$rainTplDir,
|
||||
$rainTplDir . '/' . $conf->get('resource.theme'),
|
||||
] as $path
|
||||
) {
|
||||
if (!is_readable(realpath($path))) {
|
||||
$errors[] = '"' . $path . '" ' . t('directory is not readable');
|
||||
}
|
||||
|
@ -203,10 +206,10 @@ public static function checkResourcePermissions(ConfigManager $conf, bool $minim
|
|||
];
|
||||
} else {
|
||||
$folders = [
|
||||
$conf->get('resource.thumbnails_cache'),
|
||||
$conf->get('resource.data_dir'),
|
||||
$conf->get('resource.page_cache'),
|
||||
$conf->get('resource.raintpl_tmp'),
|
||||
$conf->get('resource.thumbnails_cache'),
|
||||
$conf->get('resource.data_dir'),
|
||||
$conf->get('resource.page_cache'),
|
||||
$conf->get('resource.raintpl_tmp'),
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -224,13 +227,15 @@ public static function checkResourcePermissions(ConfigManager $conf, bool $minim
|
|||
}
|
||||
|
||||
// Check configuration files are readable and writable
|
||||
foreach (array(
|
||||
$conf->getConfigFileExt(),
|
||||
$conf->get('resource.datastore'),
|
||||
$conf->get('resource.ban_file'),
|
||||
$conf->get('resource.log'),
|
||||
$conf->get('resource.update_check'),
|
||||
) as $path) {
|
||||
foreach (
|
||||
[
|
||||
$conf->getConfigFileExt(),
|
||||
$conf->get('resource.datastore'),
|
||||
$conf->get('resource.ban_file'),
|
||||
$conf->get('resource.log'),
|
||||
$conf->get('resource.update_check'),
|
||||
] as $path
|
||||
) {
|
||||
if (!is_file(realpath($path))) {
|
||||
# the file may not exist yet
|
||||
continue;
|
||||
|
|
|
@ -105,7 +105,7 @@ public static function clearFolder(string $path, bool $selfDelete, array $exclud
|
|||
}
|
||||
|
||||
foreach (new \DirectoryIterator($path) as $file) {
|
||||
if($file->isDot()) {
|
||||
if ($file->isDot()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ public static function clearFolder(string $path, bool $selfDelete, array $exclud
|
|||
|
||||
if ($file->isFile()) {
|
||||
unlink($file->getPathname());
|
||||
} elseif($file->isDir()) {
|
||||
} elseif ($file->isDir()) {
|
||||
$skipped = static::clearFolder($file->getRealPath(), true, $exclude) || $skipped;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ function get_http_response(
|
|||
$cleanUrl = $urlObj->idnToAscii();
|
||||
|
||||
if (!filter_var($cleanUrl, FILTER_VALIDATE_URL) || !$urlObj->isHttp()) {
|
||||
return array(array(0 => 'Invalid HTTP UrlUtils'), false);
|
||||
return [[0 => 'Invalid HTTP UrlUtils'], false];
|
||||
}
|
||||
|
||||
$userAgent =
|
||||
|
@ -71,7 +71,7 @@ function get_http_response(
|
|||
|
||||
$ch = curl_init($cleanUrl);
|
||||
if ($ch === false) {
|
||||
return array(array(0 => 'curl_init() error'), false);
|
||||
return [[0 => 'curl_init() error'], false];
|
||||
}
|
||||
|
||||
// General cURL settings
|
||||
|
@ -82,7 +82,7 @@ function get_http_response(
|
|||
curl_setopt(
|
||||
$ch,
|
||||
CURLOPT_HTTPHEADER,
|
||||
array('Accept-Language: ' . $acceptLanguage)
|
||||
['Accept-Language: ' . $acceptLanguage]
|
||||
);
|
||||
curl_setopt($ch, CURLOPT_MAXREDIRS, $maxRedirs);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
@ -90,7 +90,7 @@ function get_http_response(
|
|||
curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
|
||||
|
||||
// Max download size management
|
||||
curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024*16);
|
||||
curl_setopt($ch, CURLOPT_BUFFERSIZE, 1024 * 16);
|
||||
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
|
||||
if (is_callable($curlHeaderFunction)) {
|
||||
curl_setopt($ch, CURLOPT_HEADERFUNCTION, $curlHeaderFunction);
|
||||
|
@ -122,9 +122,9 @@ function ($arg0, $arg1, $arg2, $arg3, $arg4) use ($maxBytes) {
|
|||
* Removing this would require updating
|
||||
* 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
|
||||
|
@ -135,7 +135,7 @@ function ($arg0, $arg1, $arg2, $arg3, $arg4) use ($maxBytes) {
|
|||
$rawHeadersLastRedir = end($rawHeadersArrayRedirs);
|
||||
|
||||
$content = substr($response, $headSize);
|
||||
$headers = array();
|
||||
$headers = [];
|
||||
foreach (preg_split('~[\r\n]+~', $rawHeadersLastRedir) as $line) {
|
||||
if (empty($line) || ctype_space($line)) {
|
||||
continue;
|
||||
|
@ -146,7 +146,7 @@ function ($arg0, $arg1, $arg2, $arg3, $arg4) use ($maxBytes) {
|
|||
$value = $splitLine[1];
|
||||
if (array_key_exists($key, $headers)) {
|
||||
if (!is_array($headers[$key])) {
|
||||
$headers[$key] = array(0 => $headers[$key]);
|
||||
$headers[$key] = [0 => $headers[$key]];
|
||||
}
|
||||
$headers[$key][] = $value;
|
||||
} 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,
|
||||
$maxRedr
|
||||
) {
|
||||
$options = array(
|
||||
'http' => array(
|
||||
$options = [
|
||||
'http' => [
|
||||
'method' => 'GET',
|
||||
'timeout' => $timeout,
|
||||
'user_agent' => $userAgent,
|
||||
'header' => "Accept: */*\r\n"
|
||||
. 'Accept-Language: ' . $acceptLanguage
|
||||
)
|
||||
);
|
||||
]
|
||||
];
|
||||
|
||||
stream_context_set_default($options);
|
||||
list($headers, $finalUrl) = get_redirected_headers($cleanUrl, $maxRedr);
|
||||
|
@ -207,7 +207,7 @@ function get_http_response_fallback(
|
|||
}
|
||||
|
||||
if (! $headers) {
|
||||
return array($headers, false);
|
||||
return [$headers, false];
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -215,10 +215,10 @@ function get_http_response_fallback(
|
|||
$context = stream_context_create($options);
|
||||
$content = file_get_contents($finalUrl, false, $context, -1, $maxBytes);
|
||||
} 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.
|
||||
if ($redirectionLimit-- > 0
|
||||
if (
|
||||
$redirectionLimit-- > 0
|
||||
&& !empty($headers)
|
||||
&& (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'];
|
||||
if ($redirection != $url) {
|
||||
$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);
|
||||
$final = $parts['scheme'] .'://'. $parts['host'];
|
||||
$final = $parts['scheme'] . '://' . $parts['host'];
|
||||
$final .= (!empty($parts['port'])) ? $parts['port'] : '';
|
||||
$final .= '/';
|
||||
if ($newUrl[0] != '/') {
|
||||
|
@ -323,7 +325,8 @@ function server_url($server)
|
|||
$scheme = 'https';
|
||||
}
|
||||
|
||||
if (($scheme == 'http' && $port != '80')
|
||||
if (
|
||||
($scheme == 'http' && $port != '80')
|
||||
|| ($scheme == 'https' && $port != '443')
|
||||
) {
|
||||
$port = ':' . $port;
|
||||
|
@ -344,22 +347,26 @@ function server_url($server)
|
|||
$host = $server['SERVER_NAME'];
|
||||
}
|
||||
|
||||
return $scheme.'://'.$host.$port;
|
||||
return $scheme . '://' . $host . $port;
|
||||
}
|
||||
|
||||
// SSL detection
|
||||
if ((! empty($server['HTTPS']) && strtolower($server['HTTPS']) == 'on')
|
||||
|| (isset($server['SERVER_PORT']) && $server['SERVER_PORT'] == '443')) {
|
||||
if (
|
||||
(! empty($server['HTTPS']) && strtolower($server['HTTPS']) == 'on')
|
||||
|| (isset($server['SERVER_PORT']) && $server['SERVER_PORT'] == '443')
|
||||
) {
|
||||
$scheme = 'https';
|
||||
}
|
||||
|
||||
// Do not append standard port values
|
||||
if (($scheme == 'http' && $server['SERVER_PORT'] != '80')
|
||||
|| ($scheme == 'https' && $server['SERVER_PORT'] != '443')) {
|
||||
$port = ':'.$server['SERVER_PORT'];
|
||||
if (
|
||||
($scheme == 'http' && $server['SERVER_PORT'] != '80')
|
||||
|| ($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 function ($ch, $data) use (
|
||||
return function (
|
||||
$ch,
|
||||
$data
|
||||
) use (
|
||||
$retrieveDescription,
|
||||
$tagsSeparator,
|
||||
&$charset,
|
||||
|
@ -601,7 +611,7 @@ function get_curl_download_callback(
|
|||
$foundChunk = $currentChunk;
|
||||
// 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 `-`.
|
||||
$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), '-');
|
||||
}, tags_str2array($keywords, ',')), $tagsSeparator);
|
||||
}
|
||||
|
@ -611,7 +621,8 @@ function get_curl_download_callback(
|
|||
// If we already found either the title, description or keywords,
|
||||
// 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.
|
||||
if ((!empty($responseCode) && !empty($contentType) && !empty($charset)) && $foundChunk !== null
|
||||
if (
|
||||
(!empty($responseCode) && !empty($contentType) && !empty($charset)) && $foundChunk !== null
|
||||
&& (! $retrieveDescription
|
||||
|| $foundChunk < $currentChunk
|
||||
|| (!empty($title) && !empty($description) && !empty($keywords))
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
class Url
|
||||
{
|
||||
private static $annoyingQueryParams = array(
|
||||
private static $annoyingQueryParams = [
|
||||
// Facebook
|
||||
'action_object_map=',
|
||||
'action_ref_map=',
|
||||
|
@ -37,15 +37,15 @@ class Url
|
|||
|
||||
// Other
|
||||
'campaign_'
|
||||
);
|
||||
];
|
||||
|
||||
private static $annoyingFragments = array(
|
||||
private static $annoyingFragments = [
|
||||
// ATInternet
|
||||
'xtor=RSS-',
|
||||
|
||||
// Misc.
|
||||
'tk.rss_all'
|
||||
);
|
||||
];
|
||||
|
||||
/*
|
||||
* URL parts represented as an array
|
||||
|
@ -120,7 +120,7 @@ protected function cleanupQuery()
|
|||
foreach (self::$annoyingQueryParams as $annoying) {
|
||||
foreach ($queryParams as $param) {
|
||||
if (startsWith($param, $annoying)) {
|
||||
$queryParams = array_diff($queryParams, array($param));
|
||||
$queryParams = array_diff($queryParams, [$param]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Converts an array-represented URL to a string
|
||||
*
|
||||
|
@ -12,15 +13,15 @@
|
|||
*/
|
||||
function unparse_url($parsedUrl)
|
||||
{
|
||||
$scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'].'://' : '';
|
||||
$scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'] . '://' : '';
|
||||
$host = isset($parsedUrl['host']) ? $parsedUrl['host'] : '';
|
||||
$port = isset($parsedUrl['port']) ? ':'.$parsedUrl['port'] : '';
|
||||
$port = isset($parsedUrl['port']) ? ':' . $parsedUrl['port'] : '';
|
||||
$user = isset($parsedUrl['user']) ? $parsedUrl['user'] : '';
|
||||
$pass = isset($parsedUrl['pass']) ? ':'.$parsedUrl['pass'] : '';
|
||||
$pass = isset($parsedUrl['pass']) ? ':' . $parsedUrl['pass'] : '';
|
||||
$pass = ($user || $pass) ? "$pass@" : '';
|
||||
$path = isset($parsedUrl['path']) ? $parsedUrl['path'] : '';
|
||||
$query = isset($parsedUrl['query']) ? '?'.$parsedUrl['query'] : '';
|
||||
$fragment = isset($parsedUrl['fragment']) ? '#'.$parsedUrl['fragment'] : '';
|
||||
$query = isset($parsedUrl['query']) ? '?' . $parsedUrl['query'] : '';
|
||||
$fragment = isset($parsedUrl['fragment']) ? '#' . $parsedUrl['fragment'] : '';
|
||||
|
||||
return "$scheme$user$pass$host$port$path$query$fragment";
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ public function post(Request $request, Response $response): Response
|
|||
|
||||
if (!$this->container->loginManager->isLoggedIn()) {
|
||||
$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);
|
||||
|
|
|
@ -62,7 +62,7 @@ class LegacyLinkDB implements Iterator, Countable, ArrayAccess
|
|||
private $datastore;
|
||||
|
||||
// Link date storage format
|
||||
const LINK_DATE_FORMAT = 'Ymd_His';
|
||||
public const LINK_DATE_FORMAT = 'Ymd_His';
|
||||
|
||||
// List of bookmarks (associative array)
|
||||
// - key: link date (e.g. "20110823_124546"),
|
||||
|
@ -240,8 +240,8 @@ private function check()
|
|||
}
|
||||
|
||||
// Create a dummy database for example
|
||||
$this->links = array();
|
||||
$link = array(
|
||||
$this->links = [];
|
||||
$link = [
|
||||
'id' => 1,
|
||||
'title' => t('The personal, minimalist, super-fast, database free, bookmarking service'),
|
||||
'url' => 'https://shaarli.readthedocs.io',
|
||||
|
@ -257,11 +257,11 @@ private function check()
|
|||
'created' => new DateTime(),
|
||||
'tags' => 'opensource software',
|
||||
'sticky' => false,
|
||||
);
|
||||
];
|
||||
$link['shorturl'] = link_small_hash($link['created'], $link['id']);
|
||||
$this->links[1] = $link;
|
||||
|
||||
$link = array(
|
||||
$link = [
|
||||
'id' => 0,
|
||||
'title' => t('My secret stuff... - Pastebin.com'),
|
||||
'url' => 'http://sebsauvage.net/paste/?8434b27936c09649#bR7XsXhoTiLcqCpQbmOpBi3rq2zzQUC5hBI7ZT1O3x8=',
|
||||
|
@ -270,7 +270,7 @@ private function check()
|
|||
'created' => new DateTime('1 minute ago'),
|
||||
'tags' => 'secretstuff',
|
||||
'sticky' => false,
|
||||
);
|
||||
];
|
||||
$link['shorturl'] = link_small_hash($link['created'], $link['id']);
|
||||
$this->links[0] = $link;
|
||||
|
||||
|
@ -285,7 +285,7 @@ private function read()
|
|||
{
|
||||
// Public bookmarks are hidden and user not logged in => nothing to show
|
||||
if ($this->hidePublicLinks && !$this->loggedIn) {
|
||||
$this->links = array();
|
||||
$this->links = [];
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -293,7 +293,7 @@ private function read()
|
|||
$this->ids = [];
|
||||
$this->links = FileUtils::readFlatDB($this->datastore, []);
|
||||
|
||||
$toremove = array();
|
||||
$toremove = [];
|
||||
foreach ($this->links as $key => &$link) {
|
||||
if (!$this->loggedIn && $link['private'] != 0) {
|
||||
// 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.
|
||||
*/
|
||||
public function filterSearch(
|
||||
$filterRequest = array(),
|
||||
$filterRequest = [],
|
||||
$casesensitive = false,
|
||||
$visibility = 'all',
|
||||
$untaggedonly = false
|
||||
|
@ -512,7 +512,7 @@ public function renameTag($from, $to)
|
|||
*/
|
||||
public function days()
|
||||
{
|
||||
$linkDays = array();
|
||||
$linkDays = [];
|
||||
foreach ($this->links as $link) {
|
||||
$linkDays[$link['created']->format('Ymd')] = 0;
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ private function noFilter($visibility = 'all')
|
|||
return $this->links;
|
||||
}
|
||||
|
||||
$out = array();
|
||||
$out = [];
|
||||
foreach ($this->links as $key => $value) {
|
||||
if ($value['private'] && $visibility === 'private') {
|
||||
$out[$key] = $value;
|
||||
|
@ -143,7 +143,7 @@ private function noFilter($visibility = 'all')
|
|||
*/
|
||||
private function filterSmallHash($smallHash)
|
||||
{
|
||||
$filtered = array();
|
||||
$filtered = [];
|
||||
foreach ($this->links as $key => $l) {
|
||||
if ($smallHash == $l['shorturl']) {
|
||||
// Yes, this is ugly and slow
|
||||
|
@ -186,7 +186,7 @@ private function filterFulltext($searchterms, $visibility = 'all')
|
|||
return $this->noFilter($visibility);
|
||||
}
|
||||
|
||||
$filtered = array();
|
||||
$filtered = [];
|
||||
$search = mb_convert_case(html_entity_decode($searchterms), MB_CASE_LOWER, 'UTF-8');
|
||||
$exactRegex = '/"([^"]+)"/';
|
||||
// Retrieve exact search terms.
|
||||
|
@ -198,8 +198,8 @@ private function filterFulltext($searchterms, $visibility = 'all')
|
|||
$explodedSearchAnd = array_values(array_filter($explodedSearchAnd));
|
||||
|
||||
// Filter excluding terms and update andSearch.
|
||||
$excludeSearch = array();
|
||||
$andSearch = array();
|
||||
$excludeSearch = [];
|
||||
$andSearch = [];
|
||||
foreach ($explodedSearchAnd as $needle) {
|
||||
if ($needle[0] == '-' && strlen($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.
|
||||
foreach ($this->links as $id => $link) {
|
||||
|
@ -336,7 +336,7 @@ public function filterTags($tags, $casesensitive = false, $visibility = 'all')
|
|||
}
|
||||
|
||||
// create resulting array
|
||||
$filtered = array();
|
||||
$filtered = [];
|
||||
|
||||
// iterate over each 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
|
||||
if (strlen(trim($link['description'])) && strpos($link['description'], '#') !== false) {
|
||||
// description given and at least one possible tag found
|
||||
$descTags = array();
|
||||
$descTags = [];
|
||||
// find all tags in the form of #tag in the description
|
||||
preg_match_all(
|
||||
'/(?<![' . self::$HASHTAG_CHARS . '])#([' . self::$HASHTAG_CHARS . ']+?)\b/sm',
|
||||
|
@ -419,7 +419,7 @@ public function filterDay($day)
|
|||
throw new Exception('Invalid date format');
|
||||
}
|
||||
|
||||
$filtered = array();
|
||||
$filtered = [];
|
||||
foreach ($this->links as $key => $l) {
|
||||
if ($l['created']->format('Ymd') == $day) {
|
||||
$filtered[$key] = $l;
|
||||
|
|
|
@ -93,7 +93,7 @@ public function __construct($doneUpdates, $linkDB, $conf, $isLoggedIn, &$session
|
|||
*/
|
||||
public function update()
|
||||
{
|
||||
$updatesRan = array();
|
||||
$updatesRan = [];
|
||||
|
||||
// If the user isn't logged in, exit without updating.
|
||||
if ($this->isLoggedIn !== true) {
|
||||
|
@ -106,7 +106,8 @@ public function update()
|
|||
|
||||
foreach ($this->methods as $method) {
|
||||
// Not an update method or already done, pass.
|
||||
if (!startsWith($method->getName(), 'updateMethod')
|
||||
if (
|
||||
!startsWith($method->getName(), 'updateMethod')
|
||||
|| in_array($method->getName(), $this->doneUpdates)
|
||||
) {
|
||||
continue;
|
||||
|
@ -189,7 +190,7 @@ public function updateMethodConfigToJson()
|
|||
}
|
||||
|
||||
// Set sub config keys (config and plugins)
|
||||
$subConfig = array('config', 'plugins');
|
||||
$subConfig = ['config', 'plugins'];
|
||||
foreach ($subConfig as $sub) {
|
||||
foreach ($oldConfig[$sub] as $key => $value) {
|
||||
if (isset($legacyMap[$sub . '.' . $key])) {
|
||||
|
@ -259,7 +260,7 @@ public function updateMethodDatastoreIds()
|
|||
$save = $this->conf->get('resource.data_dir') . '/datastore.' . date('YmdHis') . '.php';
|
||||
copy($this->conf->get('resource.datastore'), $save);
|
||||
|
||||
$links = array();
|
||||
$links = [];
|
||||
foreach ($this->linkDB as $offset => $value) {
|
||||
$links[] = $value;
|
||||
unset($this->linkDB[$offset]);
|
||||
|
@ -498,7 +499,8 @@ public function updateMethodVisibilitySession()
|
|||
*/
|
||||
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')
|
||||
) {
|
||||
return true;
|
||||
|
|
|
@ -59,11 +59,11 @@ public function filterAndFormat(
|
|||
$indexUrl
|
||||
) {
|
||||
// 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 . '"');
|
||||
}
|
||||
|
||||
$bookmarkLinks = array();
|
||||
$bookmarkLinks = [];
|
||||
foreach ($this->bookmarkService->search([], $selection) as $bookmark) {
|
||||
$link = $formatter->format($bookmark);
|
||||
$link['taglist'] = implode(',', $bookmark->getTags());
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Plugin;
|
||||
|
||||
use Shaarli\Config\ConfigManager;
|
||||
|
@ -23,7 +24,7 @@ class PluginManager
|
|||
*
|
||||
* @var array $loadedPlugins
|
||||
*/
|
||||
private $loadedPlugins = array();
|
||||
private $loadedPlugins = [];
|
||||
|
||||
/**
|
||||
* @var ConfigManager Configuration Manager instance.
|
||||
|
@ -57,7 +58,7 @@ class PluginManager
|
|||
public function __construct(&$conf)
|
||||
{
|
||||
$this->conf = $conf;
|
||||
$this->errors = array();
|
||||
$this->errors = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,7 +99,7 @@ public function load($authorizedPlugins)
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function executeHooks($hook, &$data, $params = array())
|
||||
public function executeHooks($hook, &$data, $params = [])
|
||||
{
|
||||
$metadataParameters = [
|
||||
'target' => '_PAGE_',
|
||||
|
@ -196,7 +197,7 @@ public function buildHookName($hook, $pluginName)
|
|||
*/
|
||||
public function getPluginsMeta()
|
||||
{
|
||||
$metaData = array();
|
||||
$metaData = [];
|
||||
$dirs = glob(self::$PLUGINS_PATH . '/*', GLOB_ONLYDIR | GLOB_MARK);
|
||||
|
||||
// Browse all plugin directories.
|
||||
|
@ -217,9 +218,9 @@ public function getPluginsMeta()
|
|||
if (isset($metaData[$plugin]['parameters'])) {
|
||||
$params = explode(';', $metaData[$plugin]['parameters']);
|
||||
} else {
|
||||
$params = array();
|
||||
$params = [];
|
||||
}
|
||||
$metaData[$plugin]['parameters'] = array();
|
||||
$metaData[$plugin]['parameters'] = [];
|
||||
foreach ($params as $param) {
|
||||
if (empty($param)) {
|
||||
continue;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Plugin\Exception;
|
||||
|
||||
use Exception;
|
||||
|
|
|
@ -23,10 +23,10 @@ class ThemeUtils
|
|||
public static function getThemes($tplDir)
|
||||
{
|
||||
$tplDir = rtrim($tplDir, '/');
|
||||
$allTheme = glob($tplDir.'/*', GLOB_ONLYDIR);
|
||||
$allTheme = glob($tplDir . '/*', GLOB_ONLYDIR);
|
||||
$themes = [];
|
||||
foreach ($allTheme as $value) {
|
||||
$themes[] = str_replace($tplDir.'/', '', $value);
|
||||
$themes[] = str_replace($tplDir . '/', '', $value);
|
||||
}
|
||||
|
||||
return $themes;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Shaarli\Security;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
@ -47,7 +46,8 @@ class BanManager
|
|||
* @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
|
||||
*/
|
||||
public function __construct($trustedProxies, $nbAttempts, $banDuration, $banFile, LoggerInterface $logger) {
|
||||
public function __construct($trustedProxies, $nbAttempts, $banDuration, $banFile, LoggerInterface $logger)
|
||||
{
|
||||
$this->trustedProxies = $trustedProxies;
|
||||
$this->nbAttempts = $nbAttempts;
|
||||
$this->banDuration = $banDuration;
|
||||
|
@ -80,7 +80,7 @@ public function handleFailedAttempt($server)
|
|||
|
||||
if ($this->failures[$ip] >= $this->nbAttempts) {
|
||||
$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();
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ public function isBanned($server)
|
|||
unset($this->failures[$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();
|
||||
return false;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Security;
|
||||
|
||||
use Exception;
|
||||
|
@ -106,7 +107,8 @@ public function checkLoginState($clientIpId)
|
|||
// The user client has a valid stay-signed-in cookie
|
||||
// Session information is updated with the current client information
|
||||
$this->sessionManager->storeLoginInfo($clientIpId);
|
||||
} elseif ($this->sessionManager->hasSessionExpired()
|
||||
} elseif (
|
||||
$this->sessionManager->hasSessionExpired()
|
||||
|| $this->sessionManager->hasClientIpChanged($clientIpId)
|
||||
) {
|
||||
$this->sessionManager->logout();
|
||||
|
@ -145,7 +147,8 @@ public function checkCredentials($clientIpId, $login, $password)
|
|||
// Check credentials
|
||||
try {
|
||||
$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))
|
||||
|| (true === $useLdapLogin && $this->checkCredentialsFromLdap($login, $password))
|
||||
|
@ -156,7 +159,7 @@ public function checkCredentials($clientIpId, $login, $password)
|
|||
|
||||
return true;
|
||||
}
|
||||
} catch(Exception $exception) {
|
||||
} catch (Exception $exception) {
|
||||
$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
|
||||
*/
|
||||
public function checkCredentialsFromLocalConfig($login, $password) {
|
||||
public function checkCredentialsFromLocalConfig($login, $password)
|
||||
{
|
||||
$hash = sha1($password . $login . $this->configManager->get('credentials.salt'));
|
||||
|
||||
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)
|
||||
{
|
||||
$connect = $connect ?? function($host) {
|
||||
$connect = $connect ?? function ($host) {
|
||||
$resource = ldap_connect($host);
|
||||
|
||||
ldap_set_option($resource, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
|
||||
return $resource;
|
||||
};
|
||||
$bind = $bind ?? function($handle, $dn, $password) {
|
||||
$bind = $bind ?? function ($handle, $dn, $password) {
|
||||
return ldap_bind($handle, $dn, $password);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Security;
|
||||
|
||||
use Shaarli\Config\ConfigManager;
|
||||
|
@ -79,7 +80,7 @@ public function setStaySignedIn($staySignedIn)
|
|||
*/
|
||||
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;
|
||||
return $token;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,8 @@ public function update(string $basePath = null)
|
|||
|
||||
foreach ($this->methods as $method) {
|
||||
// Not an update method or already done, pass.
|
||||
if (! startsWith($method->getName(), 'updateMethod')
|
||||
if (
|
||||
! startsWith($method->getName(), 'updateMethod')
|
||||
|| in_array($method->getName(), $this->doneUpdates)
|
||||
) {
|
||||
continue;
|
||||
|
@ -121,12 +122,12 @@ public function getDoneUpdates()
|
|||
|
||||
public function readUpdates(string $updatesFilepath): array
|
||||
{
|
||||
return UpdaterUtils::read_updates_file($updatesFilepath);
|
||||
return UpdaterUtils::readUpdatesFile($updatesFilepath);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
foreach ($this->bookmarkService->search() as $bookmark) {
|
||||
if ($bookmark->isNote()
|
||||
if (
|
||||
$bookmark->isNote()
|
||||
&& startsWith($bookmark->getUrl(), '?')
|
||||
&& 1 === preg_match('/^\?([a-zA-Z0-9-_@]{6})($|&|#)/', $bookmark->getUrl(), $match)
|
||||
) {
|
||||
|
|
|
@ -11,7 +11,7 @@ class UpdaterUtils
|
|||
*
|
||||
* @return array Already done update methods.
|
||||
*/
|
||||
public static function read_updates_file($updatesFilepath)
|
||||
public static function readUpdatesFile($updatesFilepath)
|
||||
{
|
||||
if (! empty($updatesFilepath) && is_file($updatesFilepath)) {
|
||||
$content = file_get_contents($updatesFilepath);
|
||||
|
@ -19,7 +19,7 @@ public static function read_updates_file($updatesFilepath)
|
|||
return explode(';', $content);
|
||||
}
|
||||
}
|
||||
return array();
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ public static function read_updates_file($updatesFilepath)
|
|||
*
|
||||
* @throws \Exception Couldn't write version number.
|
||||
*/
|
||||
public static function write_updates_file($updatesFilepath, $updates)
|
||||
public static function writeUpdatesFile($updatesFilepath, $updates)
|
||||
{
|
||||
if (empty($updatesFilepath)) {
|
||||
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));
|
||||
if ($res === false) {
|
||||
throw new \Exception('Unable to write updates in '. $updatesFilepath . '.');
|
||||
throw new \Exception('Unable to write updates in ' . $updatesFilepath . '.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ Please read [Contributing to Shaarli](https://github.com/shaarli/Shaarli/tree/ma
|
|||
|
||||
|
||||
- [Unit tests](Unit-tests)
|
||||
- Javascript linting - Shaarli uses [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript).
|
||||
- Javascript linting - Shaarli uses [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript).
|
||||
Run `make eslint` to check JS style.
|
||||
- [GnuPG signature](GnuPG-signature) for tags/releases
|
||||
|
||||
|
@ -51,12 +51,12 @@ PHP (managed through [`composer.json`](https://github.com/shaarli/Shaarli/blob/m
|
|||
|
||||
## Link structure
|
||||
|
||||
Every link available through the `LinkDB` object is represented as an array
|
||||
Every link available through the `LinkDB` object is represented as an array
|
||||
containing the following fields:
|
||||
|
||||
* `id` (integer): Unique identifier.
|
||||
* `title` (string): Title of the link.
|
||||
* `url` (string): URL of the link. Used for displayable links (without redirector, url encoding, etc.).
|
||||
* `url` (string): URL of the link. Used for displayable links (without redirector, url encoding, etc.).
|
||||
Can be absolute or relative for Notes.
|
||||
* `real_url` (string): Real destination URL, can be redirected, encoded, etc.
|
||||
* `shorturl` (string): Permalink small hash.
|
||||
|
@ -66,7 +66,7 @@ containing the following fields:
|
|||
* `thumbnail` (string|boolean): relative path of the thumbnail cache file, or false if there isn't any.
|
||||
* `created` (DateTime): link creation date time.
|
||||
* `updated` (DateTime): last modification date time.
|
||||
|
||||
|
||||
Small hashes are used to make a link to an entry in Shaarli. They are unique: the date of the item (eg. `20110923_150523`) is hashed with CRC32, then converted to base64 and some characters are replaced. They are always 6 characters longs and use only `A-Z a-z 0-9 - _` and `@`.
|
||||
|
||||
|
||||
|
@ -163,11 +163,13 @@ See [`.travis.yml`](https://github.com/shaarli/Shaarli/blob/master/.travis.yml).
|
|||
|
||||
## 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-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)
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Shaarli - The personal, minimalist, super-fast, database free, bookmarking service.
|
||||
*
|
||||
|
@ -77,9 +78,9 @@
|
|||
new Languages(setlocale(LC_MESSAGES, 0), $conf);
|
||||
|
||||
$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
|
||||
|
||||
date_default_timezone_set($conf->get('general.timezone', 'UTC'));
|
||||
|
@ -177,6 +178,6 @@
|
|||
} catch (Throwable $e) {
|
||||
die(nl2br(
|
||||
'An unexpected error happened, and the error template could not be displayed.' . PHP_EOL . PHP_EOL .
|
||||
exception2text($e)
|
||||
exception2text($e)
|
||||
));
|
||||
}
|
||||
|
|
11
phpcs.xml
11
phpcs.xml
|
@ -5,13 +5,18 @@
|
|||
<file>index.php</file>
|
||||
<file>application</file>
|
||||
<file>plugins</file>
|
||||
<file>tests</file>
|
||||
<!-- <file>tests</file>-->
|
||||
|
||||
<exclude-pattern>*/*.css</exclude-pattern>
|
||||
<exclude-pattern>*/*.js</exclude-pattern>
|
||||
|
||||
<arg name="colors"/>
|
||||
|
||||
<rule ref="PSR1"/>
|
||||
<rule ref="PSR2"/>
|
||||
<rule ref="PSR12"/>
|
||||
<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>
|
||||
|
|
|
@ -17,26 +17,26 @@
|
|||
function hook_addlink_toolbar_render_header($data)
|
||||
{
|
||||
if ($data['_PAGE_'] == TemplatePage::LINKLIST && $data['_LOGGEDIN_'] === true) {
|
||||
$form = array(
|
||||
'attr' => array(
|
||||
$form = [
|
||||
'attr' => [
|
||||
'method' => 'GET',
|
||||
'action' => $data['_BASE_PATH_'] . '/admin/shaare',
|
||||
'name' => 'addform',
|
||||
'class' => 'addform',
|
||||
),
|
||||
'inputs' => array(
|
||||
array(
|
||||
],
|
||||
'inputs' => [
|
||||
[
|
||||
'type' => 'text',
|
||||
'name' => 'post',
|
||||
'placeholder' => t('URI'),
|
||||
),
|
||||
array(
|
||||
],
|
||||
[
|
||||
'type' => 'submit',
|
||||
'value' => t('Add link'),
|
||||
'class' => 'bigbutton',
|
||||
),
|
||||
),
|
||||
);
|
||||
],
|
||||
],
|
||||
];
|
||||
$data['fields_toolbar'][] = $form;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Plugin Archive.org.
|
||||
*
|
||||
|
|
|
@ -28,14 +28,14 @@ function default_colors_init($conf)
|
|||
{
|
||||
$params = [];
|
||||
foreach (DEFAULT_COLORS_PLACEHOLDERS as $placeholder) {
|
||||
$value = trim($conf->get('plugins.'. $placeholder, ''));
|
||||
$value = trim($conf->get('plugins.' . $placeholder, ''));
|
||||
if (strlen($value) > 0) {
|
||||
$params[$placeholder] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
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.');
|
||||
return [$error];
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ function default_colors_init($conf)
|
|||
function hook_default_colors_render_includes($data)
|
||||
{
|
||||
$file = PluginManager::$PLUGINS_PATH . '/default_colors/default_colors.css';
|
||||
if (file_exists($file )) {
|
||||
if (file_exists($file)) {
|
||||
$data['css_files'][] = $file ;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ function default_colors_generate_css_file($params): void
|
|||
$content = '';
|
||||
foreach (DEFAULT_COLORS_PLACEHOLDERS as $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('_', '-', strtolower($key)) .'-color';
|
||||
return ' --'. $key .': '. $data[$parameter];
|
||||
$key = str_replace('_', '-', strtolower($key)) . '-color';
|
||||
return ' --' . $key . ': ' . $data[$parameter];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Demo Plugin.
|
||||
*
|
||||
|
@ -82,14 +83,14 @@ function hook_demo_plugin_render_header($data)
|
|||
* A link is an array of its attributes (key="value"),
|
||||
* and a mandatory `html` key, which contains its value.
|
||||
*/
|
||||
$button = array(
|
||||
'attr' => array (
|
||||
$button = [
|
||||
'attr' => [
|
||||
'href' => '#',
|
||||
'class' => 'mybutton',
|
||||
'title' => 'hover me',
|
||||
),
|
||||
],
|
||||
'html' => 'DEMO buttons toolbar',
|
||||
);
|
||||
];
|
||||
$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">
|
||||
* </form>
|
||||
*/
|
||||
$form = array(
|
||||
'attr' => array(
|
||||
$form = [
|
||||
'attr' => [
|
||||
'method' => 'GET',
|
||||
'action' => $data['_BASE_PATH_'] . '/',
|
||||
'class' => 'addform',
|
||||
),
|
||||
'inputs' => array(
|
||||
array(
|
||||
],
|
||||
'inputs' => [
|
||||
[
|
||||
'type' => 'text',
|
||||
'name' => 'demo',
|
||||
'placeholder' => 'demo',
|
||||
)
|
||||
)
|
||||
);
|
||||
]
|
||||
]
|
||||
];
|
||||
$data['fields_toolbar'][] = $form;
|
||||
}
|
||||
// Another button always displayed
|
||||
$button = array(
|
||||
'attr' => array(
|
||||
$button = [
|
||||
'attr' => [
|
||||
'href' => '#',
|
||||
),
|
||||
],
|
||||
'html' => 'Demo',
|
||||
);
|
||||
];
|
||||
$data['buttons_toolbar'][] = $button;
|
||||
|
||||
return $data;
|
||||
|
@ -187,7 +188,7 @@ function hook_demo_plugin_render_includes($data)
|
|||
function hook_demo_plugin_render_footer($data)
|
||||
{
|
||||
// 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.
|
||||
$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.
|
||||
* It's also recommended to add key 'on' or 'off' for theme rendering.
|
||||
*/
|
||||
$action = array(
|
||||
'attr' => array(
|
||||
$action = [
|
||||
'attr' => [
|
||||
'href' => '?up',
|
||||
'title' => 'Uppercase!',
|
||||
),
|
||||
],
|
||||
'html' => '←',
|
||||
);
|
||||
];
|
||||
|
||||
if (isset($_GET['up'])) {
|
||||
// Manipulate link data
|
||||
|
@ -275,7 +276,7 @@ function hook_demo_plugin_render_linklist($data)
|
|||
function hook_demo_plugin_render_editlink($data)
|
||||
{
|
||||
// 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
|
||||
if (!empty($data['link']['stuff'])) {
|
||||
|
|
|
@ -19,9 +19,9 @@ function isso_init($conf)
|
|||
{
|
||||
$issoUrl = $conf->get('plugins.ISSO_SERVER');
|
||||
if (empty($issoUrl)) {
|
||||
$error = t('Isso plugin error: '.
|
||||
$error = t('Isso plugin error: ' .
|
||||
'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']);
|
||||
$data['plugin_end_zone'][] = $isso;
|
||||
} 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
|
||||
if ($conf->get('resource.theme') === 'default') {
|
||||
$button .= '<i class="linklist-plugin-icon fa fa-comment"></i>';
|
||||
} 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 .= '</a></span>';
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Piwik plugin.
|
||||
* Adds tracking code on each page.
|
||||
|
@ -22,7 +23,7 @@ function piwik_init($conf)
|
|||
if (empty($piwikUrl) || empty($piwikSiteid)) {
|
||||
$error = t('Piwik plugin error: ' .
|
||||
'Please define PIWIK_URL and PIWIK_SITEID in the plugin administration page.');
|
||||
return array($error);
|
||||
return [$error];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Plugin PlayVideos
|
||||
*
|
||||
|
@ -19,14 +20,14 @@
|
|||
function hook_playvideos_render_header($data)
|
||||
{
|
||||
if ($data['_PAGE_'] == TemplatePage::LINKLIST) {
|
||||
$playvideo = array(
|
||||
'attr' => array(
|
||||
$playvideo = [
|
||||
'attr' => [
|
||||
'href' => '#',
|
||||
'title' => t('Video player'),
|
||||
'id' => 'playvideos',
|
||||
),
|
||||
'html' => '► '. t('Play Videos')
|
||||
);
|
||||
],
|
||||
'html' => '► ' . t('Play Videos')
|
||||
];
|
||||
$data['buttons_toolbar'][] = $playvideo;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ function pubsubhubbub_init($conf)
|
|||
function hook_pubsubhubbub_render_feed($data, $conf)
|
||||
{
|
||||
$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'));
|
||||
|
||||
return $data;
|
||||
|
@ -59,10 +59,10 @@ function hook_pubsubhubbub_render_feed($data, $conf)
|
|||
*/
|
||||
function hook_pubsubhubbub_save_link($data, $conf)
|
||||
{
|
||||
$feeds = array(
|
||||
index_url($_SERVER) .'feed/atom',
|
||||
index_url($_SERVER) .'feed/rss',
|
||||
);
|
||||
$feeds = [
|
||||
index_url($_SERVER) . 'feed/atom',
|
||||
index_url($_SERVER) . 'feed/rss',
|
||||
];
|
||||
|
||||
$httpPost = function_exists('curl_version') ? false : 'nocurl_http_post';
|
||||
try {
|
||||
|
@ -87,11 +87,11 @@ function hook_pubsubhubbub_save_link($data, $conf)
|
|||
*/
|
||||
function nocurl_http_post($url, $postString)
|
||||
{
|
||||
$params = array('http' => array(
|
||||
$params = ['http' => [
|
||||
'method' => 'POST',
|
||||
'content' => $postString,
|
||||
'user_agent' => 'PubSubHubbub-Publisher-PHP/1.0',
|
||||
));
|
||||
]];
|
||||
|
||||
$context = stream_context_create($params);
|
||||
$fp = @fopen($url, 'rb', false, $context);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Plugin qrcode
|
||||
* Add QRCode containing URL for each links.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
namespace Shaarli\Plugin\Wallabag;
|
||||
|
||||
/**
|
||||
|
@ -11,20 +12,20 @@ class WallabagInstance
|
|||
* - key: version ID, must match plugin settings.
|
||||
* - value: version name.
|
||||
*/
|
||||
private static $wallabagVersions = array(
|
||||
private static $wallabagVersions = [
|
||||
1 => '1.x',
|
||||
2 => '2.x',
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array Static reference to WB endpoint according to the API version.
|
||||
* - key: version name.
|
||||
* - value: endpoint.
|
||||
*/
|
||||
private static $wallabagEndpoints = array(
|
||||
private static $wallabagEndpoints = [
|
||||
'1.x' => '?plainurl=',
|
||||
'2.x' => 'bookmarklet?url=',
|
||||
);
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string Wallabag user instance URL.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Wallabag plugin
|
||||
*/
|
||||
|
@ -18,9 +19,9 @@ function wallabag_init($conf)
|
|||
{
|
||||
$wallabagUrl = $conf->get('plugins.WALLABAG_URL');
|
||||
if (empty($wallabagUrl)) {
|
||||
$error = t('Wallabag plugin error: '.
|
||||
$error = t('Wallabag plugin error: ' .
|
||||
'Please define the "WALLABAG_URL" setting in the plugin administration page.');
|
||||
return array($error);
|
||||
return [$error];
|
||||
}
|
||||
$conf->setEmpty('plugins.WALLABAG_URL', '2');
|
||||
}
|
||||
|
|
|
@ -51,10 +51,10 @@ protected function setUp(): void
|
|||
*/
|
||||
public function testReadEmptyUpdatesFile()
|
||||
{
|
||||
$this->assertEquals(array(), UpdaterUtils::read_updates_file(''));
|
||||
$this->assertEquals(array(), UpdaterUtils::readUpdatesFile(''));
|
||||
$updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt';
|
||||
touch($updatesFile);
|
||||
$this->assertEquals(array(), UpdaterUtils::read_updates_file($updatesFile));
|
||||
$this->assertEquals(array(), UpdaterUtils::readUpdatesFile($updatesFile));
|
||||
unlink($updatesFile);
|
||||
}
|
||||
|
||||
|
@ -66,14 +66,14 @@ public function testReadWriteUpdatesFile()
|
|||
$updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt';
|
||||
$updatesMethods = array('m1', 'm2', 'm3');
|
||||
|
||||
UpdaterUtils::write_updates_file($updatesFile, $updatesMethods);
|
||||
$readMethods = UpdaterUtils::read_updates_file($updatesFile);
|
||||
UpdaterUtils::writeUpdatesFile($updatesFile, $updatesMethods);
|
||||
$readMethods = UpdaterUtils::readUpdatesFile($updatesFile);
|
||||
$this->assertEquals($readMethods, $updatesMethods);
|
||||
|
||||
// Update
|
||||
$updatesMethods[] = 'm4';
|
||||
UpdaterUtils::write_updates_file($updatesFile, $updatesMethods);
|
||||
$readMethods = UpdaterUtils::read_updates_file($updatesFile);
|
||||
UpdaterUtils::writeUpdatesFile($updatesFile, $updatesMethods);
|
||||
$readMethods = UpdaterUtils::readUpdatesFile($updatesFile);
|
||||
$this->assertEquals($readMethods, $updatesMethods);
|
||||
unlink($updatesFile);
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ public function testWriteEmptyUpdatesFile()
|
|||
$this->expectException(\Exception::class);
|
||||
$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);
|
||||
chmod($updatesFile, 0444);
|
||||
try {
|
||||
@UpdaterUtils::write_updates_file($updatesFile, array('test'));
|
||||
@UpdaterUtils::writeUpdatesFile($updatesFile, array('test'));
|
||||
} catch (Exception $e) {
|
||||
unlink($updatesFile);
|
||||
throw $e;
|
||||
|
|
|
@ -60,10 +60,10 @@ protected function setUp(): void
|
|||
*/
|
||||
public function testReadEmptyUpdatesFile()
|
||||
{
|
||||
$this->assertEquals(array(), UpdaterUtils::read_updates_file(''));
|
||||
$this->assertEquals(array(), UpdaterUtils::readUpdatesFile(''));
|
||||
$updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt';
|
||||
touch($updatesFile);
|
||||
$this->assertEquals(array(), UpdaterUtils::read_updates_file($updatesFile));
|
||||
$this->assertEquals(array(), UpdaterUtils::readUpdatesFile($updatesFile));
|
||||
unlink($updatesFile);
|
||||
}
|
||||
|
||||
|
@ -75,14 +75,14 @@ public function testReadWriteUpdatesFile()
|
|||
$updatesFile = $this->conf->get('resource.data_dir') . '/updates.txt';
|
||||
$updatesMethods = array('m1', 'm2', 'm3');
|
||||
|
||||
UpdaterUtils::write_updates_file($updatesFile, $updatesMethods);
|
||||
$readMethods = UpdaterUtils::read_updates_file($updatesFile);
|
||||
UpdaterUtils::writeUpdatesFile($updatesFile, $updatesMethods);
|
||||
$readMethods = UpdaterUtils::readUpdatesFile($updatesFile);
|
||||
$this->assertEquals($readMethods, $updatesMethods);
|
||||
|
||||
// Update
|
||||
$updatesMethods[] = 'm4';
|
||||
UpdaterUtils::write_updates_file($updatesFile, $updatesMethods);
|
||||
$readMethods = UpdaterUtils::read_updates_file($updatesFile);
|
||||
UpdaterUtils::writeUpdatesFile($updatesFile, $updatesMethods);
|
||||
$readMethods = UpdaterUtils::readUpdatesFile($updatesFile);
|
||||
$this->assertEquals($readMethods, $updatesMethods);
|
||||
unlink($updatesFile);
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ public function testWriteEmptyUpdatesFile()
|
|||
$this->expectException(\Exception::class);
|
||||
$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);
|
||||
chmod($updatesFile, 0444);
|
||||
try {
|
||||
@UpdaterUtils::write_updates_file($updatesFile, array('test'));
|
||||
@UpdaterUtils::writeUpdatesFile($updatesFile, array('test'));
|
||||
} catch (Exception $e) {
|
||||
unlink($updatesFile);
|
||||
throw $e;
|
||||
|
|
Loading…
Reference in a new issue