X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModule%2FSearch%2FAcl.php;h=e8b6f357d9c422280d805a922a60e4df55a28bdb;hb=dfeae25e6dd4edfd096afcb3e51d48315cba84d0;hp=07cc9cdac5516865492e2d1db4a7e1ebc17efec4;hpb=8f20e2054b7cfdfabc1ff7cca54f05925d4a049b;p=friendica.git diff --git a/src/Module/Search/Acl.php b/src/Module/Search/Acl.php index 07cc9cdac5..e8b6f357d9 100644 --- a/src/Module/Search/Acl.php +++ b/src/Module/Search/Acl.php @@ -1,22 +1,37 @@ . + * + */ namespace Friendica\Module\Search; use Friendica\BaseModule; use Friendica\Content\Widget; -use Friendica\Core\Config; use Friendica\Core\Hook; -use Friendica\Core\L10n; use Friendica\Core\Logger; use Friendica\Core\Protocol; -use Friendica\Core\Session; +use Friendica\Core\Search; use Friendica\Database\DBA; +use Friendica\DI; use Friendica\Model\Contact; -use Friendica\Model\GContact; use Friendica\Model\Item; use Friendica\Network\HTTPException; -use Friendica\Util\Network; -use Friendica\Util\Proxy as ProxyUtils; use Friendica\Util\Strings; /** @@ -26,22 +41,72 @@ use Friendica\Util\Strings; */ class Acl extends BaseModule { - public static function rawContent() + const TYPE_GLOBAL_CONTACT = 'x'; + const TYPE_MENTION_CONTACT = 'c'; + const TYPE_MENTION_GROUP = 'g'; + const TYPE_MENTION_CONTACT_GROUP = ''; + const TYPE_MENTION_FORUM = 'f'; + const TYPE_PRIVATE_MESSAGE = 'm'; + const TYPE_ANY_CONTACT = 'a'; + + public static function rawContent(array $parameters = []) { if (!local_user()) { - throw new HTTPException\UnauthorizedException(L10n::t('You must be logged in to use this module.')); + throw new HTTPException\UnauthorizedException(DI::l10n()->t('You must be logged in to use this module.')); + } + + $type = $_REQUEST['type'] ?? self::TYPE_MENTION_CONTACT_GROUP; + if ($type === self::TYPE_GLOBAL_CONTACT) { + $o = self::globalContactSearch(); + } else { + $o = self::regularContactSearch($type); + } + + echo json_encode($o); + exit; + } + + private static function globalContactSearch() + { + // autocomplete for global contact search (e.g. navbar search) + $search = Strings::escapeTags(trim($_REQUEST['search'])); + $mode = $_REQUEST['smode']; + $page = $_REQUEST['page'] ?? 1; + + $result = Search::searchContact($search, $mode, $page); + + $contacts = []; + foreach ($result as $contact) { + $contacts[] = [ + 'photo' => Contact::getMicro($contact), + 'name' => htmlspecialchars($contact['name']), + 'nick' => $contact['addr'] ?: $contact['url'], + 'network' => $contact['network'], + 'link' => $contact['url'], + 'forum' => $contact['contact-type'] == Contact::TYPE_COMMUNITY, + ]; } + $o = [ + 'start' => ($page - 1) * 20, + 'count' => 1000, + 'items' => $contacts, + ]; + + return $o; + } + + private static function regularContactSearch(string $type) + { $start = $_REQUEST['start'] ?? 0; $count = $_REQUEST['count'] ?? 100; $search = $_REQUEST['search'] ?? ''; - $type = $_REQUEST['type'] ?? ''; $conv_id = $_REQUEST['conversation'] ?? null; // For use with jquery.textcomplete for private mail completion if (!empty($_REQUEST['query'])) { if (!$type) { - $type = 'm'; + $type = self::TYPE_PRIVATE_MESSAGE; } $search = $_REQUEST['query']; } @@ -58,7 +123,7 @@ class Acl extends BaseModule // count groups and contacts $group_count = 0; - if ($type == '' || $type == 'g') { + if ($type == self::TYPE_MENTION_CONTACT_GROUP || $type == self::TYPE_MENTION_GROUP) { $r = q("SELECT COUNT(*) AS g FROM `group` WHERE NOT `deleted` AND `uid` = %d $sql_extra", intval(local_user()) ); @@ -68,45 +133,55 @@ class Acl extends BaseModule $sql_extra2 .= ' ' . Widget::unavailableNetworks(); $contact_count = 0; - if ($type == '' || $type == 'c') { - // autocomplete for editor mentions - $r = q("SELECT COUNT(*) AS c FROM `contact` - WHERE `uid` = %d AND NOT `self` AND NOT `deleted` - AND NOT `blocked` AND NOT `pending` AND NOT `archive` - AND `notify` != '' $sql_extra2", - intval(local_user()) - ); - $contact_count = (int) $r[0]['c']; - } elseif ($type == 'f') { - // autocomplete for editor mentions of forums - $r = q("SELECT COUNT(*) AS c FROM `contact` - WHERE `uid` = %d AND NOT `self` AND NOT `deleted` - AND NOT `blocked` AND NOT `pending` AND NOT `archive` - AND (`forum` OR `prv`) - AND `notify` != '' $sql_extra2", - intval(local_user()) - ); - $contact_count = (int) $r[0]['c']; - } elseif ($type == 'm') { - // autocomplete for Private Messages - $r = q("SELECT COUNT(*) AS c FROM `contact` - WHERE `uid` = %d AND NOT `self` AND NOT `deleted` - AND NOT `blocked` AND NOT `pending` AND NOT `archive` - AND `network` IN ('%s', '%s', '%s') $sql_extra2", - intval(local_user()), - DBA::escape(Protocol::ACTIVITYPUB), - DBA::escape(Protocol::DFRN), - DBA::escape(Protocol::DIASPORA) - ); - $contact_count = (int) $r[0]['c']; - } elseif ($type == 'a') { - // autocomplete for Contacts - $r = q("SELECT COUNT(*) AS c FROM `contact` - WHERE `uid` = %d AND NOT `self` - AND NOT `pending` AND NOT `deleted` $sql_extra2", - intval(local_user()) - ); - $contact_count = (int) $r[0]['c']; + switch ($type) { + case self::TYPE_MENTION_CONTACT_GROUP: + case self::TYPE_MENTION_CONTACT: + // autocomplete for editor mentions + $r = q("SELECT COUNT(*) AS c FROM `contact` + WHERE `uid` = %d AND NOT `self` AND NOT `deleted` + AND NOT `blocked` AND NOT `pending` AND NOT `archive` + AND `notify` != '' $sql_extra2", + intval(local_user()) + ); + $contact_count = (int) $r[0]['c']; + break; + + case self::TYPE_MENTION_FORUM: + // autocomplete for editor mentions of forums + $r = q("SELECT COUNT(*) AS c FROM `contact` + WHERE `uid` = %d AND NOT `self` AND NOT `deleted` + AND NOT `blocked` AND NOT `pending` AND NOT `archive` + AND (`forum` OR `prv`) + AND `notify` != '' $sql_extra2", + intval(local_user()) + ); + $contact_count = (int) $r[0]['c']; + break; + + case self::TYPE_PRIVATE_MESSAGE: + // autocomplete for Private Messages + $r = q("SELECT COUNT(*) AS c FROM `contact` + WHERE `uid` = %d AND NOT `self` AND NOT `deleted` + AND NOT `blocked` AND NOT `pending` AND NOT `archive` + AND `network` IN ('%s', '%s', '%s') $sql_extra2", + intval(local_user()), + DBA::escape(Protocol::ACTIVITYPUB), + DBA::escape(Protocol::DFRN), + DBA::escape(Protocol::DIASPORA) + ); + $contact_count = (int) $r[0]['c']; + break; + + case self::TYPE_ANY_CONTACT: + default: + // autocomplete for Contacts + $r = q("SELECT COUNT(*) AS c FROM `contact` + WHERE `uid` = %d AND NOT `self` + AND NOT `pending` AND NOT `deleted` $sql_extra2", + intval(local_user()) + ); + $contact_count = (int) $r[0]['c']; + break; } $tot = $group_count + $contact_count; @@ -114,7 +189,7 @@ class Acl extends BaseModule $groups = []; $contacts = []; - if ($type == '' || $type == 'g') { + if ($type == self::TYPE_MENTION_CONTACT_GROUP || $type == self::TYPE_MENTION_GROUP) { /// @todo We should cache this query. // This can be done when we can delete cache entries via wildcard $r = q("SELECT `group`.`id`, `group`.`name`, GROUP_CONCAT(DISTINCT `group_member`.`contact-id` SEPARATOR ',') AS uids @@ -147,79 +222,64 @@ class Acl extends BaseModule } $r = []; - if ($type == '') { - $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv`, (`prv` OR `forum`) AS `frm` FROM `contact` - WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != '' - AND NOT (`network` IN ('%s', '%s')) - $sql_extra2 - ORDER BY `name`", - intval(local_user()), - DBA::escape(Protocol::OSTATUS), - DBA::escape(Protocol::STATUSNET) - ); - } elseif ($type == 'c') { - $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact` - WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != '' - AND NOT (`network` IN ('%s')) - $sql_extra2 - ORDER BY `name`", - intval(local_user()), - DBA::escape(Protocol::STATUSNET) - ); - } elseif ($type == 'f') { - $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact` - WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != '' - AND NOT (`network` IN ('%s')) - AND (`forum` OR `prv`) - $sql_extra2 - ORDER BY `name`", - intval(local_user()), - DBA::escape(Protocol::STATUSNET) - ); - } elseif ($type == 'm') { - $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr` FROM `contact` - WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive` - AND `network` IN ('%s', '%s', '%s') - $sql_extra2 - ORDER BY `name`", - intval(local_user()), - DBA::escape(Protocol::ACTIVITYPUB), - DBA::escape(Protocol::DFRN), - DBA::escape(Protocol::DIASPORA) - ); - } elseif ($type == 'a') { - $r = q("SELECT `id`, `name`, `nick`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact` - WHERE `uid` = %d AND NOT `deleted` AND NOT `pending` AND NOT `archive` - $sql_extra2 - ORDER BY `name`", - intval(local_user()) - ); - } elseif ($type == 'x') { - // autocomplete for global contact search (e.g. navbar search) - $search = Strings::escapeTags(trim($_REQUEST['search'])); - $mode = $_REQUEST['smode']; - $page = $_REQUEST['page'] ?? 1; - - $r = self::contactAutocomplete($search, $mode, $page); - - $contacts = []; - foreach ($r as $g) { - $contacts[] = [ - 'photo' => ProxyUtils::proxifyUrl($g['photo'], false, ProxyUtils::SIZE_MICRO), - 'name' => htmlspecialchars($g['name']), - 'nick' => $g['addr'] ?: $g['url'], - 'network' => $g['network'], - 'link' => $g['url'], - 'forum' => !empty($g['community']) ? 1 : 0, - ]; - } - $o = [ - 'start' => $start, - 'count' => $count, - 'items' => $contacts, - ]; - echo json_encode($o); - exit; + switch ($type) { + case self::TYPE_MENTION_CONTACT_GROUP: + $r = q("SELECT `id`, `name`, `nick`, `avatar`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv`, (`prv` OR `forum`) AS `frm` FROM `contact` + WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != '' + AND NOT (`network` IN ('%s', '%s')) + $sql_extra2 + ORDER BY `name`", + intval(local_user()), + DBA::escape(Protocol::OSTATUS), + DBA::escape(Protocol::STATUSNET) + ); + break; + + case self::TYPE_MENTION_CONTACT: + $r = q("SELECT `id`, `name`, `nick`, `avatar`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact` + WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != '' + AND NOT (`network` IN ('%s')) + $sql_extra2 + ORDER BY `name`", + intval(local_user()), + DBA::escape(Protocol::STATUSNET) + ); + break; + + case self::TYPE_MENTION_FORUM: + $r = q("SELECT `id`, `name`, `nick`, `avatar`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv` FROM `contact` + WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive` AND `notify` != '' + AND NOT (`network` IN ('%s')) + AND (`forum` OR `prv`) + $sql_extra2 + ORDER BY `name`", + intval(local_user()), + DBA::escape(Protocol::STATUSNET) + ); + break; + + case self::TYPE_PRIVATE_MESSAGE: + $r = q("SELECT `id`, `name`, `nick`, `avatar`, `micro`, `network`, `url`, `attag`, `addr` FROM `contact` + WHERE `uid` = %d AND NOT `self` AND NOT `deleted` AND NOT `blocked` AND NOT `pending` AND NOT `archive` + AND `network` IN ('%s', '%s', '%s') + $sql_extra2 + ORDER BY `name`", + intval(local_user()), + DBA::escape(Protocol::ACTIVITYPUB), + DBA::escape(Protocol::DFRN), + DBA::escape(Protocol::DIASPORA) + ); + break; + + case self::TYPE_ANY_CONTACT: + default: + $r = q("SELECT `id`, `name`, `nick`, `avatar`, `micro`, `network`, `url`, `attag`, `addr`, `forum`, `prv`, `avatar` FROM `contact` + WHERE `uid` = %d AND NOT `deleted` AND NOT `pending` AND NOT `archive` + $sql_extra2 + ORDER BY `name`", + intval(local_user()) + ); + break; } if (DBA::isResult($r)) { @@ -227,13 +287,13 @@ class Acl extends BaseModule foreach ($r as $g) { $entry = [ 'type' => 'c', - 'photo' => ProxyUtils::proxifyUrl($g['micro'], false, ProxyUtils::SIZE_MICRO), + 'photo' => Contact::getMicro($g), 'name' => htmlspecialchars($g['name']), 'id' => intval($g['id']), 'network' => $g['network'], 'link' => $g['url'], - 'nick' => htmlentities(defaults($g, 'attag', $g['nick'])), - 'addr' => htmlentities(defaults($g, 'addr', $g['url'])), + 'nick' => htmlentities(($g['attag'] ?? '') ?: $g['nick']), + 'addr' => htmlentities(($g['addr'] ?? '') ?: $g['url']), 'forum' => !empty($g['forum']) || !empty($g['prv']) ? 1 : 0, ]; if ($entry['forum']) { @@ -283,18 +343,18 @@ class Acl extends BaseModule continue; } - $contact = Contact::getDetailsByURL($author); + $contact = Contact::getByURL($author, false, ['micro', 'name', 'id', 'network', 'nick', 'addr', 'url', 'forum', 'avatar']); if (count($contact) > 0) { $unknown_contacts[] = [ 'type' => 'c', - 'photo' => ProxyUtils::proxifyUrl($contact['micro'], false, ProxyUtils::SIZE_MICRO), + 'photo' => Contact::getMicro($contact), 'name' => htmlspecialchars($contact['name']), - 'id' => intval($contact['cid']), + 'id' => intval($contact['id']), 'network' => $contact['network'], 'link' => $contact['url'], - 'nick' => htmlentities(defaults($contact, 'nick', $contact['addr'])), - 'addr' => htmlentities(defaults($contact, 'addr', $contact['url'])), + 'nick' => htmlentities(($contact['nick'] ?? '') ?: $contact['addr']), + 'addr' => htmlentities(($contact['addr'] ?? '') ?: $contact['url']), 'forum' => $contact['forum'] ]; } @@ -324,51 +384,6 @@ class Acl extends BaseModule 'items' => $results['items'], ]; - echo json_encode($o); - exit; - } - - - /** - * Searching for global contacts for autocompletion - * - * @brief Searching for global contacts for autocompletion - * @param string $search Name or part of a name or nick - * @param string $mode Search mode (e.g. "community") - * @param int $page Page number (starts at 1) - * @return array with the search results - * @throws HTTPException\InternalServerErrorException - */ - private static function contactAutocomplete($search, $mode, int $page = 1) - { - if (Config::get('system', 'block_public') && !Session::isAuthenticated()) { - return []; - } - - // don't search if search term has less than 2 characters - if (!$search || mb_strlen($search) < 2) { - return []; - } - - if (substr($search, 0, 1) === '@') { - $search = substr($search, 1); - } - - // check if searching in the local global contact table is enabled - if (Config::get('system', 'poco_local_search')) { - $return = GContact::searchByName($search, $mode); - } else { - $p = $page > 1 ? 'p=' . $page : ''; - - $curlResult = Network::curl(get_server() . '/lsearch?' . $p . '&search=' . urlencode($search)); - if ($curlResult->isSuccess()) { - $lsearch = json_decode($curlResult->getBody(), true); - if (!empty($lsearch['results'])) { - $return = $lsearch['results']; - } - } - } - - return $return ?? []; + return $o; } }