From aeb112ab5f488e4e89a9607fd043fdb9243bf6d0 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 17 Jan 2022 07:39:05 -0500 Subject: [PATCH 1/5] Fix bidi support in shared posts - Display was wrong when language direction was different between nickname and content --- src/Content/Text/BBCode.php | 4 ++-- view/templates/shared_content.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Content/Text/BBCode.php b/src/Content/Text/BBCode.php index 1f638c2f5..4c895f533 100644 --- a/src/Content/Text/BBCode.php +++ b/src/Content/Text/BBCode.php @@ -1135,7 +1135,7 @@ class BBCode case self::API: $text = ($is_quote_share? '
' : '') . '' . html_entity_decode('♲', ENT_QUOTES, 'UTF-8') . ' ' . $author_contact['addr'] . ":
\n" . - '
' . $content . '
'; + '
' . $content . '
'; break; case self::DIASPORA: if (stripos(Strings::normaliseLink($attributes['link']), 'http://twitter.com/') === 0) { @@ -1160,7 +1160,7 @@ class BBCode $headline .= DI::l10n()->t('%2$s %3$s', $attributes['link'], $mention, $attributes['posted']); $headline .= ':

' . "\n"; - $text = ($is_quote_share? '
' : '') . $headline . '
' . trim($content) . '
' . "\n"; + $text = ($is_quote_share? '
' : '') . $headline . '
' . trim($content) . '
' . "\n"; break; case self::OSTATUS: diff --git a/view/templates/shared_content.tpl b/view/templates/shared_content.tpl index 4db3b66c5..c3a808d73 100644 --- a/view/templates/shared_content.tpl +++ b/view/templates/shared_content.tpl @@ -34,5 +34,5 @@ {{/if}} -
{{$content nofilter}}
+
{{$content nofilter}}
From babbdf58e6b6351076a5940dc8817268405e5775 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 17 Jan 2022 16:46:43 -0500 Subject: [PATCH 2/5] Fix wrong default value in Module\Api\Friendica\Photo\Create::post - The underlying Model\Photo::upload doesn't accept a null value for description --- src/Model/Photo.php | 13 ++++++++++--- src/Module/Api/Friendica/Photo/Create.php | 2 +- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Model/Photo.php b/src/Model/Photo.php index 2edca9387..91d827826 100644 --- a/src/Model/Photo.php +++ b/src/Model/Photo.php @@ -973,10 +973,17 @@ class Photo } /** - * - * @param int $uid User ID - * @param array $files uploaded file array + * @param int $uid User ID + * @param array $files uploaded file array + * @param string $album + * @param string|null $allow_cid + * @param string|null $allow_gid + * @param string $deny_cid + * @param string $deny_gid + * @param string $desc + * @param string $resource_id * @return array photo record + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ public static function upload(int $uid, array $files, string $album = '', string $allow_cid = null, string $allow_gid = null, string $deny_cid = '', string $deny_gid = '', string $desc = '', string $resource_id = ''): array { diff --git a/src/Module/Api/Friendica/Photo/Create.php b/src/Module/Api/Friendica/Photo/Create.php index c207820b0..62889d328 100644 --- a/src/Module/Api/Friendica/Photo/Create.php +++ b/src/Module/Api/Friendica/Photo/Create.php @@ -55,7 +55,7 @@ class Create extends BaseApi $type = $this->getRequestValue($this->parameters, 'extension', 'json'); // input params - $desc = $this->getRequestValue($request, 'desc'); + $desc = $this->getRequestValue($request, 'desc') ?? ''; $album = $this->getRequestValue($request, 'album'); $allow_cid = $this->getRequestValue($request, 'allow_cid'); $deny_cid = $this->getRequestValue($request, 'deny_cid'); From 8143fb7cc20cc4a664591cbc71c2b188e36c19fd Mon Sep 17 00:00:00 2001 From: Philipp Date: Tue, 18 Jan 2022 00:39:20 +0100 Subject: [PATCH 3/5] Remove "include/" folder from release-list --- mods/release-list-include.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/mods/release-list-include.txt b/mods/release-list-include.txt index 2c788d9d4..24eff91c2 100644 --- a/mods/release-list-include.txt +++ b/mods/release-list-include.txt @@ -11,7 +11,6 @@ config/addon-sample.config.php config/local-sample.config.php doc/ images/ -include/ mod/ mods/ spec/ From 615c6ca6968c6880fd4c23b0ec149bc9469955ed Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 18 Jan 2022 06:35:18 +0000 Subject: [PATCH 4/5] Issue 10935: Improved "GROUP BY" handling --- src/Database/Database.php | 42 ++++++++++++++++++++++- src/Module/Api/Friendica/Photo/Create.php | 2 +- src/Module/Update/Profile.php | 33 +++++++++--------- src/Worker/Notifier.php | 23 ++----------- 4 files changed, 62 insertions(+), 38 deletions(-) diff --git a/src/Database/Database.php b/src/Database/Database.php index a812efbdb..292625bb5 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -1367,6 +1367,45 @@ class Database return $this->toArray($this->select($table, $fields, $condition, $params)); } + /** + * Escape fields, adding special treatment for "group by" handling + * + * @param array $fields + * @param array $options + * @return array + */ + private function escapeFields(array $fields, array $options) + { + // In the case of a "GROUP BY" we have to add all the ORDER fields to the fieldlist. + // This needs to done to apply the "MAX(...)" treatment from below to them. + // Otherwise MySQL would report errors. + if (!empty($options['group_by']) && !empty($options['order'])) { + foreach ($options['order'] as $key => $field) { + if (!is_int($key)) { + if (!in_array($key, $fields)) { + $fields[] = $key; + } + } else { + if (!in_array($field, $fields)) { + $fields[] = $field; + } + } + } + } + + array_walk($fields, function(&$value, $key) use ($options) + { + $field = $value; + $value = '`' . str_replace('`', '``', $value) . '`'; + + if (!empty($options['group_by']) && !in_array($field, $options['group_by'])) { + $value = 'MAX(' . $value . ') AS ' . $value; + } + }); + + return $fields; + } + /** * Select rows from a table * @@ -1403,7 +1442,8 @@ class Database } if (count($fields) > 0) { - $select_string = implode(', ', array_map([DBA::class, 'quoteIdentifier'], $fields)); + $fields = $this->escapeFields($fields, $params); + $select_string = implode(', ', $fields); } else { $select_string = '*'; } diff --git a/src/Module/Api/Friendica/Photo/Create.php b/src/Module/Api/Friendica/Photo/Create.php index 62889d328..bb3dc63b2 100644 --- a/src/Module/Api/Friendica/Photo/Create.php +++ b/src/Module/Api/Friendica/Photo/Create.php @@ -55,7 +55,7 @@ class Create extends BaseApi $type = $this->getRequestValue($this->parameters, 'extension', 'json'); // input params - $desc = $this->getRequestValue($request, 'desc') ?? ''; + $desc = $this->getRequestValue($request, 'desc', ''); $album = $this->getRequestValue($request, 'album'); $allow_cid = $this->getRequestValue($request, 'allow_cid'); $deny_cid = $this->getRequestValue($request, 'deny_cid'); diff --git a/src/Module/Update/Profile.php b/src/Module/Update/Profile.php index 22e6e4a99..b97b9f89e 100644 --- a/src/Module/Update/Profile.php +++ b/src/Module/Update/Profile.php @@ -70,32 +70,35 @@ class Profile extends BaseModule $last_updated = $last_updated_array[$last_updated_key] ?? 0; + $condition = ["`uid` = ? AND NOT `contact-blocked` AND NOT `contact-pending` + AND `visible` AND (NOT `deleted` OR `gravity` = ?) + AND `wall` " . $sql_extra, $a->getProfileOwner(), GRAVITY_ACTIVITY]; + if ($_GET['force'] && !empty($_GET['item'])) { // When the parent is provided, we only fetch this - $sql_extra4 = " AND `parent` = " . intval($_GET['item']); + $condition = DBA::mergeConditions($condition, ['parent' => $_GET['item']]); } elseif ($is_owner || !$last_updated) { // If the page user is the owner of the page we should query for unseen // items. Otherwise use a timestamp of the last succesful update request. - $sql_extra4 = " AND `unseen`"; + $condition = DBA::mergeConditions($condition, ['unseen' => true]); } else { $gmupdate = gmdate(DateTimeFormat::MYSQL, $last_updated); - $sql_extra4 = " AND `received` > '" . $gmupdate . "'"; + $condition = DBA::mergeConditions($condition, ["`received` > ?", $gmupdate]); } - $items_stmt = DBA::p( - "SELECT `parent-uri-id` AS `uri-id`, MAX(`created`), MAX(`received`) FROM `post-user-view` - WHERE `uid` = ? AND NOT `contact-blocked` AND NOT `contact-pending` - AND `visible` AND (NOT `deleted` OR `gravity` = ?) - AND `wall` $sql_extra4 $sql_extra - GROUP BY `parent-uri-id` ORDER BY `received` DESC", - $a->getProfileOwner(), - GRAVITY_ACTIVITY - ); - - if (!DBA::isResult($items_stmt)) { + $items = Post::selectToArray(['parent-uri-id', 'created', 'received'], $condition, ['group_by' => ['parent-uri-id'], 'order' => ['received' => true]]); + if (!DBA::isResult($items)) { return; } + // @todo the DBA functions should handle "SELECT field AS alias" in the future, + // so that this workaround here could be removed. + $items = array_map(function ($item) { + $item['uri-id'] = $item['parent-uri-id']; + unset($item['parent-uri-id']); + return $item; + }, $items); + // Set a time stamp for this page. We will make use of it when we // search for new items (update routine) $last_updated_array[$last_updated_key] = time(); @@ -113,8 +116,6 @@ class Profile extends BaseModule } } - $items = DBA::toArray($items_stmt); - $o .= DI::conversation()->create($items, 'profile', $a->getProfileOwner(), false, 'received', $a->getProfileOwner()); System::htmlUpdateExit($o); diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php index bb6627086..f46b1b0d9 100644 --- a/src/Worker/Notifier.php +++ b/src/Worker/Notifier.php @@ -446,26 +446,9 @@ class Notifier if ($diaspora_delivery && !$unlisted) { $batch_delivery = true; - $participants_stmt = DBA::p( - "SELECT - `batch`, `network`, `protocol`, - ANY_VALUE(`id`) AS `id`, - ANY_VALUE(`url`) AS `url`, - ANY_VALUE(`name`) AS `name` - FROM `contact` - WHERE `network` = ? - AND `batch` != '' - AND `uid` = ? - AND `rel` != ? - AND NOT `blocked` - AND NOT `pending` - AND NOT `archive` - GROUP BY `batch`, `network`, `protocol`", - Protocol::DIASPORA, - $owner['uid'], - Contact::SHARING - ); - $participants = DBA::toArray($participants_stmt); + $participants = DBA::selectToArray('contact', ['batch', 'network', 'protocol', 'id', 'url', 'name'], + ["`network` = ? AND `batch` != '' AND `uid` = ? AND `rel` != ? AND NOT `blocked` AND NOT `pending` AND NOT `archive`", Protocol::DIASPORA, $owner['uid'], Contact::SHARING], + ['group_by' => ['batch', 'network', 'protocol']]); // Fetch the participation list // The function will ensure that there are no duplicates From a46b21590d2ee40596cafb9bfaa045f4e33f49e7 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 18 Jan 2022 06:59:02 +0000 Subject: [PATCH 5/5] use "ANY_VALUE" instead of "MAX" --- src/Database/Database.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Database/Database.php b/src/Database/Database.php index 292625bb5..cc7f754ee 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -1377,7 +1377,7 @@ class Database private function escapeFields(array $fields, array $options) { // In the case of a "GROUP BY" we have to add all the ORDER fields to the fieldlist. - // This needs to done to apply the "MAX(...)" treatment from below to them. + // This needs to done to apply the "ANY_VALUE(...)" treatment from below to them. // Otherwise MySQL would report errors. if (!empty($options['group_by']) && !empty($options['order'])) { foreach ($options['order'] as $key => $field) { @@ -1399,7 +1399,7 @@ class Database $value = '`' . str_replace('`', '``', $value) . '`'; if (!empty($options['group_by']) && !in_array($field, $options['group_by'])) { - $value = 'MAX(' . $value . ') AS ' . $value; + $value = 'ANY_VALUE(' . $value . ') AS ' . $value; } });