Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
100.00% |
1 / 1 |
|
100.00% |
4 / 4 |
CRAP | |
100.00% |
24 / 24 |
| Network | |
100.00% |
1 / 1 |
|
100.00% |
4 / 4 |
5 | |
100.00% |
24 / 24 |
| public | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| home | |
100.00% |
1 / 1 |
2 | |
100.00% |
10 / 10 |
|||
| network | |
100.00% |
1 / 1 |
1 | |
100.00% |
4 / 4 |
|||
| replies | |
100.00% |
1 / 1 |
1 | |
100.00% |
6 / 6 |
|||
| 1 | <?php |
| 2 | |
| 3 | // {{{ License |
| 4 | |
| 5 | // This file is part of GNU social - https://www.gnu.org/software/social |
| 6 | // |
| 7 | // GNU social is free software: you can redistribute it and/or modify |
| 8 | // it under the terms of the GNU Affero General Public License as published by |
| 9 | // the Free Software Foundation, either version 3 of the License, or |
| 10 | // (at your option) any later version. |
| 11 | // |
| 12 | // GNU social is distributed in the hope that it will be useful, |
| 13 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | // GNU Affero General Public License for more details. |
| 16 | // |
| 17 | // You should have received a copy of the GNU Affero General Public License |
| 18 | // along with GNU social. If not, see <http://www.gnu.org/licenses/>. |
| 19 | |
| 20 | // }}} |
| 21 | |
| 22 | /** |
| 23 | * Handle network public feed |
| 24 | * |
| 25 | * @package GNUsocial |
| 26 | * @category Controller |
| 27 | * |
| 28 | * @author Hugo Sales <hugo@hsal.es> |
| 29 | * @author Eliseu Amaro <eliseu@fc.up.pt> |
| 30 | * @copyright 2020-2021 Free Software Foundation, Inc http://www.fsf.org |
| 31 | * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later |
| 32 | */ |
| 33 | |
| 34 | namespace App\Controller; |
| 35 | |
| 36 | use App\Core\Controller; |
| 37 | use App\Core\DB\DB; |
| 38 | use App\Core\Event; |
| 39 | use function App\Core\I18n\_m; |
| 40 | use App\Core\VisibilityScope; |
| 41 | use App\Entity\Note; |
| 42 | use App\Util\Common; |
| 43 | use App\Util\Exception\ClientException; |
| 44 | use App\Util\Exception\NotFoundException; |
| 45 | use Symfony\Component\HttpFoundation\Request; |
| 46 | |
| 47 | class Network extends Controller |
| 48 | { |
| 49 | // Can't have constants inside herestring |
| 50 | private $public_scope = VisibilityScope::PUBLIC; |
| 51 | private $instance_scope = VisibilityScope::PUBLIC | VisibilityScope::SITE; |
| 52 | private $message_scope = VisibilityScope::MESSAGE; |
| 53 | private $follower_scope = VisibilityScope::PUBLIC | VisibilityScope::FOLLOWER; |
| 54 | |
| 55 | public function public(Request $request) |
| 56 | { |
| 57 | $notes = Note::getAllNotes($this->instance_scope); |
| 58 | |
| 59 | Event::handle('FormatNoteList', [$notes, &$notes_out]); |
| 60 | |
| 61 | return [ |
| 62 | '_template' => 'network/public.html.twig', |
| 63 | 'notes' => $notes_out, |
| 64 | ]; |
| 65 | } |
| 66 | |
| 67 | public function home(Request $request, string $nickname) |
| 68 | { |
| 69 | try { |
| 70 | $target = DB::findOneBy('gsactor', ['nickname' => $nickname]); |
| 71 | } catch (NotFoundException) { |
| 72 | throw new ClientException(_m('User {nickname} doesn\'t exist', ['{nickname}' => $nickname])); |
| 73 | } |
| 74 | |
| 75 | $query = <<<END |
| 76 | -- Select notes from: |
| 77 | select note.* from note left join -- left join ensures all returned notes' ids are not null |
| 78 | ( |
| 79 | -- Followed by target |
| 80 | select n.id from note n inner join follow f on n.gsactor_id = f.followed |
| 81 | where f.follower = :target_actor_id |
| 82 | union all |
| 83 | -- Replies to notes by target |
| 84 | select n.id from note n inner join note nr on nr.id = nr.reply_to |
| 85 | union all |
| 86 | -- Notifications to target |
| 87 | select a.activity_id from notification a inner join note n on a.activity_id = n.id |
| 88 | union all |
| 89 | -- Notes in groups target follows |
| 90 | select gi.activity_id from group_inbox gi inner join group_member gm on gi.group_id = gm.group_id |
| 91 | where gm.gsactor_id = :target_actor_id |
| 92 | ) |
| 93 | as s on s.id = note.id |
| 94 | where |
| 95 | -- Remove direct messages |
| 96 | note.scope <> {$this->message_scope} |
| 97 | order by note.modified DESC |
| 98 | END; |
| 99 | $notes = DB::sql($query, ['note' => 'App\Entity\Note'], ['target_actor_id' => $target->getId()]); |
| 100 | |
| 101 | Event::handle('FormatNoteList', [$notes, &$notes_out]); |
| 102 | |
| 103 | return [ |
| 104 | '_template' => 'network/public.html.twig', |
| 105 | 'notes' => $notes_out, |
| 106 | ]; |
| 107 | } |
| 108 | |
| 109 | public function network(Request $request) |
| 110 | { |
| 111 | $notes = Note::getAllNotes($this->public_scope); |
| 112 | |
| 113 | Event::handle('FormatNoteList', [$notes, &$notes_out]); |
| 114 | |
| 115 | return [ |
| 116 | '_template' => 'network/public.html.twig', |
| 117 | 'notes' => $notes_out, |
| 118 | ]; |
| 119 | } |
| 120 | |
| 121 | public function replies(Request $request) |
| 122 | { |
| 123 | $actor_id = Common::ensureLoggedIn()->getId(); |
| 124 | $notes = DB::dql('select n from App\Entity\Note n ' . |
| 125 | 'where n.reply_to is not null and n.gsactor_id = :id ' . |
| 126 | 'order by n.created DESC', ['id' => $actor_id]); |
| 127 | |
| 128 | Event::handle('FormatNoteList', [$notes, &$notes_out]); |
| 129 | |
| 130 | return [ |
| 131 | '_template' => 'network/public.html.twig', |
| 132 | 'notes' => $notes_out, |
| 133 | ]; |
| 134 | } |
| 135 | } |