]> git.mxchange.org Git - friendica.git/blob - mod/follow.php
Remove dependency to App in Contact::createFromProbe
[friendica.git] / mod / follow.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2020, Friendica
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
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.
11  *
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.
16  *
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/>.
19  *
20  */
21
22 use Friendica\App;
23 use Friendica\Core\Protocol;
24 use Friendica\Core\Renderer;
25 use Friendica\DI;
26 use Friendica\Model\Contact;
27 use Friendica\Model\Profile;
28 use Friendica\Model\Item;
29 use Friendica\Network\Probe;
30 use Friendica\Database\DBA;
31 use Friendica\Util\Strings;
32
33 function follow_post(App $a)
34 {
35         if (!local_user()) {
36                 throw new \Friendica\Network\HTTPException\ForbiddenException(DI::l10n()->t('Access denied.'));
37         }
38
39         if (isset($_REQUEST['cancel'])) {
40                 DI::baseUrl()->redirect('contact');
41         }
42
43         $url = Probe::cleanURI($_REQUEST['url']);
44         $return_path = 'follow?url=' . urlencode($url);
45
46         // Makes the connection request for friendica contacts easier
47         // This is just a precaution if maybe this page is called somewhere directly via POST
48         $_SESSION['fastlane'] = $url;
49
50         $result = Contact::createFromProbe($a->user, $url, true);
51
52         if ($result['success'] == false) {
53                 // Possibly it is a remote item and not an account
54                 follow_remote_item($url);
55
56                 if ($result['message']) {
57                         notice($result['message']);
58                 }
59                 DI::baseUrl()->redirect($return_path);
60         } elseif ($result['cid']) {
61                 DI::baseUrl()->redirect('contact/' . $result['cid']);
62         }
63
64         info(DI::l10n()->t('The contact could not be added.'));
65
66         DI::baseUrl()->redirect($return_path);
67         // NOTREACHED
68 }
69
70 function follow_content(App $a)
71 {
72         $return_path = 'contact';
73
74         if (!local_user()) {
75                 notice(DI::l10n()->t('Permission denied.'));
76                 DI::baseUrl()->redirect($return_path);
77                 // NOTREACHED
78         }
79
80         $uid = local_user();
81
82         // Issue 4815: Silently removing a prefixing @
83         $url = ltrim(Strings::escapeTags(trim($_REQUEST['url'] ?? '')), '@!');
84
85         // Issue 6874: Allow remote following from Peertube
86         if (strpos($url, 'acct:') === 0) {
87                 $url = str_replace('acct:', '', $url);
88         }
89
90         if (!$url) {
91                 DI::baseUrl()->redirect($return_path);
92         }
93
94         $submit = DI::l10n()->t('Submit Request');
95
96         // Don't try to add a pending contact
97         $r = q("SELECT `pending` FROM `contact` WHERE `uid` = %d AND ((`rel` != %d) OR (`network` = '%s')) AND
98                 (`nurl` = '%s' OR `alias` = '%s' OR `alias` = '%s') AND
99                 `network` != '%s' LIMIT 1",
100                 intval(local_user()), DBA::escape(Contact::FOLLOWER), DBA::escape(Protocol::DFRN), DBA::escape(Strings::normaliseLink($url)),
101                 DBA::escape(Strings::normaliseLink($url)), DBA::escape($url), DBA::escape(Protocol::STATUSNET));
102
103         if ($r) {
104                 if ($r[0]['pending']) {
105                         notice(DI::l10n()->t('You already added this contact.'));
106                         $submit = '';
107                         //$a->internalRedirect($_SESSION['return_path']);
108                         // NOTREACHED
109                 }
110         }
111
112         $ret = Probe::uri($url);
113
114         $protocol = Contact::getProtocol($ret['url'], $ret['network']);
115
116         if (($protocol == Protocol::DIASPORA) && !DI::config()->get('system', 'diaspora_enabled')) {
117                 notice(DI::l10n()->t("Diaspora support isn't enabled. Contact can't be added."));
118                 $submit = '';
119                 //$a->internalRedirect($_SESSION['return_path']);
120                 // NOTREACHED
121         }
122
123         if (($protocol == Protocol::OSTATUS) && DI::config()->get('system', 'ostatus_disabled')) {
124                 notice(DI::l10n()->t("OStatus support is disabled. Contact can't be added."));
125                 $submit = '';
126                 //$a->internalRedirect($_SESSION['return_path']);
127                 // NOTREACHED
128         }
129
130         if ($protocol == Protocol::PHANTOM) {
131                 // Possibly it is a remote item and not an account
132                 follow_remote_item($url);
133
134                 notice(DI::l10n()->t("The network type couldn't be detected. Contact can't be added."));
135                 $submit = '';
136                 //$a->internalRedirect($_SESSION['return_path']);
137                 // NOTREACHED
138         }
139
140         if ($protocol == Protocol::MAIL) {
141                 $ret['url'] = $ret['addr'];
142         }
143
144         if (($protocol === Protocol::DFRN) && !DBA::isResult($r)) {
145                 $request = $ret['request'];
146                 $tpl = Renderer::getMarkupTemplate('dfrn_request.tpl');
147         } else {
148                 $request = DI::baseUrl() . '/follow';
149                 $tpl = Renderer::getMarkupTemplate('auto_request.tpl');
150         }
151
152         $r = q("SELECT `url` FROM `contact` WHERE `uid` = %d AND `self` LIMIT 1", intval($uid));
153
154         if (!$r) {
155                 notice(DI::l10n()->t('Permission denied.'));
156                 DI::baseUrl()->redirect($return_path);
157                 // NOTREACHED
158         }
159
160         $myaddr = $r[0]['url'];
161         $gcontact_id = 0;
162
163         // Makes the connection request for friendica contacts easier
164         $_SESSION['fastlane'] = $ret['url'];
165
166         $r = q("SELECT `id`, `location`, `about`, `keywords` FROM `gcontact` WHERE `nurl` = '%s'",
167                 Strings::normaliseLink($ret['url']));
168
169         if (!$r) {
170                 $r = [['location' => '', 'about' => '', 'keywords' => '']];
171         } else {
172                 $gcontact_id = $r[0]['id'];
173         }
174
175         if ($protocol === Protocol::DIASPORA) {
176                 $r[0]['location'] = '';
177                 $r[0]['about'] = '';
178         }
179
180         $o = Renderer::replaceMacros($tpl, [
181                 '$header'        => DI::l10n()->t('Connect/Follow'),
182                 '$pls_answer'    => DI::l10n()->t('Please answer the following:'),
183                 '$your_address'  => DI::l10n()->t('Your Identity Address:'),
184                 '$url_label'     => DI::l10n()->t('Profile URL'),
185                 '$keywords_label'=> DI::l10n()->t('Tags:'),
186                 '$submit'        => $submit,
187                 '$cancel'        => DI::l10n()->t('Cancel'),
188
189                 '$request'       => $request,
190                 '$name'          => $ret['name'],
191                 '$url'           => $ret['url'],
192                 '$zrl'           => Profile::zrl($ret['url']),
193                 '$myaddr'        => $myaddr,
194                 '$keywords'      => $r[0]['keywords'],
195
196                 '$does_know_you' => ['knowyou', DI::l10n()->t('%s knows you', $ret['name'])],
197                 '$addnote_field' => ['dfrn-request-message', DI::l10n()->t('Add a personal note:')],
198         ]);
199
200         DI::page()['aside'] = '';
201
202         $profiledata = Contact::getDetailsByURL($ret['url']);
203         if ($profiledata) {
204                 Profile::load($a, '', $profiledata, false);
205         }
206
207         if ($gcontact_id <> 0) {
208                 $o .= Renderer::replaceMacros(Renderer::getMarkupTemplate('section_title.tpl'),
209                         ['$title' => DI::l10n()->t('Status Messages and Posts')]
210                 );
211
212                 // Show last public posts
213                 $o .= Contact::getPostsFromUrl($ret['url']);
214         }
215
216         return $o;
217 }
218
219 function follow_remote_item($url)
220 {
221         $item_id = Item::fetchByLink($url, local_user());
222         if (!$item_id) {
223                 // If the user-specific search failed, we search and probe a public post
224                 $item_id = Item::fetchByLink($url);
225         }
226
227         if (!empty($item_id)) {
228                 $item = Item::selectFirst(['guid'], ['id' => $item_id]);
229                 if (DBA::isResult($item)) {
230                         DI::baseUrl()->redirect('display/' . $item['guid']);
231                 }
232         }
233 }