3 * @copyright Copyright (C) 2010-2022, the Friendica project
5 * @license GNU AGPL version 3 or any later version
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Affero General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
12 * This program 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.
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 namespace Friendica\Module\Contact;
24 use Friendica\BaseModule;
25 use Friendica\Content\Widget;
26 use Friendica\Core\Hook;
27 use Friendica\Core\Logger;
28 use Friendica\Core\Renderer;
29 use Friendica\Core\System;
30 use Friendica\Database\DBA;
33 use Friendica\Model\Contact;
34 use Friendica\Network\HTTPException;
35 use Friendica\Protocol\Activity;
36 use Friendica\Util\XML;
38 class Poke extends BaseModule
40 protected function post(array $request = [])
42 if (!local_user() || empty($this->parameters['id'])) {
43 return self::postReturn(false);
48 if (empty($_POST['verb'])) {
49 return self::postReturn(false);
52 $verb = $_POST['verb'];
54 $verbs = DI::l10n()->getPokeVerbs();
55 if (!array_key_exists($verb, $verbs)) {
56 return self::postReturn(false);
59 $activity = Activity::POKE . '#' . urlencode($verbs[$verb][0]);
61 $contact_id = intval($this->parameters['id']);
63 return self::postReturn(false);
66 Logger::info('verb ' . $verb . ' contact ' . $contact_id);
68 $contact = DBA::selectFirst('contact', ['id', 'name', 'url', 'photo'], ['id' => $this->parameters['id'], 'uid' => local_user()]);
69 if (!DBA::isResult($contact)) {
70 return self::postReturn(false);
75 $private = !empty($_POST['private']) ? Model\Item::PRIVATE : Model\Item::PUBLIC;
77 $user = Model\User::getById($a->getLoggedInUserId());
78 $allow_cid = ($private ? '<' . $contact['id']. '>' : $user['allow_cid']);
79 $allow_gid = ($private ? '' : $user['allow_gid']);
80 $deny_cid = ($private ? '' : $user['deny_cid']);
81 $deny_gid = ($private ? '' : $user['deny_gid']);
83 $actor = Contact::getById($a->getContactId());
85 $uri = Model\Item::newURI($uid);
89 $arr['guid'] = System::createUUID();
93 $arr['contact-id'] = $actor['id'];
94 $arr['owner-name'] = $actor['name'];
95 $arr['owner-link'] = $actor['url'];
96 $arr['owner-avatar'] = $actor['thumb'];
97 $arr['author-name'] = $actor['name'];
98 $arr['author-link'] = $actor['url'];
99 $arr['author-avatar'] = $actor['thumb'];
101 $arr['allow_cid'] = $allow_cid;
102 $arr['allow_gid'] = $allow_gid;
103 $arr['deny_cid'] = $deny_cid;
104 $arr['deny_gid'] = $deny_gid;
106 $arr['verb'] = $activity;
107 $arr['private'] = $private;
108 $arr['object-type'] = Activity\ObjectType::PERSON;
111 $arr['body'] = '@[url=' . $actor['url'] . ']' . $actor['name'] . '[/url]' . ' ' . $verbs[$verb][2] . ' ' . '@[url=' . $contact['url'] . ']' . $contact['name'] . '[/url]';
113 $arr['object'] = '<object><type>' . Activity\ObjectType::PERSON . '</type><title>' . XML::escape($contact['name']) . '</title><id>' . XML::escape($contact['url']) . '</id>';
114 $arr['object'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . $contact['url'] . '" />') . "\n";
116 $arr['object'] .= XML::escape('<link rel="photo" type="image/jpeg" href="' . $contact['photo'] . '" />') . "\n";
117 $arr['object'] .= '</link></object>' . "\n";
119 $result = Model\Item::insert($arr);
121 Hook::callAll('post_local_end', $arr);
123 return self::postReturn($result);
127 * Since post() is called before rawContent(), we need to be able to return a JSON response in post() directly.
129 * @param bool $success
132 private static function postReturn(bool $success)
135 notice(DI::l10n()->t('Error while sending poke, please retry.'));
138 if (DI::mode()->isAjax()) {
139 System::jsonExit(['success' => $success]);
145 protected function content(array $request = []): string
148 throw new HTTPException\UnauthorizedException(DI::l10n()->t('You must be logged in to use this module.'));
151 if (empty($this->parameters['id'])) {
152 throw new HTTPException\BadRequestException();
155 $contact = DBA::selectFirst('contact', ['id', 'url', 'name'], ['id' => $this->parameters['id'], 'uid' => local_user()]);
156 if (!DBA::isResult($contact)) {
157 throw new HTTPException\NotFoundException();
160 DI::page()['aside'] = Widget\VCard::getHTML(Model\Contact::getByURL($contact["url"], false));
163 foreach (DI::l10n()->getPokeVerbs() as $verb => $translations) {
164 if ($translations[1] !== 'NOTRANSLATION') {
165 $verbs[$verb] = $translations[1];
169 $tpl = Renderer::getMarkupTemplate('contact/poke.tpl');
170 $o = Renderer::replaceMacros($tpl,[
171 '$title' => DI::l10n()->t('Poke/Prod'),
172 '$desc' => DI::l10n()->t('poke, prod or do other things to somebody'),
173 '$id' => $contact['id'],
174 '$verb' => ['verb', DI::l10n()->t('Choose what you wish to do to recipient'), '', '', $verbs],
175 '$private' => ['private', DI::l10n()->t('Make this post private')],
176 '$loading' => DI::l10n()->t('Loading...'),
177 '$submit' => DI::l10n()->t('Submit'),