Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New user account type "Channel Relay" #13806

Merged
merged 33 commits into from Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
811a9f0
New user account type "Channel Relay"
annando Jan 6, 2024
aba4a48
Limited settings for the relay account type
annando Jan 6, 2024
4aedf7f
Improved code / updated messages.po
annando Jan 6, 2024
6cd0e1e
Use owner instead of author
annando Jan 7, 2024
6e830f7
Improved handling for undeterminded languages
annando Jan 7, 2024
da02df2
Simplified language check
annando Jan 7, 2024
08738e6
Improved handling of undetected languages
annando Jan 7, 2024
c4b85ef
New field "publish" for channels
annando Jan 7, 2024
d2a74d1
New option to disallow
annando Jan 7, 2024
7e8aee6
Updated messages.po
annando Jan 7, 2024
43fa224
Fix warning, when the language is invalid
annando Jan 7, 2024
5dedf5e
Execute the language detection all the time
annando Jan 8, 2024
7a680dd
Take language from quoted post
annando Jan 8, 2024
0b84e0d
Compare with lowered tags
annando Jan 9, 2024
a04dc06
Handle reshares / improved code
annando Jan 9, 2024
b2dd95a
Language check added
annando Jan 10, 2024
b48467c
Validate full search text
annando Jan 10, 2024
dfce85a
Improved performance with full text search
annando Jan 10, 2024
6155565
Code clean up
annando Jan 10, 2024
ad15b7b
Fix warning: E_WARNING: Undefined array key "publish"
annando Jan 10, 2024
43d5409
Property added
annando Jan 11, 2024
cc0b16c
Fix a problem with MySQL
annando Jan 11, 2024
62975b0
Simplify SQL check
annando Jan 11, 2024
a30b9e6
Improved handling of empty default languages
annando Jan 12, 2024
1eeef89
Link preview text and description added to search text.
annando Jan 13, 2024
98de6ad
Fix regexp for search text generation
annando Jan 13, 2024
7a13d8b
Merge remote-tracking branch 'upstream/develop' into channel-relay
annando Jan 15, 2024
9075d7f
Constant for undeterminded language
annando Jan 15, 2024
23b247d
Merge remote-tracking branch 'upstream/develop' into channel-relay
annando Jan 15, 2024
0c8c031
Merge remote-tracking branch 'upstream/develop' into channel-relay
annando Jan 15, 2024
976ec30
Merge branch 'channel-relay' of https://github.com/annando/friendica …
annando Jan 15, 2024
63b958d
Centralized functionality to store and delete the check-full-text-sea…
annando Jan 15, 2024
586a221
Merge branch 'channel-relay' of https://github.com/annando/friendica …
annando Jan 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions database.sql
@@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 2024.03-dev (Yellow Archangel)
-- DB_UPDATE_VERSION 1545
-- DB_UPDATE_VERSION 1546
-- ------------------------------------------


Expand Down Expand Up @@ -505,6 +505,8 @@ CREATE TABLE IF NOT EXISTS `channel` (
`full-text-search` varchar(1023) COMMENT 'Full text search pattern, see https://mariadb.com/kb/en/full-text-index-overview/#in-boolean-mode',
`media-type` smallint unsigned COMMENT 'Filtered media types',
`languages` mediumtext COMMENT 'Desired languages',
`publish` boolean COMMENT 'publish channel content',
`valid` boolean COMMENT 'Set, when the full-text-search is valid',
PRIMARY KEY(`id`),
INDEX `uid` (`uid`),
FOREIGN KEY (`uid`) REFERENCES `user` (`uid`) ON UPDATE RESTRICT ON DELETE CASCADE
Expand Down Expand Up @@ -1343,7 +1345,7 @@ CREATE TABLE IF NOT EXISTS `post-engagement` (
`owner-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'Item owner',
`contact-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Person, organisation, news, community, relay',
`media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio',
`language` varbinary(128) COMMENT 'Language information about this post',
`language` varchar(128) COMMENT 'Language information about this post',
`searchtext` mediumtext COMMENT 'Simplified text for the full text search',
`created` datetime COMMENT '',
`restricted` boolean NOT NULL DEFAULT '0' COMMENT 'If true, this post is either unlisted or not from a federated network',
Expand Down
2 changes: 2 additions & 0 deletions doc/database/db_channel.md
Expand Up @@ -19,6 +19,8 @@ Fields
| full-text-search | Full text search pattern, see https://mariadb.com/kb/en/full-text-index-overview/#in-boolean-mode | varchar(1023) | YES | | NULL | |
| media-type | Filtered media types | smallint unsigned | YES | | NULL | |
| languages | Desired languages | mediumtext | YES | | NULL | |
| publish | publish channel content | boolean | YES | | NULL | |
| valid | Set, when the full-text-search is valid | boolean | YES | | NULL | |

Indexes
------------
Expand Down
2 changes: 1 addition & 1 deletion doc/database/db_post-engagement.md
Expand Up @@ -12,7 +12,7 @@ Fields
| owner-id | Item owner | int unsigned | NO | | 0 | |
| contact-type | Person, organisation, news, community, relay | tinyint | NO | | 0 | |
| media-type | Type of media in a bit array (1 = image, 2 = video, 4 = audio | tinyint | NO | | 0 | |
| language | Language information about this post | varbinary(128) | YES | | NULL | |
| language | Language information about this post | varchar(128) | YES | | NULL | |
| searchtext | Simplified text for the full text search | mediumtext | YES | | NULL | |
| created | | datetime | YES | | NULL | |
| restricted | If true, this post is either unlisted or not from a federated network | boolean | NO | | 0 | |
Expand Down
10 changes: 9 additions & 1 deletion src/Content/Conversation/Entity/Timeline.php
Expand Up @@ -34,6 +34,8 @@
* @property-read int $mediaType Media types that are included in the channel
* @property-read array $languages Channel languages
* @property-read int $circle Circle or timeline this channel is based on
* @property-read bool $publish Publish the channel
* @property-read bool $valid Indicates that the search conditions are valid
*/
MrPetovan marked this conversation as resolved.
Show resolved Hide resolved
class Timeline extends \Friendica\BaseEntity
{
Expand Down Expand Up @@ -61,8 +63,12 @@
protected $mediaType;
/** @var array */
protected $languages;
/** @var bool */
protected $publish;
/** @var bool */
protected $valid;

public function __construct(string $code = null, string $label = null, string $description = null, string $accessKey = null, string $path = null, int $uid = null, string $includeTags = null, string $excludeTags = null, string $fullTextSearch = null, int $mediaType = null, int $circle = null, array $languages = null)
public function __construct(string $code = null, string $label = null, string $description = null, string $accessKey = null, string $path = null, int $uid = null, string $includeTags = null, string $excludeTags = null, string $fullTextSearch = null, int $mediaType = null, int $circle = null, array $languages = null, bool $publish = null, bool $valid = null)

Check warning on line 71 in src/Content/Conversation/Entity/Timeline.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Entity/Timeline.php#L71

Added line #L71 was not covered by tests
{
$this->code = $code;
$this->label = $label;
Expand All @@ -76,5 +82,7 @@
$this->mediaType = $mediaType;
$this->circle = $circle;
$this->languages = $languages;
$this->publish = $publish;
$this->valid = $valid;

Check warning on line 86 in src/Content/Conversation/Entity/Timeline.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Entity/Timeline.php#L85-L86

Added lines #L85 - L86 were not covered by tests
}
}
2 changes: 2 additions & 0 deletions src/Content/Conversation/Factory/UserDefinedChannel.php
Expand Up @@ -50,6 +50,8 @@
$row['media-type'] ?? null,
$row['circle'] ?? null,
$row['languages'] ?? null,
$row['publish'] ?? null,
$row['valid'] ?? null,

Check warning on line 54 in src/Content/Conversation/Factory/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Factory/UserDefinedChannel.php#L53-L54

Added lines #L53 - L54 were not covered by tests
);
}
}
199 changes: 177 additions & 22 deletions src/Content/Conversation/Repository/UserDefinedChannel.php
Expand Up @@ -25,24 +25,27 @@
use Friendica\Content\Conversation\Collection\UserDefinedChannels;
use Friendica\Content\Conversation\Entity;
use Friendica\Content\Conversation\Factory;
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Database\Database;
use Friendica\Database\DBA;
use Friendica\Model\Contact;
use Friendica\Model\Post\Engagement;
use Friendica\Model\User;
use Friendica\Util\DateTimeFormat;
use Psr\Log\LoggerInterface;

class UserDefinedChannel extends \Friendica\BaseRepository
{
protected static $table_name = 'channel';

/** @var IManagePersonalConfigValues */
private $pConfig;
/** @var IManageConfigValues */
private $config;

public function __construct(Database $database, LoggerInterface $logger, Factory\UserDefinedChannel $factory, IManagePersonalConfigValues $pConfig)
public function __construct(Database $database, LoggerInterface $logger, Factory\UserDefinedChannel $factory, IManageConfigValues $config)
{
parent::__construct($database, $logger, $factory);

$this->pConfig = $pConfig;
$this->config = $config;
}

/**
Expand All @@ -63,6 +66,11 @@
return $Entities;
}

public function select(array $condition, array $params = []): UserDefinedChannels
{
return $this->_select($condition, $params);
}

/**
* Fetch a single user channel
*
Expand Down Expand Up @@ -125,6 +133,8 @@
'full-text-search' => $Channel->fullTextSearch,
'media-type' => $Channel->mediaType,
'languages' => serialize($Channel->languages),
'publish' => $Channel->publish,
'valid' => $this->isValid($Channel->fullTextSearch),

Check warning on line 137 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L136-L137

Added lines #L136 - L137 were not covered by tests
];

if ($Channel->code) {
Expand All @@ -140,40 +150,185 @@
return $Channel;
}

private function isValid(string $searchtext): bool

Check warning on line 153 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L153

Added line #L153 was not covered by tests
{
if ($searchtext == '') {
return true;

Check warning on line 156 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L155-L156

Added lines #L155 - L156 were not covered by tests
}

return $this->db->select('check-full-text-search', [], ["`pid` = ? AND MATCH (`searchtext`) AGAINST (? IN BOOLEAN MODE)", getmypid(), $this->escapeKeywords($searchtext)]) !== false;

Check warning on line 159 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L159

Added line #L159 was not covered by tests
}

/**
* Checks, if one of the user defined channels matches with the given search text
* @todo To increase the performance, this functionality should be replaced with a single SQL call.
* Checks, if one of the user defined channels matches with the given search text or languages
*
* @param string $searchtext
* @param string $language
* @return boolean
*/
public function match(string $searchtext, string $language): bool
{
$users = $this->db->selectToArray('user', ['uid'], $this->getUserCondition());
if (empty($users)) {
return [];

Check warning on line 173 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L173

Added line #L173 was not covered by tests
}

$uids = array_column($users, 'uid');

$usercondition = ['uid' => $uids];
$condition = DBA::mergeConditions($usercondition, ["`languages` != ? AND `include-tags` = ? AND `full-text-search` = ? AND `circle` = ?", '', '', '', 0]);
foreach ($this->select($condition) as $channel) {
if (!empty($channel->languages) && in_array($language, $channel->languages)) {
return true;

Check warning on line 182 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L181-L182

Added lines #L181 - L182 were not covered by tests
}
}

$search = '';
$condition = DBA::mergeConditions($usercondition, ["`full-text-search` != ? AND `circle` = ? AND `valid`", '', 0]);
foreach ($this->select($condition) as $channel) {
$search .= '(' . $channel->fullTextSearch . ') ';

Check warning on line 189 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L189

Added line #L189 was not covered by tests
}

$this->insertCheckFullTextSearch($searchtext);
$result = $this->inFulltext($search);
$this->deleteCheckFullTextSearch();

return $result;
}

/**
* Fetch the channel users that have got matching channels
*
* @param string $searchtext
* @param string $language
* @param array $tags
* @param int $media_type
* @param int $owner_id
* @param int $reshare_id
* @return array
*/
public function getMatchingChannelUsers(string $searchtext, string $language, array $tags, int $media_type, int $owner_id, int $reshare_id): array
{
$condition = $this->getUserCondition();
$condition = DBA::mergeConditions($condition, ["`account-type` IN (?, ?) AND `uid` != ?", User::ACCOUNT_TYPE_RELAY, User::ACCOUNT_TYPE_COMMUNITY, 0]);
$users = $this->db->selectToArray('user', ['uid'], $condition);
if (empty($users)) {
return [];
}

if (!in_array($language, User::getLanguages())) {
$this->logger->debug('Unwanted language found. No matched channel found.', ['language' => $language, 'searchtext' => $searchtext]);
return false;
return [];

Check warning on line 221 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L221

Added line #L221 was not covered by tests
}

$store = false;
$this->db->insert('check-full-text-search', ['pid' => getmypid(), 'searchtext' => $searchtext], Database::INSERT_UPDATE);
$channels = $this->db->select(self::$table_name, ['full-text-search', 'uid', 'label'], ["`full-text-search` != ? AND `circle` = ?", '', 0]);
while ($channel = $this->db->fetch($channels)) {
$channelsearchtext = $channel['full-text-search'];
foreach (Engagement::KEYWORDS as $keyword) {
$channelsearchtext = preg_replace('~(' . $keyword . ':.[\w@\.-]+)~', '"$1"', $channelsearchtext);
$this->insertCheckFullTextSearch($searchtext);

Check warning on line 224 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L224

Added line #L224 was not covered by tests

$uids = [];

Check warning on line 226 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L226

Added line #L226 was not covered by tests

foreach ($this->select(['uid' => array_column($users, 'uid'), 'publish' => true, 'valid' => true]) as $channel) {
if (in_array($channel->uid, $uids)) {
continue;

Check warning on line 230 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L228-L230

Added lines #L228 - L230 were not covered by tests
}
if ($this->db->exists('check-full-text-search', ["`pid` = ? AND MATCH (`searchtext`) AGAINST (? IN BOOLEAN MODE)", getmypid(), $channelsearchtext])) {
if (in_array($language, $this->pConfig->get($channel['uid'], 'channel', 'languages', [User::getLanguageCode($channel['uid'])]))) {
$store = true;
$this->logger->debug('Matching channel found.', ['uid' => $channel['uid'], 'label' => $channel['label'], 'language' => $language, 'channelsearchtext' => $channelsearchtext, 'searchtext' => $searchtext]);
break;
if (!empty($channel->circle) && ($channel->circle > 0) && !in_array($channel->uid, $uids)) {
if (!$this->inCircle($channel->circle, $channel->uid, $owner_id) && !$this->inCircle($channel->circle, $channel->uid, $reshare_id)) {
continue;

Check warning on line 234 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L232-L234

Added lines #L232 - L234 were not covered by tests
}
}
if (!empty($channel->languages) && !in_array($channel->uid, $uids)) {
if (!in_array($language, $channel->languages)) {
continue;

Check warning on line 239 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L237-L239

Added lines #L237 - L239 were not covered by tests
}
} elseif (!in_array($language, User::getWantedLanguages($channel->uid))) {
continue;

Check warning on line 242 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L241-L242

Added lines #L241 - L242 were not covered by tests
}
if (!empty($channel->includeTags) && !in_array($channel->uid, $uids)) {
if (!$this->inTaglist($channel->includeTags, $tags)) {
continue;

Check warning on line 246 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L244-L246

Added lines #L244 - L246 were not covered by tests
}
}
if (!empty($channel->excludeTags) && !in_array($channel->uid, $uids)) {
if ($this->inTaglist($channel->excludeTags, $tags)) {
continue;

Check warning on line 251 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L249-L251

Added lines #L249 - L251 were not covered by tests
}
}
if (!empty($channel->mediaType) && !in_array($channel->uid, $uids)) {
if (!($channel->mediaType & $media_type)) {
continue;

Check warning on line 256 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L254-L256

Added lines #L254 - L256 were not covered by tests
}
}
if (!empty($channel->fullTextSearch) && !in_array($channel->uid, $uids)) {
if (!$this->inFulltext($channel->fullTextSearch)) {
continue;

Check warning on line 261 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L259-L261

Added lines #L259 - L261 were not covered by tests
}
}
$uids[] = $channel->uid;
$this->logger->debug('Matching channel found.', ['uid' => $channel->uid, 'label' => $channel->label, 'language' => $language, 'tags' => $tags, 'media_type' => $media_type, 'searchtext' => $searchtext]);

Check warning on line 265 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L264-L265

Added lines #L264 - L265 were not covered by tests
}
$this->db->close($channels);

$this->deleteCheckFullTextSearch();
return $uids;

Check warning on line 269 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L268-L269

Added lines #L268 - L269 were not covered by tests
}

private function insertCheckFullTextSearch(string $searchtext)
{
$this->db->insert('check-full-text-search', ['pid' => getmypid(), 'searchtext' => $searchtext], Database::INSERT_UPDATE);
}

private function deleteCheckFullTextSearch()
{
$this->db->delete('check-full-text-search', ['pid' => getmypid()]);
return $store;
}

private function inCircle(int $circleId, int $uid, int $cid): bool

Check warning on line 282 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L282

Added line #L282 was not covered by tests
{
if ($cid == 0) {
return false;

Check warning on line 285 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L284-L285

Added lines #L284 - L285 were not covered by tests
}

$account = Contact::selectFirstAccountUser(['id'], ['pid' => $cid, 'uid' => $uid]);
if (empty($account['id'])) {
return false;

Check warning on line 290 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L288-L290

Added lines #L288 - L290 were not covered by tests
}
return $this->db->exists('group_member', ['gid' => $circleId, 'contact-id' => $account['id']]);

Check warning on line 292 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L292

Added line #L292 was not covered by tests
}

private function inTaglist(string $tagList, array $tags): bool

Check warning on line 295 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L295

Added line #L295 was not covered by tests
{
if (empty($tags)) {
return false;

Check warning on line 298 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L297-L298

Added lines #L297 - L298 were not covered by tests
}
array_walk($tags, function (&$value) {
$value = mb_strtolower($value);
});
foreach (explode(',', $tagList) as $tag) {
if (in_array($tag, $tags)) {
return true;

Check warning on line 305 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L300-L305

Added lines #L300 - L305 were not covered by tests
}
}
return false;

Check warning on line 308 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L308

Added line #L308 was not covered by tests
}

private function inFulltext(string $fullTextSearch): bool
{
return $this->db->exists('check-full-text-search', ["`pid` = ? AND MATCH (`searchtext`) AGAINST (? IN BOOLEAN MODE)", getmypid(), $this->escapeKeywords($fullTextSearch)]);
}

private function escapeKeywords(string $fullTextSearch): string
{
foreach (Engagement::KEYWORDS as $keyword) {
$fullTextSearch = preg_replace('~(' . $keyword . ':.[\w@\.-]+)~', '"$1"', $fullTextSearch);
}
return $fullTextSearch;
}

private function getUserCondition()
{
$condition = ["`verified` AND NOT `blocked` AND NOT `account_removed` AND NOT `account_expired` AND `user`.`uid` > ?", 0];

$abandon_days = intval($this->config->get('system', 'account_abandon_days'));
if (!empty($abandon_days)) {
$condition = DBA::mergeConditions($condition, ["`last-activity` > ?", DateTimeFormat::utc('now - ' . $abandon_days . ' days')]);

Check warning on line 330 in src/Content/Conversation/Repository/UserDefinedChannel.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Conversation/Repository/UserDefinedChannel.php#L330

Added line #L330 was not covered by tests
}
return $condition;
}
}
6 changes: 5 additions & 1 deletion src/Content/Text/BBCode.php
Expand Up @@ -258,6 +258,10 @@
// Add images because of possible alt texts
if (!empty($uri_id)) {
$text = Post\Media::addAttachmentsToBody($uri_id, $text, [Post\Media::IMAGE]);

foreach (Post\Media::getByURIId($uri_id, [Post\Media::HTML]) as $media) {
$text .= ' ' . $media['name'] . ' ' . $media['description'];

Check warning on line 263 in src/Content/Text/BBCode.php

View check run for this annotation

Codecov / codecov/patch

src/Content/Text/BBCode.php#L263

Added line #L263 was not covered by tests
}
}

if (empty($text)) {
Expand All @@ -279,7 +283,7 @@
// Removes mentions, remove links from hashtags
$text = preg_replace('/[@!]\[url\=.*?\].*?\[\/url\]/ism', ' ', $text);
$text = preg_replace('/[#]\[url\=.*?\](.*?)\[\/url\]/ism', ' #$1 ', $text);
$text = preg_replace('/[@!#]?\[url.*?\[\/url\]/ism', ' ', $text);
$text = preg_replace('/[@!#]+?\[url.*?\[\/url\]/ism', ' ', $text);
$text = preg_replace("/\[url=[^\[\]]*\](.*)\[\/url\]/Usi", ' $1 ', $text);

// Convert it to plain text
Expand Down
7 changes: 6 additions & 1 deletion src/Core/L10n.php
Expand Up @@ -65,6 +65,9 @@
'zh-cn' => '简体中文',
];

/** @var string Undetermined language */
const UNDETERMINED_LANGUAGE = 'un';

/**
* A string indicating the current language used for translation:
* - Two-letter ISO 639-1 code.
Expand Down Expand Up @@ -436,7 +439,9 @@
{
$iso639 = new \Matriphe\ISO639\ISO639;

$languages = [];
// In ISO 639-2 undetermined languages have got the code "und".
// There is no official code for ISO 639-1, but "un" is not assigned to any language.
$languages = [self::UNDETERMINED_LANGUAGE => $this->t('Undetermined')];

Check warning on line 444 in src/Core/L10n.php

View check run for this annotation

Codecov / codecov/patch

src/Core/L10n.php#L444

Added line #L444 was not covered by tests

foreach ($this->getDetectableLanguages() as $code) {
$code = $this->toISO6391($code);
Expand Down
5 changes: 5 additions & 0 deletions src/Model/Contact.php
Expand Up @@ -172,6 +172,11 @@
return DBA::selectFirst('account-view', $fields, $condition, $params);
}

public static function selectFirstAccountUser(array $fields = [], array $condition = [], array $params = [])

Check warning on line 175 in src/Model/Contact.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Contact.php#L175

Added line #L175 was not covered by tests
{
return DBA::selectFirst('account-user-view', $fields, $condition, $params);

Check warning on line 177 in src/Model/Contact.php

View check run for this annotation

Codecov / codecov/patch

src/Model/Contact.php#L177

Added line #L177 was not covered by tests
}

/**
* Insert a row into the contact table
* Important: You can't use DBA::lastInsertId() after this call since it will be set to 0.
Expand Down