]> git.mxchange.org Git - friendica.git/blob - mod/display.php
Updating after post does now work
[friendica.git] / mod / display.php
1 <?php
2
3 use Friendica\App;
4 use Friendica\Core\Config;
5 use Friendica\Core\System;
6 use Friendica\Database\DBM;
7 use Friendica\Model\Contact;
8 use Friendica\Protocol\DFRN;
9
10 function display_init(App $a) {
11
12         if ((Config::get('system','block_public')) && (! local_user()) && (! remote_user())) {
13                 return;
14         }
15
16         $nick = (($a->argc > 1) ? $a->argv[1] : '');
17         $profiledata = array();
18
19         if ($a->argc == 3) {
20                 if (substr($a->argv[2], -5) == '.atom') {
21                         $item_id = substr($a->argv[2], 0, -5);
22                         displayShowFeed($item_id, false);
23                 }
24         }
25
26         if ($a->argc == 4) {
27                 if ($a->argv[3] == 'conversation.atom') {
28                         $item_id = $a->argv[2];
29                         displayShowFeed($item_id, true);
30                 }
31         }
32
33         $r = false;
34
35         // If there is only one parameter, then check if this parameter could be a guid
36         if ($a->argc == 2) {
37                 $nick = "";
38                 $r = false;
39
40                 // Does the local user have this item?
41                 if (local_user()) {
42                         $r = dba::fetch_first("SELECT `id`, `parent`, `author-name`, `author-link`,
43                                                 `author-avatar`, `network`, `body`, `uid`, `owner-link`
44                                 FROM `item` WHERE `visible` AND NOT `deleted` AND NOT `moderated`
45                                         AND `guid` = ? AND `uid` = ? LIMIT 1", $a->argv[1], local_user());
46                         if (DBM::is_result($r)) {
47                                 $nick = $a->user["nickname"];
48                         }
49                 }
50
51                 // Is it an item with uid=0?
52                 if (!DBM::is_result($r)) {
53                         $r = dba::fetch_first("SELECT `id`, `parent`, `author-name`, `author-link`,
54                                                 `author-avatar`, `network`, `body`, `uid`, `owner-link`
55                                 FROM `item` WHERE `visible` AND NOT `deleted` AND NOT `moderated`
56                                         AND `allow_cid` = ''  AND `allow_gid` = ''
57                                         AND `deny_cid`  = '' AND `deny_gid`  = ''
58                                         AND NOT `private` AND `uid` = 0
59                                         AND `guid` = ? LIMIT 1", $a->argv[1]);
60                 }
61
62                 // Or is it anywhere on the server?
63                 if (!DBM::is_result($r)) {
64                         $r = dba::fetch_first("SELECT `item`.`id`, `item`.`parent`, `item`.`author-name`, `item`.`author-link`,
65                                 `item`.`author-avatar`, `item`.`network`, `item`.`body`, `item`.`uid`, `item`.`owner-link`
66                                 FROM `item` STRAIGHT_JOIN `user` ON `user`.`uid` = `item`.`uid`
67                                 WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
68                                         AND `item`.`allow_cid` = ''  AND `item`.`allow_gid` = ''
69                                         AND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = ''
70                                         AND NOT `item`.`private` AND NOT `user`.`hidewall`
71                                         AND `item`.`guid` = ? LIMIT 1", $a->argv[1]);
72                 }
73
74                 if (!DBM::is_result($r)) {
75                         $a->error = 404;
76                         notice(t('Item not found.') . EOL);
77                         return;
78                 }
79         } elseif (($a->argc == 3) && ($nick == '_feed_')) {
80                 $r = dba::fetch_first("SELECT `id`, `parent`, `author-name`, `author-link`,
81                                         `author-avatar`, `network`, `body`, `uid`, `owner-link`
82                         FROM `item` WHERE `visible` AND NOT `deleted` AND NOT `moderated`
83                                 AND `allow_cid` = ''  AND `allow_gid` = ''
84                                 AND `deny_cid`  = '' AND `deny_gid`  = ''
85                                 AND NOT `private` AND `uid` = 0
86                                 AND `id` = ? LIMIT 1", $a->argv[2]);
87         }
88
89         if (DBM::is_result($r)) {
90                 if (strstr($_SERVER['HTTP_ACCEPT'], 'application/atom+xml')) {
91                         logger('Directly serving XML for id '.$r["id"], LOGGER_DEBUG);
92                         displayShowFeed($r["id"], false);
93                 }
94
95                 if ($r["id"] != $r["parent"]) {
96                         $r = dba::fetch_first("SELECT `id`, `author-name`, `author-link`, `author-avatar`, `network`, `body`, `uid`, `owner-link` FROM `item`
97                                 WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
98                                         AND `id` = ?", $r["parent"]);
99                 }
100
101                 $profiledata = display_fetchauthor($a, $r);
102
103                 if (strstr(normalise_link($profiledata["url"]), normalise_link(System::baseUrl()))) {
104                         $nickname = str_replace(normalise_link(System::baseUrl())."/profile/", "", normalise_link($profiledata["url"]));
105
106                         if (($nickname != $a->user["nickname"])) {
107                                 $r = dba::fetch_first("SELECT `profile`.`uid` AS `profile_uid`, `profile`.* , `contact`.`avatar-date` AS picdate, `user`.* FROM `profile`
108                                         INNER JOIN `contact` on `contact`.`uid` = `profile`.`uid` INNER JOIN `user` ON `profile`.`uid` = `user`.`uid`
109                                         WHERE `user`.`nickname` = ? AND `profile`.`is-default` AND `contact`.`self` LIMIT 1",
110                                         $nickname
111                                 );
112                                 if (DBM::is_result($r)) {
113                                         $profiledata = $r;
114                                 }
115                                 $profiledata["network"] = NETWORK_DFRN;
116                         } else {
117                                 $profiledata = array();
118                         }
119                 }
120         }
121
122         profile_load($a, $nick, 0, $profiledata);
123 }
124
125 function display_fetchauthor($a, $item) {
126
127         $profiledata = array();
128         $profiledata["uid"] = -1;
129         $profiledata["nickname"] = $item["author-name"];
130         $profiledata["name"] = $item["author-name"];
131         $profiledata["picdate"] = "";
132         $profiledata["photo"] = $item["author-avatar"];
133         $profiledata["url"] = $item["author-link"];
134         $profiledata["network"] = $item["network"];
135
136         // Check for a repeated message
137         $skip = false;
138         $body = trim($item["body"]);
139
140         // Skip if it isn't a pure repeated messages
141         // Does it start with a share?
142         if (!$skip && strpos($body, "[share") > 0) {
143                 $skip = true;
144         }
145         // Does it end with a share?
146         if (!$skip && (strlen($body) > (strrpos($body, "[/share]") + 8))) {
147                 $skip = true;
148         }
149         if (!$skip) {
150                 $attributes = preg_replace("/\[share(.*?)\]\s?(.*?)\s?\[\/share\]\s?/ism","$1",$body);
151                 // Skip if there is no shared message in there
152                 if ($body == $attributes) {
153                         $skip = true;
154                 }
155         }
156
157         if (!$skip) {
158                 $author = "";
159                 preg_match("/author='(.*?)'/ism", $attributes, $matches);
160                 if ($matches[1] != "") {
161                         $profiledata["name"] = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
162                 }
163                 preg_match('/author="(.*?)"/ism', $attributes, $matches);
164                 if ($matches[1] != "") {
165                         $profiledata["name"] = html_entity_decode($matches[1],ENT_QUOTES,'UTF-8');
166                 }
167                 $profile = "";
168                 preg_match("/profile='(.*?)'/ism", $attributes, $matches);
169                 if ($matches[1] != "") {
170                         $profiledata["url"] = $matches[1];
171                 }
172                 preg_match('/profile="(.*?)"/ism', $attributes, $matches);
173                 if ($matches[1] != "") {
174                         $profiledata["url"] = $matches[1];
175                 }
176                 $avatar = "";
177                 preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
178                 if ($matches[1] != "") {
179                         $profiledata["photo"] = $matches[1];
180                 }
181                 preg_match('/avatar="(.*?)"/ism', $attributes, $matches);
182                 if ($matches[1] != "") {
183                         $profiledata["photo"] = $matches[1];
184                 }
185                 $profiledata["nickname"] = $profiledata["name"];
186                 $profiledata["network"] = GetProfileUsername($profiledata["url"], "", false, true);
187
188                 $profiledata["address"] = "";
189                 $profiledata["about"] = "";
190         }
191
192         $profiledata = Contact::getDetailsByURL($profiledata["url"], local_user(), $profiledata);
193
194         $profiledata["photo"] = System::removedBaseUrl($profiledata["photo"]);
195
196         if (local_user()) {
197                 if (in_array($profiledata["network"], array(NETWORK_DFRN, NETWORK_DIASPORA, NETWORK_OSTATUS))) {
198                         $profiledata["remoteconnect"] = System::baseUrl()."/follow?url=".urlencode($profiledata["url"]);
199                 }
200         } elseif ($profiledata["network"] == NETWORK_DFRN) {
201                 $connect = str_replace("/profile/", "/dfrn_request/", $profiledata["url"]);
202                 $profiledata["remoteconnect"] = $connect;
203         }
204
205         return($profiledata);
206 }
207
208 function display_content(App $a, $update = false, $update_uid = 0) {
209
210         if (Config::get('system','block_public') && !local_user() && !remote_user()) {
211                 notice(t('Public access denied.') . EOL);
212                 return;
213         }
214
215         require_once('include/security.php');
216         require_once('include/conversation.php');
217         require_once('include/acl_selectors.php');
218
219
220         $o = '';
221
222         if ($update) {
223                 $nick = $_REQUEST['nick'];
224         } else {
225                 $nick = (($a->argc > 1) ? $a->argv[1] : '');
226         }
227
228         if ($update) {
229                 $item_id = $_REQUEST['item_id'];
230                 $item = dba::select('item', ['uid'], ['id' => $item_id], ['limit' => 1]);
231                 $a->profile = array('uid' => intval($item['uid']), 'profile_uid' => intval($item['uid']));
232         } else {
233                 $item_id = (($a->argc > 2) ? $a->argv[2] : 0);
234
235                 if ($a->argc == 2) {
236                         $item_parent = 0;
237                         $nick = "";
238
239                         if (local_user()) {
240                                 $r = dba::fetch_first("SELECT `id`, `parent` FROM `item`
241                                         WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
242                                                 AND `guid` = ? AND `uid` = ?", $a->argv[1], local_user());
243                                 if (DBM::is_result($r)) {
244                                         $item_id = $r["id"];
245                                         $item_parent = $r["parent"];
246                                         $nick = $a->user["nickname"];
247                                 }
248                         }
249
250                         if ($item_parent == 0) {
251                                 $r = dba::fetch_first("SELECT `item`.`id`, `item`.`parent` FROM `item`
252                                         WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
253                                                 AND `item`.`allow_cid` = ''  AND `item`.`allow_gid` = ''
254                                                 AND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = ''
255                                                 AND NOT `item`.`private` AND `item`.`uid` = 0
256                                                 AND `item`.`guid` = ?", $a->argv[1]);
257                                 if (DBM::is_result($r)) {
258                                         $item_id = $r["id"];
259                                         $item_parent = $r["parent"];
260                                 }
261                         }
262                         if ($item_parent == 0) {
263                                 $r = dba::fetch_first("SELECT `user`.`nickname`, `item`.`id`, `item`.`parent` FROM `item` STRAIGHT_JOIN `user` ON `user`.`uid` = `item`.`uid`
264                                         WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
265                                                 AND `item`.`allow_cid` = ''  AND `item`.`allow_gid` = ''
266                                                 AND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = ''
267                                                 AND NOT `item`.`private` AND NOT `user`.`hidewall`
268                                                 AND `item`.`guid` = ?", $a->argv[1]);
269                                 if (DBM::is_result($r)) {
270                                         $item_id = $r["id"];
271                                         $item_parent = $r["parent"];
272                                         $nick = $r["nickname"];
273                                 }
274                         }
275                 }
276         }
277
278         if ($item_id && !is_numeric($item_id)) {
279                 $r = dba::select('item', array('id', 'parent'), array('uri' => $item_id, 'uid' => $a->profile['uid']), array('limit' => 1));
280                 if (DBM::is_result($r)) {
281                         $item_id = $r["id"];
282                         $item_parent = $r["parent"];
283                 } else {
284                         $item_id = false;
285                 }
286         }
287
288         if (!$item_id) {
289                 $a->error = 404;
290                 notice(t('Item not found.').EOL);
291                 return;
292         }
293
294         // We are displaying an "alternate" link if that post was public. See issue 2864
295         $is_public = dba::exists('item', array('id' => $item_id, 'private' => false));
296         if ($is_public) {
297                 // For the atom feed the nickname doesn't matter at all, we only need the item id.
298                 if ($nick == '') {
299                         $nick = '_feed_';
300                 }
301                 $alternate = System::baseUrl().'/display/'.$nick.'/'.$item_id.'.atom';
302                 $conversation = System::baseUrl().'/display/'.$nick.'/'.$item_parent.'/conversation.atom';
303         } else {
304                 $alternate = '';
305                 $conversation = '';
306         }
307
308         $a->page['htmlhead'] .= replace_macros(get_markup_template('display-head.tpl'),
309                                 array('$alternate' => $alternate,
310                                         '$conversation' => $conversation));
311
312         $groups = array();
313
314         $contact = null;
315         $remote_contact = false;
316
317         $contact_id = 0;
318
319         if (is_array($_SESSION['remote'])) {
320                 foreach ($_SESSION['remote'] as $v) {
321                         if ($v['uid'] == $a->profile['uid']) {
322                                 $contact_id = $v['cid'];
323                                 break;
324                         }
325                 }
326         }
327
328         if ($contact_id) {
329                 $groups = init_groups_visitor($contact_id);
330                 $r = dba::fetch_first("SELECT * FROM `contact` WHERE `id` = ? AND `uid` = ? LIMIT 1",
331                         $contact_id,
332                         $a->profile['uid']
333                 );
334                 if (DBM::is_result($r)) {
335                         $contact = $r;
336                         $remote_contact = true;
337                 }
338         }
339
340         if (!$remote_contact) {
341                 if (local_user()) {
342                         $contact_id = $_SESSION['cid'];
343                         $contact = $a->contact;
344                 }
345         }
346
347         $r = dba::fetch_first("SELECT * FROM `contact` WHERE `uid` = ? AND `self` LIMIT 1", $a->profile['uid']);
348         if (DBM::is_result($r)) {
349                 $a->page_contact = $r;
350         }
351         $is_owner = (local_user() && (local_user() == $a->profile['profile_uid']) ? true : false);
352
353         if ($a->profile['hidewall'] && !$is_owner && !$remote_contact) {
354                 notice(t('Access to this profile has been restricted.') . EOL);
355                 return;
356         }
357
358         // We need the editor here to be able to reshare an item.
359
360         if ($is_owner) {
361                 $x = array(
362                         'is_owner' => true,
363                         'allow_location' => $a->user['allow_location'],
364                         'default_location' => $a->user['default-location'],
365                         'nickname' => $a->user['nickname'],
366                         'lockstate' => ( (is_array($a->user)) && ((strlen($a->user['allow_cid'])) || (strlen($a->user['allow_gid'])) || (strlen($a->user['deny_cid'])) || (strlen($a->user['deny_gid']))) ? 'lock' : 'unlock'),
367                         'acl' => populate_acl($a->user, true),
368                         'bang' => '',
369                         'visitor' => 'block',
370                         'profile_uid' => local_user(),
371                         'acl_data' => construct_acl_data($a, $a->user), // For non-Javascript ACL selector
372                 );
373                 $o .= status_editor($a,$x,0,true);
374         }
375
376         $sql_extra = item_permissions_sql($a->profile['uid'],$remote_contact,$groups);
377
378         if ($update) {
379                 $r = dba::p("SELECT `id` FROM `item` WHERE
380                         `item`.`parent` = (SELECT `parent` FROM `item` WHERE `id` = ?)
381                         $sql_extra AND `unseen`",
382                         $item_id
383                 );
384
385                 if (dba::num_rows($r) == 0) {
386                         return '';
387                 }
388         }
389
390         $r = dba::p(item_query()."AND `item`.`parent` = (SELECT `parent` FROM `item` WHERE `id` = ?)
391                 $sql_extra
392                 ORDER BY `parent` DESC, `gravity` ASC, `id` ASC",
393                 $item_id
394         );
395
396         if (!DBM::is_result($r) && local_user()) {
397                 // Check if this is another person's link to a post that we have
398                 $r = dba::fetch_first("SELECT `item`.uri FROM `item`
399                         WHERE (`item`.`id` = ? OR `item`.`uri` = ?)
400                         LIMIT 1",
401                         $item_id,
402                         $item_id
403                 );
404                 if (DBM::is_result($r)) {
405                         $item_uri = $r['uri'];
406
407                         $r = dba::p(item_query()." AND `item`.`uid` = ?
408                                 AND `item`.`parent` = (SELECT `parent` FROM `item` WHERE `uri` = ? AND uid = ?)
409                                 ORDER BY `parent` DESC, `gravity` ASC, `id` ASC",
410                                 local_user(),
411                                 $item_uri,
412                                 local_user()
413                         );
414                 }
415         }
416
417         if (DBM::is_result($r)) {
418                 $s = dba::inArray($r);
419
420                 if ((local_user()) && (local_user() == $a->profile['uid'])) {
421                         $unseen = dba::select('item', array('id'), array('parent' => $s[0]['parent'], 'unseen' => true), array('limit' => 1));
422                         if (DBM::is_result($unseen)) {
423                                 dba::update('item', array('unseen' => false), array('parent' => $s[0]['parent'], 'unseen' => true));
424                         }
425                 }
426
427                 $items = conv_sort($s, "`commented`");
428
429                 if (!$update) {
430                         $o .= "<script> var netargs = '?f=&nick=" . $nick . "&item_id=" . $item_id . "'; </script>";
431                 }
432                 $o .= conversation($a, $items, 'display', $update_uid);
433
434                 // Preparing the meta header
435                 require_once('include/bbcode.php');
436                 require_once("include/html2plain.php");
437                 $description = trim(html2plain(bbcode($s[0]["body"], false, false), 0, true));
438                 $title = trim(html2plain(bbcode($s[0]["title"], false, false), 0, true));
439                 $author_name = $s[0]["author-name"];
440
441                 $image = $a->remove_baseurl($s[0]["author-thumb"]);
442
443                 if ($title == "") {
444                         $title = $author_name;
445                 }
446
447                 // Limit the description to 160 characters
448                 if (strlen($description) > 160) {
449                         $description = substr($description, 0, 157) . '...';
450                 }
451
452                 $description = htmlspecialchars($description, ENT_COMPAT, 'UTF-8', true); // allow double encoding here
453                 $title = htmlspecialchars($title, ENT_COMPAT, 'UTF-8', true); // allow double encoding here
454                 $author_name = htmlspecialchars($author_name, ENT_COMPAT, 'UTF-8', true); // allow double encoding here
455
456                 //<meta name="keywords" content="">
457                 $a->page['htmlhead'] .= '<meta name="author" content="'.$author_name.'" />'."\n";
458                 $a->page['htmlhead'] .= '<meta name="title" content="'.$title.'" />'."\n";
459                 $a->page['htmlhead'] .= '<meta name="fulltitle" content="'.$title.'" />'."\n";
460                 $a->page['htmlhead'] .= '<meta name="description" content="'.$description.'" />'."\n";
461
462                 // Schema.org microdata
463                 $a->page['htmlhead'] .= '<meta itemprop="name" content="'.$title.'" />'."\n";
464                 $a->page['htmlhead'] .= '<meta itemprop="description" content="'.$description.'" />'."\n";
465                 $a->page['htmlhead'] .= '<meta itemprop="image" content="'.$image.'" />'."\n";
466                 $a->page['htmlhead'] .= '<meta itemprop="author" content="'.$author_name.'" />'."\n";
467
468                 // Twitter cards
469                 $a->page['htmlhead'] .= '<meta name="twitter:card" content="summary" />'."\n";
470                 $a->page['htmlhead'] .= '<meta name="twitter:title" content="'.$title.'" />'."\n";
471                 $a->page['htmlhead'] .= '<meta name="twitter:description" content="'.$description.'" />'."\n";
472                 $a->page['htmlhead'] .= '<meta name="twitter:image" content="'.System::baseUrl().'/'.$image.'" />'."\n";
473                 $a->page['htmlhead'] .= '<meta name="twitter:url" content="'.$s[0]["plink"].'" />'."\n";
474
475                 // Dublin Core
476                 $a->page['htmlhead'] .= '<meta name="DC.title" content="'.$title.'" />'."\n";
477                 $a->page['htmlhead'] .= '<meta name="DC.description" content="'.$description.'" />'."\n";
478
479                 // Open Graph
480                 $a->page['htmlhead'] .= '<meta property="og:type" content="website" />'."\n";
481                 $a->page['htmlhead'] .= '<meta property="og:title" content="'.$title.'" />'."\n";
482                 $a->page['htmlhead'] .= '<meta property="og:image" content="'.System::baseUrl().'/'.$image.'" />'."\n";
483                 $a->page['htmlhead'] .= '<meta property="og:url" content="'.$s[0]["plink"].'" />'."\n";
484                 $a->page['htmlhead'] .= '<meta property="og:description" content="'.$description.'" />'."\n";
485                 $a->page['htmlhead'] .= '<meta name="og:article:author" content="'.$author_name.'" />'."\n";
486                 // article:tag
487
488                 return $o;
489         }
490         $r = dba::fetch_first("SELECT `id`,`deleted` FROM `item` WHERE `id` = ? OR `uri` = ? LIMIT 1",
491                 $item_id,
492                 $item_id
493         );
494         if (DBM::is_result($r)) {
495                 if ($r['deleted']) {
496                         notice(t('Item has been removed.') . EOL);
497                 } else {
498                         notice(t('Permission denied.') . EOL);
499                 }
500         } else {
501                 notice(t('Item not found.') . EOL);
502         }
503
504         return $o;
505 }
506
507 function displayShowFeed($item_id, $conversation) {
508         $xml = DFRN::itemFeed($item_id, $conversation);
509         if ($xml == '') {
510                 http_status_exit(500);
511         }
512         header("Content-type: application/atom+xml");
513         echo $xml;
514         killme();
515 }