@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
// | |||
@@ -46,8 +48,6 @@ class Avatar extends Component | |||
} | |||
/** | |||
* @param mixed $tabs | |||
* | |||
* @throws \App\Util\Exception\ClientException | |||
*/ | |||
public function onPopulateProfileSettingsTabs(Request $request, &$tabs): bool | |||
@@ -82,14 +82,20 @@ class Avatar extends Component | |||
public static function getAvatar(?int $actor_id = null): Entity\Avatar | |||
{ | |||
$actor_id = $actor_id ?: Common::userId(); | |||
return GSFile::error(NoAvatarException::class, | |||
return GSFile::error( | |||
NoAvatarException::class, | |||
$actor_id, | |||
Cache::get("avatar-{$actor_id}", | |||
Cache::get( | |||
"avatar-{$actor_id}", | |||
function () use ($actor_id) { | |||
return DB::dql('select a from Component\Avatar\Entity\Avatar a ' . | |||
'where a.actor_id = :actor_id', | |||
['actor_id' => $actor_id]); | |||
})); | |||
return DB::dql( | |||
'select a from Component\Avatar\Entity\Avatar a ' | |||
. 'where a.actor_id = :actor_id', | |||
['actor_id' => $actor_id], | |||
); | |||
}, | |||
), | |||
); | |||
} | |||
/** | |||
@@ -112,14 +118,17 @@ class Avatar extends Component | |||
*/ | |||
public static function getAvatarFileInfo(int $actor_id, string $size = 'full'): array | |||
{ | |||
$res = Cache::get("avatar-file-info-{$actor_id}-{$size}", | |||
$res = Cache::get( | |||
"avatar-file-info-{$actor_id}-{$size}", | |||
function () use ($actor_id) { | |||
return DB::dql('select f.id, f.filename, a.title, f.mimetype ' . | |||
'from App\Entity\Attachment f ' . | |||
'join Component\Avatar\Entity\Avatar a with f.id = a.attachment_id ' . | |||
'where a.actor_id = :actor_id', | |||
['actor_id' => $actor_id]); | |||
} | |||
return DB::dql( | |||
'select f.id, f.filename, a.title, f.mimetype ' | |||
. 'from App\Entity\Attachment f ' | |||
. 'join Component\Avatar\Entity\Avatar a with f.id = a.attachment_id ' | |||
. 'where a.actor_id = :actor_id', | |||
['actor_id' => $actor_id], | |||
); | |||
}, | |||
); | |||
if ($res === []) { // Avatar not found | |||
$filepath = INSTALLDIR . '/public/assets/default-avatar.svg'; | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
@@ -96,7 +98,7 @@ class Avatar extends Controller | |||
// Cropped client side | |||
$matches = []; | |||
if (!empty(preg_match('/data:([^;]*)(;(base64))?,(.*)/', $data['hidden'], $matches))) { | |||
list(, , , $encoding_user, $data_user) = $matches; | |||
[, , , $encoding_user, $data_user] = $matches; | |||
if ($encoding_user === 'base64') { | |||
$data_user = base64_decode($data_user); | |||
$tempfile = new TemporaryFile(['prefix' => 'gs-avatar']); | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
@@ -75,17 +77,11 @@ class Avatar extends Entity | |||
return $this->attachment_id; | |||
} | |||
/** | |||
* @return null|string | |||
*/ | |||
public function getTitle(): ?string | |||
{ | |||
return $this->title; | |||
} | |||
/** | |||
* @param null|string $title | |||
*/ | |||
public function setTitle(?string $title): void | |||
{ | |||
$this->title = $title; | |||
@@ -121,14 +117,12 @@ class Avatar extends Entity | |||
public function getUrl(string $size = 'full', int $type = Router::ABSOLUTE_PATH): string | |||
{ | |||
$actor_id = $this->getActorId(); | |||
return Cache::get("avatar-url-{$actor_id}-{$size}-{$type}", function () use ($actor_id, $size, $type) { | |||
return Router::url('avatar_actor', ['actor_id' => $actor_id, 'size' => $size], $type); | |||
}); | |||
return Cache::get("avatar-url-{$actor_id}-{$size}-{$type}", fn () => Router::url('avatar_actor', ['actor_id' => $actor_id, 'size' => $size], $type)); | |||
} | |||
public function getAttachment(): Attachment | |||
{ | |||
$this->attachment = $this->attachment ?? DB::findOneBy('attachment', ['id' => $this->attachment_id]); | |||
$this->attachment ??= DB::findOneBy('attachment', ['id' => $this->attachment_id]); | |||
return $this->attachment; | |||
} | |||
@@ -144,8 +138,6 @@ class Avatar extends Entity | |||
/** | |||
* Delete this avatar and kill corresponding attachment | |||
* | |||
* @return bool | |||
*/ | |||
public function delete(): bool | |||
{ | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
// | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
// | |||
@@ -46,10 +48,10 @@ class ForeignLink | |||
private int $noticesync = 1; | |||
private int $friendsync = 2; | |||
private int $profilesync = 1; | |||
private ?\DateTimeInterface $last_noticesync; | |||
private ?\DateTimeInterface $last_friendsync; | |||
private \DateTimeInterface $created; | |||
private \DateTimeInterface $modified; | |||
private ?DateTimeInterface $last_noticesync; | |||
private ?DateTimeInterface $last_friendsync; | |||
private DateTimeInterface $created; | |||
private DateTimeInterface $modified; | |||
public function setUserId(int $user_id): self | |||
{ | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
// | |||
@@ -42,8 +44,8 @@ class ForeignService | |||
private int $id; | |||
private string $name; | |||
private ?string $description; | |||
private \DateTimeInterface $created; | |||
private \DateTimeInterface $modified; | |||
private DateTimeInterface $created; | |||
private DateTimeInterface $modified; | |||
public function setId(int $id): self | |||
{ | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
// | |||
@@ -42,7 +44,7 @@ class ForeignSubscription | |||
private int $service; | |||
private int $subscriber; | |||
private int $subscribed; | |||
private \DateTimeInterface $created; | |||
private DateTimeInterface $created; | |||
public function setService(int $service): self | |||
{ | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
// | |||
@@ -43,8 +45,8 @@ class ForeignUser | |||
private int $service; | |||
private string $uri; | |||
private ?string $nickname; | |||
private \DateTimeInterface $created; | |||
private \DateTimeInterface $modified; | |||
private DateTimeInterface $created; | |||
private DateTimeInterface $modified; | |||
public function setId(int $id): self | |||
{ | |||
@@ -1,4 +1,6 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
@@ -50,100 +52,64 @@ class FreenetworkActor extends Entity | |||
private string $source; | |||
private int $actor_id; | |||
private bool $is_local; | |||
private \DateTimeInterface $created; | |||
private \DateTimeInterface $modified; | |||
private DateTimeInterface $created; | |||
private DateTimeInterface $modified; | |||
/** | |||
* @return string | |||
*/ | |||
public function getActorUri(): string | |||
{ | |||
return $this->actor_uri; | |||
} | |||
/** | |||
* @param string $actor_uri | |||
*/ | |||
public function setActorUri(string $actor_uri): void | |||
{ | |||
$this->actor_uri = $actor_uri; | |||
} | |||
/** | |||
* @return string | |||
*/ | |||
public function getSource(): string | |||
{ | |||
return $this->source; | |||
} | |||
/** | |||
* @param string $source | |||
*/ | |||
public function setSource(string $source): void | |||
{ | |||
$this->source = $source; | |||
} | |||
/** | |||
* @return int | |||
*/ | |||
public function getActorId(): int | |||
{ | |||
return $this->actor_id; | |||
} | |||
/** | |||
* @param int $actor_id | |||
*/ | |||
public function setActorId(int $actor_id): void | |||
{ | |||
$this->actor_id = $actor_id; | |||
} | |||
/** | |||
* @return bool | |||
*/ | |||
public function isIsLocal(): bool | |||
{ | |||
return $this->is_local; | |||
} | |||
/** | |||
* @param bool $is_local | |||
*/ | |||
public function setIsLocal(bool $is_local): void | |||
{ | |||
$this->is_local = $is_local; | |||
} | |||
/** | |||
* @return DateTimeInterface | |||
*/ | |||
public function getCreated(): DateTimeInterface | |||
{ | |||
return $this->created; | |||
} | |||
/** | |||
* @param DateTimeInterface $created | |||
*/ | |||
public function setCreated(DateTimeInterface $created): void | |||
{ | |||
$this->created = $created; | |||
} | |||
/** | |||
* @return DateTimeInterface | |||
*/ | |||
public function getModified(): DateTimeInterface | |||
{ | |||
return $this->modified; | |||
} | |||
/** | |||
* @param DateTimeInterface $modified | |||
*/ | |||
public function setModified(DateTimeInterface $modified): void | |||
{ | |||
$this->modified = $modified; | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
// | |||
@@ -23,4 +25,4 @@ use App\Core\Modules\Component; | |||
class FreeNetwork extends Component | |||
{ | |||
} | |||
} |
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
// | |||
@@ -29,7 +31,7 @@ class Left extends Component | |||
* | |||
* @param array $styles stylesheets path | |||
* | |||
* @return bool hook value; true means continue processing, false means stop. | |||
* @return bool hook value; true means continue processing, false means stop | |||
*/ | |||
public function onEndShowStyles(array &$styles, string $route): bool | |||
{ | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
@@ -68,68 +70,68 @@ class Link extends Component | |||
$geouri_pctencoded_regex = '(?:\%[0-9a-fA-F][0-9a-fA-F])'; | |||
$geouri_paramchar_regex = $geouri_unreserved_regex . $geouri_punreserved_regex; //FIXME: add $geouri_pctencoded_regex here so it works | |||
return '#' . | |||
'(?:^|[\s\<\>\(\)\[\]\{\}\\\'\\\";]+)(?![\@\!\#])' . | |||
'(' . | |||
'(?:' . | |||
'(?:' . //Known protocols | |||
'(?:' . | |||
'(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_COLON_DOUBLE_SLASH)) . ')://)' . | |||
'|' . | |||
'(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_SINGLE_COLON)) . '):)' . | |||
')' . | |||
'(?:[\pN\pL\-\_\+\%\~]+(?::[\pN\pL\-\_\+\%\~]+)?\@)?' . //user:pass@ | |||
'(?:' . | |||
'(?:' . | |||
'\[[\pN\pL\-\_\:\.]+(?<![\.\:])\]' . //[dns] | |||
')|(?:' . | |||
'[\pN\pL\-\_\:\.]+(?<![\.\:])' . //dns | |||
')' . | |||
')' . | |||
')' . | |||
'|(?:' . | |||
'(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_COLON_COORDINATES)) . '):' . | |||
return '#' | |||
. '(?:^|[\s\<\>\(\)\[\]\{\}\\\'\\\";]+)(?![\@\!\#])' | |||
. '(' | |||
. '(?:' | |||
. '(?:' //Known protocols | |||
. '(?:' | |||
. '(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_COLON_DOUBLE_SLASH)) . ')://)' | |||
. '|' | |||
. '(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_SINGLE_COLON)) . '):)' | |||
. ')' | |||
. '(?:[\pN\pL\-\_\+\%\~]+(?::[\pN\pL\-\_\+\%\~]+)?\@)?' //user:pass@ | |||
. '(?:' | |||
. '(?:' | |||
. '\[[\pN\pL\-\_\:\.]+(?<![\.\:])\]' //[dns] | |||
. ')|(?:' | |||
. '[\pN\pL\-\_\:\.]+(?<![\.\:])' //dns | |||
. ')' | |||
. ')' | |||
. ')' | |||
. '|(?:' | |||
. '(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_COLON_COORDINATES)) . '):' | |||
// There's an order that must be followed here too, if ;crs= is used, it must precede ;u= | |||
// Also 'crsp' (;crs=$crsp) must match $geouri_labeltext_regex | |||
// Also 'uval' (;u=$uval) must be a pnum: \-?[0-9]+ | |||
'(?:' . | |||
'(?:[0-9]+(?:\.[0-9]+)?(?:\,[0-9]+(?:\.[0-9]+)?){1,2})' . // 1(.23)?(,4(.56)){1,2} | |||
'(?:\;(?:[' . $geouri_labeltext_regex . ']+)(?:\=[' . $geouri_paramchar_regex . ']+)*)*' . | |||
')' . | |||
')' . | |||
. '(?:' | |||
. '(?:[0-9]+(?:\.[0-9]+)?(?:\,[0-9]+(?:\.[0-9]+)?){1,2})' // 1(.23)?(,4(.56)){1,2} | |||
. '(?:\;(?:[' . $geouri_labeltext_regex . ']+)(?:\=[' . $geouri_paramchar_regex . ']+)*)*' | |||
. ')' | |||
. ')' | |||
// URLs without domain name, like magnet:?xt=... | |||
'|(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_NO_DOMAIN)) . '):(?=\?))' . // zero-length lookahead requires ? after : | |||
(Common::config('linkify', 'ipv4') // Convert IPv4 addresses to hyperlinks | |||
. '|(?:(?:' . implode('|', $this->URLSchemes(self::URL_SCHEME_NO_DOMAIN)) . '):(?=\?))' // zero-length lookahead requires ? after : | |||
. (Common::config('linkify', 'ipv4') // Convert IPv4 addresses to hyperlinks | |||
? '|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' | |||
: '') . | |||
(Common::config('linkify', 'ipv6') // Convert IPv6 addresses to hyperlinks | |||
? '|(?:' . //IPv6 | |||
'\[?(?:(?:(?:[0-9A-Fa-f]{1,4}:){7}(?:(?:[0-9A-Fa-f]{1,4})|:))|(?:(?:[0-9A-Fa-f]{1,4}:){6}(?::|(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})|(?::[0-9A-Fa-f]{1,4})))|(?:(?:[0-9A-Fa-f]{1,4}:){5}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){4}(?::[0-9A-Fa-f]{1,4}){0,1}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){3}(?::[0-9A-Fa-f]{1,4}){0,2}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){2}(?::[0-9A-Fa-f]{1,4}){0,3}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:)(?::[0-9A-Fa-f]{1,4}){0,4}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?::(?::[0-9A-Fa-f]{1,4}){0,5}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))\]?(?<!:)' . | |||
')' | |||
: '') . | |||
(Common::config('linkify', 'bare_domains') | |||
? '|(?:' . //DNS | |||
'(?:[\pN\pL\-\_\+\%\~]+(?:\:[\pN\pL\-\_\+\%\~]+)?\@)?' . //user:pass@ | |||
'[\pN\pL\-\_]+(?:\.[\pN\pL\-\_]+)*\.' . | |||
: '') | |||
. (Common::config('linkify', 'ipv6') // Convert IPv6 addresses to hyperlinks | |||
? '|(?:' //IPv6 | |||
. '\[?(?:(?:(?:[0-9A-Fa-f]{1,4}:){7}(?:(?:[0-9A-Fa-f]{1,4})|:))|(?:(?:[0-9A-Fa-f]{1,4}:){6}(?::|(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})|(?::[0-9A-Fa-f]{1,4})))|(?:(?:[0-9A-Fa-f]{1,4}:){5}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){4}(?::[0-9A-Fa-f]{1,4}){0,1}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){3}(?::[0-9A-Fa-f]{1,4}){0,2}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:){2}(?::[0-9A-Fa-f]{1,4}){0,3}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:[0-9A-Fa-f]{1,4}:)(?::[0-9A-Fa-f]{1,4}){0,4}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?::(?::[0-9A-Fa-f]{1,4}){0,5}(?:(?::(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|(?:(?::[0-9A-Fa-f]{1,4}){1,2})))|(?:(?:(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})(?:\.(?:25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))\]?(?<!:)' | |||
. ')' | |||
: '') | |||
. (Common::config('linkify', 'bare_domains') | |||
? '|(?:' //DNS | |||
. '(?:[\pN\pL\-\_\+\%\~]+(?:\:[\pN\pL\-\_\+\%\~]+)?\@)?' //user:pass@ | |||
. '[\pN\pL\-\_]+(?:\.[\pN\pL\-\_]+)*\.' | |||
//tld list from http://data.iana.org/TLD/tlds-alpha-by-domain.txt, also added local, loc, and onion | |||
'(?:AC|AD|AE|AERO|AF|AG|AI|AL|AM|AN|AO|AQ|AR|ARPA|AS|ASIA|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BIZ|BJ|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CAT|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|COM|COOP|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EDU|EE|EG|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GOV|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|INFO|INT|IO|IQ|IR|IS|IT|JE|JM|JO|JOBS|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MG|MH|MIL|MK|ML|MM|MN|MO|MOBI|MP|MQ|MR|MS|MT|MU|MUSEUM|MV|MW|MX|MY|MZ|NA|NAME|NC|NE|NET|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|ORG|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PRO|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TEL|TF|TG|TH|TJ|TK|TL|TM|TN|TO|TP|TR|TRAVEL|TT|TV|TW|TZ|UA|UG|UK|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|XN--0ZWM56D|测试|XN--11B5BS3A9AJ6G|परीक्षा|XN--80AKHBYKNJ4F|испытание|XN--9T4B11YI5A|테스트|XN--DEBA0AD|טעסט|XN--G6W251D|測試|XN--HGBK6AJ7F53BBA|آزمایشی|XN--HLCJ6AYA9ESC7A|பரிட்சை|XN--JXALPDLP|δοκιμή|XN--KGBECHTV|إختبار|XN--ZCKZAH|テスト|YE|YT|YU|ZA|ZM|ZONE|ZW|local|loc|onion)' . | |||
')(?![\pN\pL\-\_])' | |||
: '') . // if common_config('linkify', 'bare_domains') is false, don't add anything here | |||
')' . | |||
'(?:' . | |||
'(?:\:\d+)?' . //:port | |||
'(?:/[' . URL_REGEX_VALID_PATH_CHARS . ']*)?' . // path | |||
'(?:\?[' . URL_REGEX_VALID_QSTRING_CHARS . ']*)?' . // ?query string | |||
'(?:\#[' . URL_REGEX_VALID_FRAGMENT_CHARS . ']*)?' . // #fragment | |||
')(?<![' . URL_REGEX_EXCLUDED_END_CHARS . '])' . | |||
')' . | |||
'#ixu'; | |||
. '(?:AC|AD|AE|AERO|AF|AG|AI|AL|AM|AN|AO|AQ|AR|ARPA|AS|ASIA|AT|AU|AW|AX|AZ|BA|BB|BD|BE|BF|BG|BH|BI|BIZ|BJ|BM|BN|BO|BR|BS|BT|BV|BW|BY|BZ|CA|CAT|CC|CD|CF|CG|CH|CI|CK|CL|CM|CN|CO|COM|COOP|CR|CU|CV|CX|CY|CZ|DE|DJ|DK|DM|DO|DZ|EC|EDU|EE|EG|ER|ES|ET|EU|FI|FJ|FK|FM|FO|FR|GA|GB|GD|GE|GF|GG|GH|GI|GL|GM|GN|GOV|GP|GQ|GR|GS|GT|GU|GW|GY|HK|HM|HN|HR|HT|HU|ID|IE|IL|IM|IN|INFO|INT|IO|IQ|IR|IS|IT|JE|JM|JO|JOBS|JP|KE|KG|KH|KI|KM|KN|KP|KR|KW|KY|KZ|LA|LB|LC|LI|LK|LR|LS|LT|LU|LV|LY|MA|MC|MD|ME|MG|MH|MIL|MK|ML|MM|MN|MO|MOBI|MP|MQ|MR|MS|MT|MU|MUSEUM|MV|MW|MX|MY|MZ|NA|NAME|NC|NE|NET|NF|NG|NI|NL|NO|NP|NR|NU|NZ|OM|ORG|PA|PE|PF|PG|PH|PK|PL|PM|PN|PR|PRO|PS|PT|PW|PY|QA|RE|RO|RS|RU|RW|SA|SB|SC|SD|SE|SG|SH|SI|SJ|SK|SL|SM|SN|SO|SR|ST|SU|SV|SY|SZ|TC|TD|TEL|TF|TG|TH|TJ|TK|TL|TM|TN|TO|TP|TR|TRAVEL|TT|TV|TW|TZ|UA|UG|UK|US|UY|UZ|VA|VC|VE|VG|VI|VN|VU|WF|WS|XN--0ZWM56D|测试|XN--11B5BS3A9AJ6G|परीक्षा|XN--80AKHBYKNJ4F|испытание|XN--9T4B11YI5A|테스트|XN--DEBA0AD|טעסט|XN--G6W251D|測試|XN--HGBK6AJ7F53BBA|آزمایشی|XN--HLCJ6AYA9ESC7A|பரிட்சை|XN--JXALPDLP|δοκιμή|XN--KGBECHTV|إختبار|XN--ZCKZAH|テスト|YE|YT|YU|ZA|ZM|ZONE|ZW|local|loc|onion)' | |||
. ')(?![\pN\pL\-\_])' | |||
: '') // if common_config('linkify', 'bare_domains') is false, don't add anything here | |||
. ')' | |||
. '(?:' | |||
. '(?:\:\d+)?' //:port | |||
. '(?:/[' . URL_REGEX_VALID_PATH_CHARS . ']*)?' // path | |||
. '(?:\?[' . URL_REGEX_VALID_QSTRING_CHARS . ']*)?' // ?query string | |||
. '(?:\#[' . URL_REGEX_VALID_FRAGMENT_CHARS . ']*)?' // #fragment | |||
. ')(?<![' . URL_REGEX_EXCLUDED_END_CHARS . '])' | |||
. ')' | |||
. '#ixu'; | |||
} | |||
const URL_SCHEME_COLON_DOUBLE_SLASH = 1; | |||
const URL_SCHEME_SINGLE_COLON = 2; | |||
const URL_SCHEME_NO_DOMAIN = 4; | |||
const URL_SCHEME_COLON_COORDINATES = 8; | |||
public const URL_SCHEME_COLON_DOUBLE_SLASH = 1; | |||
public const URL_SCHEME_SINGLE_COLON = 2; | |||
public const URL_SCHEME_NO_DOMAIN = 4; | |||
public const URL_SCHEME_COLON_COORDINATES = 8; | |||
public function URLSchemes($filter = null) | |||
{ | |||
@@ -162,13 +164,11 @@ class Link extends Component | |||
'geo' => self::URL_SCHEME_COLON_COORDINATES, | |||
]; | |||
return array_keys(array_filter($schemes, fn ($scheme) => is_null($filter) || ($scheme & $filter))); | |||
return array_keys(array_filter($schemes, fn ($scheme) => \is_null($filter) || ($scheme & $filter))); | |||
} | |||
/** | |||
* Find links in the given text and pass them to the given callback function. | |||
* | |||
* @param string $text | |||
*/ | |||
public function replaceURLs(string $text): string | |||
{ | |||
@@ -180,16 +180,13 @@ class Link extends Component | |||
* Intermediate callback for `replaceURLs()`, which helps resolve some | |||
* ambiguous link forms before passing on to the final callback. | |||
* | |||
* @param array $matches | |||
* @param callable(string $text): string $callback: return replacement text | |||
* | |||
* @return string | |||
*/ | |||
private function callbackHelper(array $matches, callable $callback): string | |||
{ | |||
$url = $matches[1]; | |||
$left = strpos($matches[0], $url); | |||
$right = $left + strlen($url); | |||
$left = mb_strpos($matches[0], $url); | |||
$right = $left + mb_strlen($url); | |||
$groupSymbolSets = [ | |||
[ | |||
@@ -214,23 +211,23 @@ class Link extends Component | |||
do { | |||
$original_url = $url; | |||
foreach ($groupSymbolSets as $groupSymbolSet) { | |||
if (substr($url, -1) == $groupSymbolSet['right']) { | |||
$group_left_count = substr_count($url, $groupSymbolSet['left']); | |||
$group_right_count = substr_count($url, $groupSymbolSet['right']); | |||
if (mb_substr($url, -1) == $groupSymbolSet['right']) { | |||
$group_left_count = mb_substr_count($url, $groupSymbolSet['left']); | |||
$group_right_count = mb_substr_count($url, $groupSymbolSet['right']); | |||
if ($group_left_count < $group_right_count) { | |||
--$right; | |||
$url = substr($url, 0, -1); | |||
$url = mb_substr($url, 0, -1); | |||
} | |||
} | |||
} | |||
if (in_array(substr($url, -1), $cannotEndWith)) { | |||
if (\in_array(mb_substr($url, -1), $cannotEndWith)) { | |||
--$right; | |||
$url = substr($url, 0, -1); | |||
$url = mb_substr($url, 0, -1); | |||
} | |||
} while ($original_url != $url); | |||
$result = $callback($url); | |||
return substr($matches[0], 0, $left) . $result . substr($matches[0], $right); | |||
return mb_substr($matches[0], 0, $left) . $result . mb_substr($matches[0], $right); | |||
} | |||
/** | |||
@@ -242,7 +239,7 @@ class Link extends Component | |||
// functions | |||
$url = htmlspecialchars_decode($url); | |||
if (strpos($url, '@') !== false && strpos($url, ':') === false && ($email = filter_var($url, FILTER_VALIDATE_EMAIL)) !== false) { | |||
if (str_contains($url, '@') && !str_contains($url, ':') && ($email = filter_var($url, \FILTER_VALIDATE_EMAIL)) !== false) { | |||
//url is an email address without the mailto: protocol | |||
$url = "mailto:{$email}"; | |||
} | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
@@ -63,8 +65,10 @@ class Posting extends Component | |||
$actor_id = $user->getId(); | |||
$to_tags = []; | |||
$tags = Cache::get("actor-circle-{$actor_id}", | |||
fn () => DB::dql('select c.tag from App\Entity\ActorCircle c where c.tagger = :tagger', ['tagger' => $actor_id])); | |||
$tags = Cache::get( | |||
"actor-circle-{$actor_id}", | |||
fn () => DB::dql('select c.tag from App\Entity\ActorCircle c where c.tagger = :tagger', ['tagger' => $actor_id]), | |||
); | |||
foreach ($tags as $t) { | |||
$t = $t['tag']; | |||
$to_tags[$t] = $t; | |||
@@ -87,7 +91,7 @@ class Posting extends Component | |||
['content', TextareaType::class, ['label' => _m('Content:'), 'data' => $initial_content, 'attr' => ['placeholder' => _m($placeholder)]]], | |||
['attachments', FileType::class, ['label' => _m('Attachments:'), 'data' => null, 'multiple' => true, 'required' => false]], | |||
]; | |||
if (count($available_content_types) > 1) { | |||
if (\count($available_content_types) > 1) { | |||
$form_params[] = ['content_type', ChoiceType::class, | |||
[ | |||
'label' => _m('Text format:'), 'multiple' => false, 'expanded' => false, | |||
@@ -121,13 +125,6 @@ class Posting extends Component | |||
* $actor_id, possibly as a reply to note $reply_to and with flag | |||
* $is_local. Sanitizes $content and $attachments | |||
* | |||
* @param Actor $actor | |||
* @param string $content | |||
* @param string $content_type | |||
* @param array $attachments | |||
* @param null|Note $reply_to | |||
* @param null|Note $repeat_of | |||
* | |||
* @throws ClientException | |||
* @throws ServerException | |||
*/ | |||
@@ -149,8 +146,8 @@ class Posting extends Component | |||
$filesize = $f->getSize(); | |||
$max_file_size = Common::config('attachments', 'file_quota'); | |||
if ($max_file_size < $filesize) { | |||
throw new ClientException(_m('No file may be larger than {quota} bytes and the file you sent was {size} bytes. ' . | |||
'Try to upload a smaller version.', ['quota' => $max_file_size, 'size' => $filesize])); | |||
throw new ClientException(_m('No file may be larger than {quota} bytes and the file you sent was {size} bytes. ' | |||
. 'Try to upload a smaller version.', ['quota' => $max_file_size, 'size' => $filesize], )); | |||
} | |||
Event::handle('EnforceUserFileQuota', [$filesize, $actor->getId()]); | |||
$processed_attachments[] = [GSFile::storeFileAsAttachment($f), $f->getClientOriginalName()]; | |||
@@ -193,11 +190,6 @@ class Posting extends Component | |||
* Get a unique representation of a file on disk | |||
* | |||
* This can be used in the future to deduplicate images by visual content | |||
* | |||
* @param string $filename | |||
* @param null|string $out_hash | |||
* | |||
* @return bool | |||
*/ | |||
public function onHashFile(string $filename, ?string &$out_hash): bool | |||
{ | |||
@@ -207,10 +199,6 @@ class Posting extends Component | |||
/** | |||
* Fill the list with allowed sizes for an attachment, to prevent potential DoS'ing by requesting thousands of different thumbnail sizes | |||
* | |||
* @param null|array $sizes | |||
* | |||
* @return bool | |||
*/ | |||
public function onGetAllowedThumbnailSizes(?array &$sizes): bool | |||
{ | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
// | |||
@@ -29,7 +31,7 @@ class Right extends Component | |||
* | |||
* @param array $styles stylesheets path | |||
* | |||
* @return bool hook value; true means continue processing, false means stop. | |||
* @return bool hook value; true means continue processing, false means stop | |||
*/ | |||
public function onEndShowStyles(array &$styles, string $route): bool | |||
{ | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
@@ -40,14 +42,12 @@ class Search extends Controller | |||
$actor_qb->select('actor')->from('App\Entity\Actor', 'actor'); | |||
Event::handle('SeachQueryAddJoins', [&$note_qb, &$actor_qb]); | |||
$notes = $actors = []; | |||
if (!is_null($note_criteria)) { | |||
if (!\is_null($note_criteria)) { | |||
$note_qb->addCriteria($note_criteria); | |||
$notes = $note_qb->getQuery()->execute(); | |||
} else { | |||
if (!is_null($actor_criteria)) { | |||
$actor_qb->addCriteria($actor_criteria); | |||
$actors = $actor_qb->getQuery()->execute(); | |||
} | |||
} elseif (!\is_null($actor_criteria)) { | |||
$actor_qb->addCriteria($actor_criteria); | |||
$actors = $actor_qb->getQuery()->execute(); | |||
} | |||
return [ | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
@@ -23,12 +25,12 @@ namespace Component\Search; | |||
use App\Core\Event; | |||
use App\Core\Form; | |||
use function App\Core\I18n\_m; | |||
use App\Core\Modules\Component; | |||
use App\Util\Exception\RedirectException; | |||
use Symfony\Component\Form\Extension\Core\Type\SubmitType; | |||
use Symfony\Component\Form\Extension\Core\Type\TextType; | |||
use Symfony\Component\HttpFoundation\Request; | |||
use function App\Core\I18n\_m; | |||
class Search extends Component | |||
{ | |||
@@ -44,7 +46,7 @@ class Search extends Component | |||
{ | |||
$form = Form::create([ | |||
['query', TextType::class, [ | |||
'attr' => ['placeholder' => _m('Search tags...')] | |||
'attr' => ['placeholder' => _m('Search tags...')], | |||
]], | |||
[$form_name = 'submit_search', SubmitType::class, | |||
[ | |||
@@ -74,7 +76,7 @@ class Search extends Component | |||
* | |||
* @param array $styles stylesheets path | |||
* | |||
* @return bool hook value; true means continue processing, false means stop. | |||
* @return bool hook value; true means continue processing, false means stop | |||
*/ | |||
public function onEndShowStyles(array &$styles, string $route): bool | |||
{ | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
@@ -27,7 +29,6 @@ use Doctrine\Common\Collections\Criteria; | |||
abstract class Parser | |||
{ | |||
/** | |||
* Merge $parts into $criteria_arr | |||
*/ | |||
@@ -74,21 +75,17 @@ abstract class Parser | |||
foreach (['&', '|', ' '] as $delimiter) { | |||
if ($input[$index] === $delimiter || $end = ($index === $lenght - 1)) { | |||
$term = substr($input, $left, $end ? null : $right - $left); | |||
$term = mb_substr($input, $left, $end ? null : $right - $left); | |||
$note_res = $actor_res = null; | |||
$ret = Event::handle('SearchCreateExpression', [$eb, $term, &$note_res, &$actor_res]); | |||
if ((is_null($note_res) && is_null($actor_res)) || $ret == Event::next) { | |||
if ((\is_null($note_res) && \is_null($actor_res)) || $ret == Event::next) { | |||
throw new ServerException("No one claimed responsibility for a match term: {$term}"); | |||
} elseif (!\is_null($note_res)) { | |||
$note_parts[] = $note_res; | |||
} elseif (!\is_null($actor_res)) { | |||
$actor_parts[] = $actor_res; | |||
} else { | |||
if (!is_null($note_res)) { | |||
$note_parts[] = $note_res; | |||
} else { | |||
if (!is_null($actor_res)) { | |||
$actor_parts[] = $actor_res; | |||
} else { | |||
throw new ServerException('Unexpected state in Search parser'); | |||
} | |||
} | |||
throw new ServerException('Unexpected state in Search parser'); | |||
} | |||
$right = $left = $index + 1; | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
namespace Component\Tag\Controller; | |||
use App\Core\Cache; | |||
@@ -19,7 +21,7 @@ class Tag extends Controller | |||
query: 'select n from note n join note_tag nt with n.id = nt.note_id where nt.canonical = :canon order by nt.created DESC, nt.note_id DESC', | |||
query_args: ['canon' => $canonical], | |||
actor: $user, | |||
page: $page | |||
page: $page, | |||
); | |||
return [ | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
// {{{ License | |||
// This file is part of GNU social - https://www.gnu.org/software/social | |||
@@ -43,13 +45,13 @@ use Doctrine\ORM\QueryBuilder; | |||
*/ | |||
class Tag extends Component | |||
{ | |||
const MAX_TAG_LENGTH = 64; | |||
const TAG_REGEX = '/(^|\\s)(#[\\pL\\pN_\\-\\.]{1,64})/u'; // Brion Vibber 2011-02-23 v2:classes/Notice.php:367 function saveTags | |||
const TAG_SLUG_REGEX = '[A-Za-z0-9]{1,64}'; | |||
public const MAX_TAG_LENGTH = 64; | |||
public const TAG_REGEX = '/(^|\\s)(#[\\pL\\pN_\\-\\.]{1,64})/u'; // Brion Vibber 2011-02-23 v2:classes/Notice.php:367 function saveTags | |||
public const TAG_SLUG_REGEX = '[A-Za-z0-9]{1,64}'; | |||
public function onAddRoute($r): bool | |||
{ | |||
$r->connect('tag', '/tag/{tag<' . self::TAG_SLUG_REGEX . '>}' , [Controller\Tag::class, 'tag']); | |||
$r->connect('tag', '/tag/{tag<' . self::TAG_SLUG_REGEX . '>}', [Controller\Tag::class, 'tag']); | |||
return Event::next; | |||
} | |||
@@ -60,7 +62,7 @@ class Tag extends Component | |||
{ | |||
$matched_tags = []; | |||
$processed_tags = false; | |||
preg_match_all(self::TAG_REGEX, $content, $matched_tags, PREG_SET_ORDER); | |||
preg_match_all(self::TAG_REGEX, $content, $matched_tags, \PREG_SET_ORDER); | |||
foreach ($matched_tags as $match) { | |||
$tag = $match[2]; | |||
$canonical_tag = self::canonicalTag($tag); | |||
@@ -87,16 +89,13 @@ class Tag extends Component | |||
public static function canonicalTag(string $tag): string | |||
{ | |||
return substr(Formatting::slugify($tag), 0, self::MAX_TAG_LENGTH); | |||
return mb_substr(Formatting::slugify($tag), 0, self::MAX_TAG_LENGTH); | |||
} | |||
/** | |||
* Populate $note_expr with an expression to match a tag, if the term looks like a tag | |||
* | |||
* $term /^(note|tag|people|actor)/ means we want to match only either a note or an actor | |||
* | |||
* @param mixed $note_expr | |||
* @param mixed $actor_expr | |||
*/ | |||
public function onSearchCreateExpression(ExpressionBuilder $eb, string $term, &$note_expr, &$actor_expr) | |||
{ | |||
@@ -1,17 +1,19 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
use App\Core\ModuleManager; | |||
use Symfony\Component\Dotenv\Dotenv; | |||
$loader = require dirname(__DIR__) . '/vendor/autoload.php'; | |||
$loader = require \dirname(__DIR__) . '/vendor/autoload.php'; | |||
// Load cached env vars if the .env.local.php file exists | |||
// Run "composer dump-env prod" to create it (requires symfony/flex >=1.2) | |||
if (\is_array($env = @include dirname(__DIR__) . '/.env.local.php') && (!isset($env['APP_ENV']) || ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? $env['APP_ENV']) === $env['APP_ENV'])) { | |||
if (\is_array($env = @include \dirname(__DIR__) . '/.env.local.php') && (!isset($env['APP_ENV']) || ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? $env['APP_ENV']) === $env['APP_ENV'])) { | |||
foreach ($env as $k => $v) { | |||
$_ENV[$k] = $_ENV[$k] ?? (isset($_SERVER[$k]) && 0 !== strpos($k, 'HTTP_') ? $_SERVER[$k] : $v); | |||
$_ENV[$k] = $_ENV[$k] ?? (isset($_SERVER[$k]) && !str_starts_with($k, 'HTTP_') ? $_SERVER[$k] : $v); | |||
} | |||
} elseif (!\class_exists(Dotenv::class)) { | |||
} elseif (!class_exists(Dotenv::class)) { | |||
throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.'); | |||
} else { | |||
// load all the .env files | |||
@@ -19,38 +21,38 @@ if (\is_array($env = @include dirname(__DIR__) . '/.env.local.php') && (!isset($ | |||
} | |||
$_SERVER += $_ENV; | |||
$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; | |||
$_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; | |||
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; | |||
define('INSTALLDIR', dirname(__DIR__)); | |||
define('SRCDIR', INSTALLDIR . '/src'); | |||
define('PUBLICDIR', INSTALLDIR . '/public'); | |||
define('GNUSOCIAL_ENGINE_NAME', 'GNU social'); | |||
$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev'; | |||
$_SERVER['APP_DEBUG'] ??= $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV']; | |||
$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], \FILTER_VALIDATE_BOOLEAN) ? '1' : '0'; | |||
\define('INSTALLDIR', \dirname(__DIR__)); | |||
\define('SRCDIR', INSTALLDIR . '/src'); | |||
\define('PUBLICDIR', INSTALLDIR . '/public'); | |||
\define('GNUSOCIAL_ENGINE_NAME', 'GNU social'); | |||
// MERGE Change to https://gnu.io/social/ | |||
define('GNUSOCIAL_PROJECT_URL', 'https://gnusocial.rocks/'); | |||
define('GNUSOCIAL_ENGINE_URL', GNUSOCIAL_PROJECT_URL); | |||
\define('GNUSOCIAL_PROJECT_URL', 'https://gnusocial.rocks/'); | |||
\define('GNUSOCIAL_ENGINE_URL', GNUSOCIAL_PROJECT_URL); | |||
// MERGE Change to https://git.gnu.io/gnu/gnu-social | |||
define('GNUSOCIAL_REPOSITORY_URL', 'https://code.undefinedhackers.net/GNUsocial/gnu-social'); | |||
\define('GNUSOCIAL_REPOSITORY_URL', 'https://code.undefinedhackers.net/GNUsocial/gnu-social'); | |||
// Current base version, major.minor.patch | |||
define('GNUSOCIAL_BASE_VERSION', '3.0.0'); | |||
\define('GNUSOCIAL_BASE_VERSION', '3.0.0'); | |||
// 'dev', 'alpha[0-9]+', 'beta[0-9]+', 'rc[0-9]+', 'release' | |||
define('GNUSOCIAL_LIFECYCLE', 'dev'); | |||
define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE); | |||
define('GNUSOCIAL_CODENAME', 'Big bang'); | |||
\define('GNUSOCIAL_LIFECYCLE', 'dev'); | |||
\define('GNUSOCIAL_VERSION', GNUSOCIAL_BASE_VERSION . '-' . GNUSOCIAL_LIFECYCLE); | |||
\define('GNUSOCIAL_CODENAME', 'Big bang'); | |||
define('MODULE_CACHE_FILE', INSTALLDIR . '/var/cache/module_manager.php'); | |||
\define('MODULE_CACHE_FILE', INSTALLDIR . '/var/cache/module_manager.php'); | |||
/** | |||
* StatusNet had this string as valid path characters: '\pN\pL\,\!\(\)\.\:\-\_\+\/\=\&\;\%\~\*\$\'\@' | |||
* Some of those characters can be troublesome when auto-linking plain text. Such as "http://some.com/)" | |||
* URL encoding should be used whenever a weird character is used, the following strings are not definitive. | |||
*/ | |||
define('URL_REGEX_VALID_PATH_CHARS', '\pN\pL\,\!\.\:\-\_\+\/\@\=\;\%\~\*\(\)'); | |||
define('URL_REGEX_VALID_QSTRING_CHARS', URL_REGEX_VALID_PATH_CHARS . '\&'); | |||
define('URL_REGEX_VALID_FRAGMENT_CHARS', URL_REGEX_VALID_QSTRING_CHARS . '\?\#'); | |||
define('URL_REGEX_EXCLUDED_END_CHARS', '\?\.\,\!\#\:\''); // don't include these if they are directly after a URL | |||
define('URL_REGEX_DOMAIN_NAME', '(?:(?!-)[A-Za-z0-9\-]{1,63}(?<!-)\.)+[A-Za-z]{2,10}'); | |||
\define('URL_REGEX_VALID_PATH_CHARS', '\pN\pL\,\!\.\:\-\_\+\/\@\=\;\%\~\*\(\)'); | |||
\define('URL_REGEX_VALID_QSTRING_CHARS', URL_REGEX_VALID_PATH_CHARS . '\&'); | |||
\define('URL_REGEX_VALID_FRAGMENT_CHARS', URL_REGEX_VALID_QSTRING_CHARS . '\?\#'); | |||
\define('URL_REGEX_EXCLUDED_END_CHARS', '\?\.\,\!\#\:\''); // don't include these if they are directly after a URL | |||
\define('URL_REGEX_DOMAIN_NAME', '(?:(?!-)[A-Za-z0-9\-]{1,63}(?<!-)\.)+[A-Za-z]{2,10}'); | |||
// Work internally in UTC | |||
date_default_timezone_set('UTC'); | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
return [ | |||
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], | |||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true], | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
require_once 'bootstrap.php'; | |||
use App\Kernel; | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
require_once 'bootstrap.php'; | |||
use App\Kernel; | |||
@@ -1,5 +1,7 @@ | |||
<?php | |||
if (file_exists(dirname(__DIR__) . '/var/cache/prod/App_KernelProdContainer.preload.php')) { | |||
require dirname(__DIR__) . '/var/cache/prod/App_KernelProdContainer.preload.php'; | |||
declare(strict_types = 1); | |||
if (file_exists(\dirname(__DIR__) . '/var/cache/prod/App_KernelProdContainer.preload.php')) { | |||
require \dirname(__DIR__) . '/var/cache/prod/App_KernelProdContainer.preload.php'; | |||
} |
@@ -1,5 +1,7 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; | |||
return function (RoutingConfigurator $routes) { | |||
@@ -1,4 +1,6 @@ | |||
<?php | |||
declare(strict_types = 1); | |||
/** | |||
* Validation class | |||
* | |||
@@ -27,35 +29,38 @@ | |||
* | |||
* @category Validate | |||
* @package Validate | |||
* | |||
* @author Tomas V.V.Cox <cox@idecnet.com> | |||
* @author Pierre-Alain Joye <pajoye@php.net> | |||
* @author Amir Mohammad Saied <amir@php.net> | |||
* @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied | |||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |||
* | |||
* @version CVS: $Id$ | |||
* @link http://pear.php.net/package/Validate | |||
* | |||
* @see http://pear.php.net/package/Validate | |||
*/ | |||
// {{{ Constants | |||
/** | |||
* Methods for common data validations | |||
*/ | |||
define('VALIDATE_NUM', '0-9'); | |||
define('VALIDATE_SPACE', '\s'); | |||
define('VALIDATE_ALPHA_LOWER', 'a-z'); | |||
define('VALIDATE_ALPHA_UPPER', 'A-Z'); | |||
define('VALIDATE_ALPHA', VALIDATE_ALPHA_LOWER . VALIDATE_ALPHA_UPPER); | |||
define('VALIDATE_EALPHA_LOWER', VALIDATE_ALPHA_LOWER . 'áéíóúýàèìòùäëïöüÿâêîôûãñõ¨åæç½ðøþß'); | |||
define('VALIDATE_EALPHA_UPPER', VALIDATE_ALPHA_UPPER . 'ÁÉÍÓÚÝÀÈÌÒÙÄËÏÖܾÂÊÎÔÛÃÑÕ¦ÅÆÇ¼ÐØÞ'); | |||
define('VALIDATE_EALPHA', VALIDATE_EALPHA_LOWER . VALIDATE_EALPHA_UPPER); | |||
define('VALIDATE_PUNCTUATION', VALIDATE_SPACE . '\.,;\:&"\'\?\!\(\)'); | |||
define('VALIDATE_NAME', VALIDATE_EALPHA . VALIDATE_SPACE . "'" . '\-'); | |||
define('VALIDATE_STREET', VALIDATE_NUM . VALIDATE_NAME . "/\\ºª\."); | |||
define('VALIDATE_ITLD_EMAILS', 1); | |||
define('VALIDATE_GTLD_EMAILS', 2); | |||
define('VALIDATE_CCTLD_EMAILS', 4); | |||
define('VALIDATE_ALL_EMAILS', 8); | |||
\define('VALIDATE_NUM', '0-9'); | |||
\define('VALIDATE_SPACE', '\s'); | |||
\define('VALIDATE_ALPHA_LOWER', 'a-z'); | |||
\define('VALIDATE_ALPHA_UPPER', 'A-Z'); | |||
\define('VALIDATE_ALPHA', VALIDATE_ALPHA_LOWER . VALIDATE_ALPHA_UPPER); | |||
\define('VALIDATE_EALPHA_LOWER', VALIDATE_ALPHA_LOWER . 'áéíóúýàèìòùäëïöüÿâêîôûãñõ¨åæç½ðøþß'); | |||
\define('VALIDATE_EALPHA_UPPER', VALIDATE_ALPHA_UPPER . 'ÁÉÍÓÚÝÀÈÌÒÙÄËÏÖܾÂÊÎÔÛÃÑÕ¦ÅÆÇ¼ÐØÞ'); | |||
\define('VALIDATE_EALPHA', VALIDATE_EALPHA_LOWER . VALIDATE_EALPHA_UPPER); | |||
\define('VALIDATE_PUNCTUATION', VALIDATE_SPACE . '\.,;\:&"\'\?\!\(\)'); | |||
\define('VALIDATE_NAME', VALIDATE_EALPHA . VALIDATE_SPACE . "'" . '\-'); | |||
\define('VALIDATE_STREET', VALIDATE_NUM . VALIDATE_NAME . '/\\ºª\\.'); | |||
\define('VALIDATE_ITLD_EMAILS', 1); | |||
\define('VALIDATE_GTLD_EMAILS', 2); | |||
\define('VALIDATE_CCTLD_EMAILS', 4); | |||
\define('VALIDATE_ALL_EMAILS', 8); | |||
// }}} | |||
/** | |||
@@ -71,14 +76,17 @@ define('VALIDATE_ALL_EMAILS', 8); | |||
* | |||
* @category Validate | |||
* @package Validate | |||
* | |||
* @author Tomas V.V.Cox <cox@idecnet.com> | |||
* @author Pierre-Alain Joye <pajoye@php.net> | |||
* @author Amir Mohammad Saied <amir@php.net> | |||
* @author Diogo Cordeiro <diogo@fc.up.pt> | |||
* @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied | |||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |||
* | |||
* @version Release: @package_version@ | |||
* @link http://pear.php.net/package/Validate | |||
* | |||
* @see http://pear.php.net/package/Validate | |||
*/ | |||
class Validate | |||
{ | |||
@@ -91,7 +99,7 @@ class Validate | |||
* | |||
* @var array $itld (International top-level domains) | |||
*/ | |||
protected static $itld = [ | |||
protected static array $itld = [ | |||
'arpa', | |||
'root', | |||
]; | |||
@@ -104,7 +112,7 @@ class Validate | |||
* | |||
* @var array $gtld (Generic top-level domains) | |||
*/ | |||
protected static $gtld = [ | |||
protected static array $gtld = [ | |||
'aero', | |||
'biz', | |||
'cat', | |||
@@ -137,7 +145,7 @@ class Validate | |||
* | |||
* @var array $cctld (Country Code Top-Level Domain) | |||
*/ | |||
protected static $cctld = [ | |||
protected static array $cctld = [ | |||
'ac', | |||
'ad', 'ae', 'af', 'ag', | |||
'ai', 'al', 'am', 'an', | |||
@@ -210,10 +218,9 @@ class Validate | |||
* | |||
* @param string $uri tag URI to validate | |||
* | |||
* @return bool true if valid tag URI, false if not | |||
* | |||
* @access private | |||
* @throws Exception | |||
* | |||
* @return bool true if valid tag URI, false if not | |||
*/ | |||
private static function uriRFC4151(string $uri): bool | |||
{ | |||
@@ -221,15 +228,15 @@ class Validate | |||
if (preg_match( | |||
'/^tag:(?<name>.*),(?<date>\d{4}-?\d{0,2}-?\d{0,2}):(?<specific>.*)(.*:)*$/', | |||
$uri, | |||
$matches | |||
$matches, | |||
)) { | |||
$date = $matches['date']; | |||
$date = $matches['date']; | |||
$date6 = strtotime($date); | |||
if ((strlen($date) == 4) && $date <= date('Y')) { | |||
if ((mb_strlen($date) == 4) && $date <= date('Y')) { | |||
$datevalid = true; | |||
} elseif ((strlen($date) == 7) && ($date6 < strtotime("now"))) { | |||
} elseif ((mb_strlen($date) == 7) && ($date6 < strtotime('now'))) { | |||
$datevalid = true; | |||
} elseif ((strlen($date) == 10) && ($date6 < strtotime("now"))) { | |||
} elseif ((mb_strlen($date) == 10) && ($date6 < strtotime('now'))) { | |||
$datevalid = true; | |||
} | |||
if (self::email($matches['name'])) { | |||
@@ -246,28 +253,28 @@ class Validate | |||
/** | |||
* Validate a number | |||
* | |||
* @param string $number Number to validate | |||
* @param array $options array where: | |||
* 'decimal' is the decimal char or false when decimal | |||
* not allowed. | |||
* i.e. ',.' to allow both ',' and '.' | |||
* 'dec_prec' Number of allowed decimals | |||
* 'min' minimum value | |||
* 'max' maximum value | |||
* @param string $number Number to validate | |||
* @param array $options array where: | |||
* 'decimal' is the decimal char or false when decimal | |||
* not allowed. | |||
* i.e. ',.' to allow both ',' and '.' | |||
* 'dec_prec' Number of allowed decimals | |||
* 'min' minimum value | |||
* 'max' maximum value | |||
* | |||
* @return bool true if valid number, false if not | |||
*/ | |||
public static function number($number, array $options = []): bool | |||
public static function number(string $number, array $options = []): bool | |||
{ | |||
$decimal = $dec_prec = $min = $max = null; | |||
if (is_array($options)) { | |||
if (\is_array($options)) { | |||
extract($options); | |||
} | |||
$dec_prec = $dec_prec ? "{1,$dec_prec}" : '+'; | |||
$dec_regex = $decimal ? "[$decimal][0-9]$dec_prec" : ''; | |||
$dec_prec = $dec_prec ? "{1,{$dec_prec}}" : '+'; | |||
$dec_regex = $decimal ? "[{$decimal}][0-9]{$dec_prec}" : ''; | |||
if (!preg_match("|^[-+]?\s*[0-9]+($dec_regex)?\$|", $number)) { | |||
if (!preg_match("|^[-+]?\\s*[0-9]+({$dec_regex})?\$|", $number)) { | |||
return false; | |||
} | |||
@@ -275,15 +282,12 @@ class Validate | |||
$number = strtr($number, $decimal, '.'); | |||
} | |||
$number = (float)str_replace(' ', '', $number); | |||
$number = (float) str_replace(' ', '', $number); | |||
if ($min !== null && $min > $number) { | |||
return false; | |||
} | |||
if ($max !== null && $max < $number) { | |||
return false; | |||
} | |||
return true; | |||
return !($max !== null && $max < $number); | |||
} | |||
/** | |||
@@ -291,29 +295,28 @@ class Validate | |||
* | |||
* @param string $string string to be converted | |||
* | |||
* @return string converted string | |||
* @return string converted string | |||
*/ | |||
private static function stringToUtf7(string $string): string | |||
{ | |||
$return = ''; | |||
$utf7 = [ | |||
$utf7 = [ | |||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', | |||
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', | |||
'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', | |||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', | |||
's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', | |||
'3', '4', '5', '6', '7', '8', '9', '+', ',' | |||
'3', '4', '5', '6', '7', '8', '9', '+', ',', | |||
]; | |||
$state = 0; | |||
if (!empty($string)) { | |||
$i = 0; | |||
while ($i <= strlen($string)) { | |||
$char = substr($string, $i, 1); | |||
while ($i <= mb_strlen($string)) { | |||
$char = mb_substr($string, $i, 1); | |||
if ($state == 0) { | |||
if ((ord($char) >= 0x7F) || (ord($char) <= 0x1F)) { | |||
if ((\ord($char) >= 0x7F) || (\ord($char) <= 0x1F)) { | |||
if ($char) { | |||
$return .= '&'; | |||
} | |||
@@ -323,13 +326,13 @@ class Validate | |||
} else { | |||
$return .= $char; | |||
} | |||
} elseif (($i == strlen($string) || | |||
!((ord($char) >= 0x7F)) || (ord($char) <= 0x1F))) { | |||
} elseif (($i == mb_strlen($string) | |||
|| !((\ord($char) >= 0x7F)) || (\ord($char) <= 0x1F))) { | |||
if ($state != 1) { | |||
if (ord($char) > 64) { | |||
if (\ord($char) > 64) { | |||
$return .= ''; | |||
} else { | |||
$return .= $utf7[ord($char)]; | |||
$return .= $utf7[\ord($char)]; | |||
} | |||
} | |||
$return .= '-'; | |||
@@ -337,23 +340,23 @@ class Validate | |||
} else { | |||
switch ($state) { | |||
case 1: | |||
$return .= $utf7[ord($char) >> 2]; | |||
$residue = (ord($char) & 0x03) << 4; | |||
$state = 2; | |||
$return .= $utf7[\ord($char) >> 2]; | |||
$residue = (\ord($char) & 0x03) << 4; | |||
$state = 2; | |||
break; | |||
case 2: | |||
$return .= $utf7[$residue | (ord($char) >> 4)]; | |||
$residue = (ord($char) & 0x0F) << 2; | |||
$state = 3; | |||
$return .= $utf7[$residue | (\ord($char) >> 4)]; | |||
$residue = (\ord($char) & 0x0F) << 2; | |||
$state = 3; | |||
break; | |||
case 3: | |||
$return .= $utf7[$residue | (ord($char) >> 6)]; | |||
$return .= $utf7[ord($char) & 0x3F]; | |||
$return .= $utf7[$residue | (\ord($char) >> 6)]; | |||
$return .= $utf7[\ord($char) & 0x3F]; | |||
$state = 1; | |||
break; | |||
} | |||
} | |||
$i++; | |||
++$i; | |||
} | |||
return $return; | |||
} | |||
@@ -363,15 +366,15 @@ class Validate | |||
/** | |||
* Validate an email according to full RFC822 (inclusive human readable part) | |||
* | |||
* @param string $email email to validate, | |||
* @param string $email email to validate, | |||
* will return the address for optional dns validation | |||
* @param array $options email() options | |||
* @param array $options email() options | |||
* | |||
* @return bool true if valid email, false if not | |||
*/ | |||
private static function emailRFC822(string &$email, array &$options): bool | |||
{ | |||
static $address = null; | |||
static $address = null; | |||
static $uncomment = null; | |||
if (!$address) { | |||
// atom = 1*<any CHAR except specials, SPACE and CTLs> | |||
@@ -416,9 +419,9 @@ class Validate | |||
// / group ; named list | |||
$address = '/^\s*(?:' . $mailbox . '|' . $group . ')$/'; | |||
$uncomment = | |||
'/((?:(?:\\\\"|[^("])*(?:' . $quoted_string . | |||
')?)*)((?<!\\\\)\((?:(?2)|.)*?(?<!\\\\)\))/'; | |||
$uncomment | |||
= '/((?:(?:\\\\"|[^("])*(?:' . $quoted_string | |||
. ')?)*)((?<!\\\\)\((?:(?2)|.)*?(?<!\\\\)\))/'; | |||
} | |||
// strip comments | |||
$email = preg_replace($uncomment, '$1 ', $email); | |||
@@ -431,27 +434,27 @@ class Validate | |||
* This function is used to make a much more proficient validation | |||
* against all types of official domain names. | |||
* | |||
* @param string $email The email address to check. | |||
* @param array $options The options for validation | |||
* @param string $email the email address to check | |||
* @param array $options The options for validation | |||
* | |||
* @return bool True if validating succeeds | |||
*/ | |||
protected static function fullTLDValidation( | |||
string $email, | |||
array $options | |||
array $options, | |||
): bool { | |||
$validate = []; | |||
if (!empty($options["VALIDATE_ITLD_EMAILS"])) { | |||
array_push($validate, 'itld'); | |||
if (!empty($options['VALIDATE_ITLD_EMAILS'])) { | |||
$validate[] = 'itld'; | |||
} | |||
if (!empty($options["VALIDATE_GTLD_EMAILS"])) { | |||
array_push($validate, 'gtld'); | |||
if (!empty($options['VALIDATE_GTLD_EMAILS'])) { | |||
$validate[] = 'gtld'; | |||
} | |||
if (!empty($options["VALIDATE_CCTLD_EMAILS"])) { | |||
array_push($validate, 'cctld'); | |||
if (!empty($options['VALIDATE_CCTLD_EMAILS'])) { | |||
$validate[] = 'cctld'; | |||
} | |||
if (count($validate) === 0) { | |||
if (\count($validate) === 0) { | |||
array_push($validate, 'itld', 'gtld', 'cctld'); | |||
} | |||
@@ -460,7 +463,7 @@ class Validate | |||
foreach ($validate as $valid) { | |||
$tmpVar = (string) $valid; | |||
$toValidate[$valid] = self::$$tmpVar; | |||
$toValidate[$valid] = self::${$tmpVar}; | |||
} | |||
$e = self::executeFullEmailValidation($email, $toValidate); | |||
@@ -474,19 +477,19 @@ class Validate | |||
* This function will execute the full email vs tld | |||
* validation using an array of tlds passed to it. | |||
* | |||
* @param string $email The email to validate. | |||
* @param array $arrayOfTLDs The array of the TLDs to validate | |||
* @param string $email the email to validate | |||
* @param array $arrayOfTLDs The array of the TLDs to validate | |||
* | |||
* @return bool true or false (Depending on if it validates or if it does not) | |||
*/ | |||
public static function executeFullEmailValidation( | |||
string $email, | |||
array $arrayOfTLDs | |||
array $arrayOfTLDs, | |||
): bool { | |||
$emailEnding = explode('.', $email); | |||
$emailEnding = $emailEnding[count($emailEnding) - 1]; | |||
$emailEnding = $emailEnding[\count($emailEnding) - 1]; | |||
foreach ($arrayOfTLDs as $validator => $keys) { | |||
if (in_array($emailEnding, $keys)) { | |||
if (\in_array($emailEnding, $keys)) { | |||
return true; | |||
} | |||
} | |||
@@ -511,18 +514,19 @@ class Validate | |||
* 'VALIDATE_CCTLD_EMAILS' => 'true', | |||
* 'VALIDATE_ITLD_EMAILS' => 'true', | |||
* ]; | |||
* | |||
* @return bool true if valid email, false if not | |||
* @param null|mixed $options | |||
* | |||
* @throws Exception | |||
* | |||
* @return bool true if valid email, false if not | |||
*/ | |||
public static function email(string $email, $options = null): bool | |||
{ | |||
$check_domain = false; | |||
$use_rfc822 = false; | |||
if (is_bool($options)) { | |||
$use_rfc822 = false; | |||
if (\is_bool($options)) { | |||
$check_domain = $options; | |||
} elseif (is_array($options)) { | |||
} elseif (\is_array($options)) { | |||
extract($options); | |||
} | |||
@@ -538,20 +542,20 @@ class Validate | |||
} | |||
if ($hasIDNA === true) { | |||
if (strpos($email, '@') !== false) { | |||
if (str_contains($email, '@')) { | |||
$tmpEmail = explode('@', $email); | |||
$domain = array_pop($tmpEmail); | |||
$domain = array_pop($tmpEmail); | |||
// Check if the domain contains characters > 127 which means | |||
// it's an idn domain name. | |||
$chars = count_chars($domain, 1); | |||
if (!empty($chars) && max(array_keys($chars)) > 127) { | |||
$idna =& Net_IDNA2::singleton(); | |||
$idna = &Net_IDNA2::singleton(); | |||
$domain = $idna->encode($domain); | |||
} | |||
array_push($tmpEmail, $domain); | |||
$email = implode('@', $tmpEmail); | |||
$tmpEmail[] = $domain; | |||
$email = implode('@', $tmpEmail); | |||
} | |||
} | |||
@@ -580,14 +584,11 @@ class Validate | |||
$&xi'; | |||
//checks if exists the domain (MX or A) | |||
if ($use_rfc822 ? self::emailRFC822($email, $options) : | |||
preg_match($regex, $email)) { | |||
if ($check_domain && function_exists('checkdnsrr')) { | |||
if ($use_rfc822 ? self::emailRFC822($email, $options) | |||
: preg_match($regex, $email)) { | |||
if ($check_domain && \function_exists('checkdnsrr')) { | |||
$domain = preg_replace('/[^-a-z.0-9]/i', '', array_pop(explode('@', $email))); | |||
if (checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A')) { | |||
return true; | |||
} | |||
return false; | |||
return (bool) (checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A')); | |||
} | |||
return true; | |||
} | |||
@@ -597,38 +598,34 @@ class Validate | |||
/** | |||
* Validate a string using the given format 'format' | |||
* | |||
* @param string $string String to validate | |||
* @param string $string String to validate | |||
* @param array|string $options Options array where: | |||
* 'format' is the format of the string | |||
* 'format' is the format of the string | |||
* Ex:VALIDATE_NUM . VALIDATE_ALPHA (see constants) | |||
* 'min_length' minimum length | |||
* 'max_length' maximum length | |||
* 'min_length' minimum length | |||
* 'max_length' maximum length | |||
* | |||
* @return bool true if valid string, false if not | |||
*/ | |||
public static function string(string $string, $options): bool | |||
{ | |||
$format = null; | |||
$format = null; | |||
$min_length = 0; | |||
$max_length = 0; | |||
if (is_array($options)) { | |||
if (\is_array($options)) { | |||
extract($options); | |||
} | |||
if ($format && !preg_match("|^[$format]*\$|s", $string)) { | |||
if ($format && !preg_match("|^[{$format}]*\$|s", $string)) { | |||
return false; | |||
} | |||
if ($min_length && strlen($string) < $min_length) { | |||
if ($min_length && mb_strlen($string) < $min_length) { | |||
return false; | |||
} | |||
if ($max_length && strlen($string) > $max_length) { | |||
return false; | |||
} | |||
return true; | |||
return !($max_length && mb_strlen($string) > $max_length); | |||
} | |||
/** | |||
@@ -651,35 +648,35 @@ class Validate | |||
* the characters ';/?:@$,' will not be accepted in the query part | |||
* if not urlencoded, refer to the option "strict'" | |||
* | |||
* @param string $url URI to validate | |||
* @param array|null $options Options used by the validation method. | |||
* key => type | |||
* 'domain_check' => boolean | |||
* Whether to check the DNS entry or not | |||
* 'allowed_schemes' => array, list of protocols | |||
* List of allowed schemes ('http', | |||
* 'ssh+svn', 'mms') | |||
* 'strict' => string the refused chars | |||
* in query and fragment parts | |||
* default: ';/?:@$,' | |||
* empty: accept all rfc2396 foreseen chars | |||
* | |||
* @return bool true if valid uri, false if not | |||
* @param string $url URI to validate | |||
* @param null|array $options Options used by the validation method. | |||
* key => type | |||
* 'domain_check' => boolean | |||
* Whether to check the DNS entry or not | |||
* 'allowed_schemes' => array, list of protocols | |||
* List of allowed schemes ('http', | |||
* 'ssh+svn', 'mms') | |||
* 'strict' => string the refused chars | |||
* in query and fragment parts | |||
* default: ';/?:@$,' | |||
* empty: accept all rfc2396 foreseen chars | |||
* | |||
* @throws Exception | |||
* | |||
* @return bool true if valid uri, false if not | |||
*/ | |||
public static function uri(string $url, ?array $options = null): bool | |||
{ | |||
$strict = ';/?:@$,'; | |||
$domain_check = false; | |||
$strict = ';/?:@$,'; | |||
$domain_check = false; | |||
$allowed_schemes = null; | |||
if (is_array($options)) { | |||
if (\is_array($options)) { | |||
extract($options); | |||
} | |||
if (is_array($allowed_schemes) && | |||
in_array("tag", $allowed_schemes) | |||
if (\is_array($allowed_schemes) | |||
&& \in_array('tag', $allowed_schemes) | |||
) { | |||
if (strpos($url, "tag:") === 0) { | |||
if (str_starts_with($url, 'tag:')) { | |||
return self::uriRFC4151($url); | |||
} | |||
} | |||
@@ -696,12 +693,12 @@ class Validate | |||
(?:\#((?:%[0-9a-f]{2}|[-a-z0-9_.!~*\'();/?:@\&=+$,])*))? # 8. fragment | |||
$&xi', | |||
$url, | |||
$matches | |||
$matches, | |||
)) { | |||
$scheme = isset($matches[1]) ? $matches[1] : ''; | |||
$authority = isset($matches[3]) ? $matches[3] : ''; | |||
if (is_array($allowed_schemes) && | |||
!in_array($scheme, $allowed_schemes) | |||
$scheme = $matches[1] ?? ''; | |||
$authority = $matches[3] ?? ''; | |||
if (\is_array($allowed_schemes) | |||
&& !\in_array($scheme, $allowed_schemes) | |||
) { | |||
return false; | |||
} | |||
@@ -712,7 +709,7 @@ class Validate | |||
return false; | |||
} | |||
} | |||
} elseif ($domain_check && function_exists('checkdnsrr')) { | |||
} elseif ($domain_check && \function_exists('checkdnsrr')) { | |||
if (!checkdnsrr($authority, 'A')) { | |||
return false; | |||
} | |||
@@ -732,65 +729,63 @@ class Validate | |||
/** | |||
* Substr | |||
* | |||
* @param string &$date Date | |||
* @param string $num Length | |||
* @param string|false $opt Unknown | |||
* | |||
* @return string | |||
* @param string &$date Date | |||
* @param string $num Length | |||
* @param false|string $opt Unknown | |||
*/ | |||
private static function substr( | |||
string &$date, | |||
string $num, | |||
$opt = false | |||
$opt = false, | |||
): string { | |||
if ( | |||
$opt | |||
&& strlen($date) >= $opt | |||
&& mb_strlen($date) >= $opt | |||
&& preg_match('/^[0-9]{' . $opt . '}/', $date, $m) | |||
) { | |||
$ret = $m[0]; | |||
} else { | |||
$ret = substr($date, 0, $num); | |||
$ret = mb_substr($date, 0, $num); | |||
} | |||
$date = substr($date, strlen($ret)); | |||
$date = mb_substr($date, mb_strlen($ret)); | |||
return $ret; | |||
} | |||
protected static function modf($val, $div) | |||
{ | |||
if (function_exists('bcmod')) { | |||
if (\function_exists('bcmod')) { | |||
return bcmod($val, $div); | |||
} elseif (function_exists('fmod')) { | |||
} elseif (\function_exists('fmod')) { | |||
return fmod($val, $div); | |||
} | |||
$r = $val / $div; | |||
$i = intval($r); | |||
return intval($val - $i * $div + .1); | |||
$i = (int) $r; | |||
return (int) ($val - $i * $div + .1); | |||
} | |||
/** | |||
* Calculates sum of product of number digits with weights | |||
* | |||
* @param string $number number string | |||
* @param array $weights reference to array of weights | |||
* @param string $number number string | |||
* @param array $weights reference to array of weights | |||
* | |||
* @return int returns product of number digits with weights | |||
*/ | |||
protected static function multWeights( | |||
string $number, | |||
array &$weights | |||
array &$weights, | |||
): int { | |||
if (!is_array($weights)) { | |||
if (!\is_array($weights)) { | |||
return -1; | |||
} | |||
$sum = 0; | |||
$count = min(count($weights), strlen($number)); | |||
$count = min(\count($weights), mb_strlen($number)); | |||
if ($count == 0) { // empty string or weights array | |||
return -1; | |||
} | |||
for ($i = 0; $i < $count; ++$i) { | |||
$sum += intval(substr($number, $i, 1)) * $weights[$i]; | |||
$sum += (int) (mb_substr($number, $i, 1)) * $weights[$i]; | |||
} | |||
return $sum; | |||
@@ -799,20 +794,20 @@ class Validate | |||
/** | |||
* Calculates control digit for a given number | |||
* | |||
* @param string $number number string | |||
* @param array $weights reference to array of weights | |||
* @param int $modulo (optionsl) number | |||
* @param int $subtract (optional) number | |||
* @param bool $allow_high (optional) true if function can return number higher than 10 | |||
* @param string $number number string | |||
* @param array $weights reference to array of weights | |||
* @param int $modulo (optionsl) number | |||
* @param int $subtract (optional) number | |||
* @param bool $allow_high (optional) true if function can return number higher than 10 | |||
* | |||
* @return int -1 calculated control number is returned | |||
* @return int -1 calculated control number is returned | |||
*/ | |||
protected static function getControlNumber( | |||
string $number, | |||
array &$weights, | |||
int $modulo = 10, | |||
int $subtract = 0, | |||
bool $allow_high = false | |||
bool $allow_high = false, | |||
): int { | |||
// calc sum | |||
$sum = self::multWeights($number, $weights); | |||
@@ -833,30 +828,29 @@ class Validate | |||
/** | |||
* Validates a number | |||
* | |||
* @param string $number number to validate | |||
* @param array $weights reference to array of weights | |||
* @param int $modulo (optional) number | |||
* @param int $subtract (optional) number | |||
* @param string $number number to validate | |||
* @param array $weights reference to array of weights | |||
* @param int $modulo (optional) number | |||
* @param int $subtract (optional) number | |||
* | |||
* @return bool true if valid, false if not | |||
* @return bool true if valid, false if not | |||
*/ | |||
protected static function checkControlNumber( | |||
string $number, | |||
array &$weights, | |||
int $modulo = 10, | |||
int $subtract = 0 | |||
): bool | |||
{ | |||
if (strlen($number) < count($weights)) { | |||
int $subtract = 0, | |||
): bool { | |||
if (mb_strlen($number) < \count($weights)) { | |||
return false; | |||
} | |||
$target_digit = substr($number, count($weights), 1); | |||
$target_digit = mb_substr($number, \count($weights), 1); | |||
$control_digit = self::getControlNumber( | |||
$number, | |||
$weights, | |||
$modulo, | |||
$subtract, | |||
($modulo > 10) | |||
($modulo > 10), | |||
); | |||
if ($control_digit == -1) { | |||
@@ -865,10 +859,7 @@ class Validate | |||
if ($target_digit === 'X' && $control_digit == 10) { | |||
return true; | |||
} | |||
if ($control_digit != $target_digit) { | |||
return false; | |||
} | |||
return true; | |||
return !($control_digit != $target_digit); | |||
} | |||
/** | |||
@@ -876,22 +867,22 @@ class Validate | |||
* assoc array in the form $var_name => $value. | |||
* Can be used on any of Validate subpackages | |||
* | |||
* @param array $data Ex: ['name' => 'toto', 'email' => 'toto@thing.info']; | |||
* @param array $data Ex: ['name' => 'toto', 'email' => 'toto@thing.info']; | |||
* @param array $val_type Contains the validation type and all parameters used in. | |||
* 'val_type' is not optional | |||
* others validations properties must have the same name as the function | |||
* parameters. | |||
* Ex: ['toto' => ['type'=>'string','format'='toto@thing.info','min_length'=>5]]; | |||
* @param bool $remove if set, the elements not listed in data will be removed | |||
* 'val_type' is not optional | |||
* others validations properties must have the same name as the function | |||
* parameters. | |||
* Ex: ['toto' => ['type'=>'string','format'='toto@thing.info','min_length'=>5]]; | |||
* @param bool $remove if set, the elements not listed in data will be removed | |||
* | |||
* @return array value name => true|false the value name comes from the data key | |||
* @return array value name => true|false the value name comes from the data key | |||