]> git.mxchange.org Git - friendica.git/blobdiff - mod/item.php
Indentation
[friendica.git] / mod / item.php
index 651c2224cb97fb1694dc445c895f87e1315a1cd8..6864dabacd6c367385791f087a1a654e39810c52 100644 (file)
@@ -30,6 +30,7 @@
 
 use Friendica\App;
 use Friendica\Content\Item as ItemHelper;
+use Friendica\Content\PageInfo;
 use Friendica\Content\Text\BBCode;
 use Friendica\Core\Hook;
 use Friendica\Core\Logger;
@@ -44,20 +45,19 @@ use Friendica\Model\Contact;
 use Friendica\Model\Conversation;
 use Friendica\Model\FileTag;
 use Friendica\Model\Item;
+use Friendica\Model\Notify;
 use Friendica\Model\Notify\Type;
 use Friendica\Model\Photo;
+use Friendica\Model\Post;
 use Friendica\Model\Tag;
 use Friendica\Network\HTTPException;
 use Friendica\Object\EMail\ItemCCEMail;
 use Friendica\Protocol\Activity;
 use Friendica\Protocol\Diaspora;
 use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Security;
-use Friendica\Util\Strings;
+use Friendica\Security\Security;
 use Friendica\Worker\Delivery;
 
-require_once __DIR__ . '/../include/items.php';
-
 function item_post(App $a) {
        if (!Session::isAuthenticated()) {
                throw new HTTPException\ForbiddenException();
@@ -67,7 +67,10 @@ function item_post(App $a) {
 
        if (!empty($_REQUEST['dropitems'])) {
                $arr_drop = explode(',', $_REQUEST['dropitems']);
-               drop_items($arr_drop);
+               foreach ($arr_drop as $item) {
+                       Item::deleteForUser(['id' => $item], $uid);
+               }
+
                $json = ['success' => 1];
                System::jsonExit($json);
        }
@@ -78,8 +81,6 @@ function item_post(App $a) {
 
        $api_source = $_REQUEST['api_source'] ?? false;
 
-       $message_id = ((!empty($_REQUEST['message_id']) && $api_source) ? strip_tags($_REQUEST['message_id']) : '');
-
        $return_path = $_REQUEST['return'] ?? '';
        $preview = intval($_REQUEST['preview'] ?? 0);
 
@@ -98,29 +99,32 @@ function item_post(App $a) {
        }
 
        // Is this a reply to something?
-       $toplevel_item_id = intval($_REQUEST['parent'] ?? 0);
+       $parent_item_id = intval($_REQUEST['parent'] ?? 0);
        $thr_parent_uri = trim($_REQUEST['parent_uri'] ?? '');
 
+       $parent_item = null;
        $toplevel_item = null;
-       $parent_user = null;
+       $toplevel_item_id = 0;
+       $toplevel_user_id = null;
 
        $objecttype = null;
        $profile_uid = ($_REQUEST['profile_uid'] ?? 0) ?: local_user();
        $posttype = ($_REQUEST['post_type'] ?? '') ?: Item::PT_ARTICLE;
 
-       if ($toplevel_item_id || $thr_parent_uri) {
-               if ($toplevel_item_id) {
-                       $toplevel_item = Item::selectFirst([], ['id' => $toplevel_item_id]);
+       if ($parent_item_id || $thr_parent_uri) {
+               if ($parent_item_id) {
+                       $parent_item = Item::selectFirst([], ['id' => $parent_item_id]);
                } elseif ($thr_parent_uri) {
-                       $toplevel_item = Item::selectFirst([], ['uri' => $thr_parent_uri, 'uid' => $profile_uid]);
+                       $parent_item = Item::selectFirst([], ['uri' => $thr_parent_uri, 'uid' => $profile_uid]);
                }
 
                // if this isn't the top-level parent of the conversation, find it
-               if (DBA::isResult($toplevel_item)) {
+               if (DBA::isResult($parent_item)) {
                        // The URI and the contact is taken from the direct parent which needn't to be the top parent
-                       $thr_parent_uri = $toplevel_item['uri'];
+                       $thr_parent_uri = $parent_item['uri'];
+                       $toplevel_item = $parent_item;
 
-                       if ($toplevel_item['gravity'] != GRAVITY_PARENT) {
+                       if ($parent_item['gravity'] != GRAVITY_PARENT) {
                                $toplevel_item = Item::selectFirst([], ['id' => $toplevel_item['parent']]);
                        }
                }
@@ -133,8 +137,18 @@ function item_post(App $a) {
                        throw new HTTPException\NotFoundException(DI::l10n()->t('Unable to locate original post.'));
                }
 
+               // When commenting on a public post then store the post for the current user
+               // This enables interaction like starring and saving into folders
+               if ($toplevel_item['uid'] == 0) {
+                       $stored = Item::storeForUserByUriId($toplevel_item['uri-id'], local_user());
+                       Logger::info('Public item stored for user', ['uri-id' => $toplevel_item['uri-id'], 'uid' => $uid, 'stored' => $stored]);
+                       if ($stored) {
+                               $toplevel_item = Item::selectFirst([], ['id' => $stored]);
+                       }
+               }
+
                $toplevel_item_id = $toplevel_item['id'];
-               $parent_user = $toplevel_item['uid'];
+               $toplevel_user_id = $toplevel_item['uid'];
 
                $objecttype = Activity\ObjectType::COMMENT;
        }
@@ -156,16 +170,8 @@ function item_post(App $a) {
        }
 
        // Ensure that the user id in a thread always stay the same
-       if (!is_null($parent_user) && in_array($parent_user, [local_user(), 0])) {
-               $profile_uid = $parent_user;
-       }
-
-       // Check for multiple posts with the same message id (when the post was created via API)
-       if (($message_id != '') && ($profile_uid != 0)) {
-               if (Item::exists(['uri' => $message_id, 'uid' => $profile_uid])) {
-                       Logger::info('Message already exists for user', ['uri' => $message_id, 'uid' => $profile_uid]);
-                       return 0;
-               }
+       if (!is_null($toplevel_user_id) && in_array($toplevel_user_id, [local_user(), 0])) {
+               $profile_uid = $toplevel_user_id;
        }
 
        // Allow commenting if it is an answer to a public post
@@ -229,7 +235,7 @@ function item_post(App $a) {
                        ];
                }
 
-               $att_bbcode = add_page_info_data($attachment);
+               $att_bbcode = "\n" . PageInfo::getFooterFromData($attachment);
                $body .= $att_bbcode;
        }
 
@@ -247,7 +253,7 @@ function item_post(App $a) {
                $objecttype        = $orig_post['object-type'];
                $app               = $orig_post['app'];
                $categories        = $orig_post['file'] ?? '';
-               $title             = Strings::escapeTags(trim($_REQUEST['title']));
+               $title             = trim($_REQUEST['title'] ?? '');
                $body              = trim($body);
                $private           = $orig_post['private'];
                $pubmail_enabled   = $orig_post['pubmail'];
@@ -268,13 +274,13 @@ function item_post(App $a) {
                        $str_group_deny    = isset($_REQUEST['group_deny'])    ? $aclFormatter->toString($_REQUEST['group_deny'])    : $user['deny_gid']  ?? '';
                }
 
-               $title             = Strings::escapeTags(trim($_REQUEST['title']    ?? ''));
-               $location          = Strings::escapeTags(trim($_REQUEST['location'] ?? ''));
-               $coord             = Strings::escapeTags(trim($_REQUEST['coord']    ?? ''));
-               $verb              = Strings::escapeTags(trim($_REQUEST['verb']     ?? ''));
-               $emailcc           = Strings::escapeTags(trim($_REQUEST['emailcc']  ?? ''));
+               $title             = trim($_REQUEST['title']    ?? '');
+               $location          = trim($_REQUEST['location'] ?? '');
+               $coord             = trim($_REQUEST['coord']    ?? '');
+               $verb              = trim($_REQUEST['verb']     ?? '');
+               $emailcc           = trim($_REQUEST['emailcc']  ?? '');
                $body              = trim($body);
-               $network           = Strings::escapeTags(trim(($_REQUEST['network']  ?? '') ?: Protocol::DFRN));
+               $network           = trim(($_REQUEST['network']  ?? '') ?: Protocol::DFRN);
                $guid              = System::createUUID();
 
                $postopts = $_REQUEST['postopts'] ?? '';
@@ -320,7 +326,7 @@ function item_post(App $a) {
                                System::jsonExit(['preview' => '']);
                        }
 
-                       info(DI::l10n()->t('Empty post discarded.'));
+                       notice(DI::l10n()->t('Empty post discarded.'));
                        if ($return_path) {
                                DI::baseUrl()->redirect($return_path);
                        }
@@ -363,9 +369,9 @@ function item_post(App $a) {
 
        // get contact info for owner
        if ($profile_uid == local_user() || $allow_comment) {
-               $contact_record = $author;
+               $contact_record = $author ?: [];
        } else {
-               $contact_record = DBA::selectFirst('contact', [], ['uid' => $profile_uid, 'self' => true]);
+               $contact_record = DBA::selectFirst('contact', [], ['uid' => $profile_uid, 'self' => true]) ?: [];
        }
 
        // Look for any tags and linkify them
@@ -375,7 +381,7 @@ function item_post(App $a) {
        $only_to_forum = false;
        $forum_contact = [];
 
-       $body = BBCode::performWithEscapedTags($body, ['noparse', 'pre', 'code'], function ($body) use ($profile_uid, $network, $str_contact_allow, &$inform, &$private_forum, &$private_id, &$only_to_forum, &$forum_contact) {
+       $body = BBCode::performWithEscapedTags($body, ['noparse', 'pre', 'code', 'img'], function ($body) use ($profile_uid, $network, $str_contact_allow, &$inform, &$private_forum, &$private_id, &$only_to_forum, &$forum_contact) {
                $tags = BBCode::getTags($body);
 
                $tagged = [];
@@ -419,7 +425,7 @@ function item_post(App $a) {
 
        $original_contact_id = $contact_id;
 
-       if (!$toplevel_item_id && count($forum_contact) && ($private_forum || $only_to_forum)) {
+       if (!$toplevel_item_id && !empty($forum_contact) && ($private_forum || $only_to_forum)) {
                // we tagged a forum in a top level post. Now we change the post
                $private = $private_forum;
 
@@ -519,9 +525,8 @@ function item_post(App $a) {
                                if (strlen($attachments)) {
                                        $attachments .= ',';
                                }
-                               $attachments .= '[attach]href="' . DI::baseUrl() . '/attach/' . $attachment['id'] .
-                                               '" length="' . $attachment['filesize'] . '" type="' . $attachment['filetype'] .
-                                               '" title="' . ($attachment['filename'] ? $attachment['filename'] : '') . '"[/attach]';
+                               $attachments .= Post\Media::getAttachElement(DI::baseUrl() . '/attach/' . $attachment['id'],
+                                       $attachment['filesize'], $attachment['filetype'], $attachment['filename'] ?? '');
                        }
                        $body = str_replace($match[1],'',$body);
                }
@@ -547,7 +552,7 @@ function item_post(App $a) {
                $origin = $_REQUEST['origin'];
        }
 
-       $uri = ($message_id ? $message_id : Item::newURI($api_source ? $profile_uid : $uid, $guid));
+       $uri = Item::newURI($api_source ? $profile_uid : $uid, $guid);
 
        // Fallback so that we alway have a parent uri
        if (!$thr_parent_uri || !$toplevel_item_id) {
@@ -560,9 +565,9 @@ function item_post(App $a) {
        $datarray['gravity']       = $gravity;
        $datarray['network']       = $network;
        $datarray['contact-id']    = $contact_id;
-       $datarray['owner-name']    = $contact_record['name'];
-       $datarray['owner-link']    = $contact_record['url'];
-       $datarray['owner-avatar']  = $contact_record['thumb'];
+       $datarray['owner-name']    = $contact_record['name'] ?? '';
+       $datarray['owner-link']    = $contact_record['url'] ?? '';
+       $datarray['owner-avatar']  = $contact_record['thumb'] ?? '';
        $datarray['owner-id']      = Contact::getIdForURL($datarray['owner-link']);
        $datarray['author-name']   = $author['name'];
        $datarray['author-link']   = $author['url'];
@@ -594,8 +599,7 @@ function item_post(App $a) {
        $datarray['pubmail']       = $pubmail_enabled;
        $datarray['attach']        = $attachments;
 
-       // This is not a bug. The item store function changes 'parent-uri' to 'thr-parent' and fetches 'parent-uri' new. (We should change this)
-       $datarray['parent-uri']    = $thr_parent_uri;
+       $datarray['thr-parent']    = $thr_parent_uri;
 
        $datarray['postopts']      = $postopts;
        $datarray['origin']        = $origin;
@@ -614,9 +618,9 @@ function item_post(App $a) {
        $datarray['api_source'] = $api_source;
 
        // This field is for storing the raw conversation data
-       $datarray['protocol'] = Conversation::PARCEL_DFRN;
+       $datarray['protocol'] = Conversation::PARCEL_DIRECT;
 
-       $conversation = DBA::selectFirst('conversation', ['conversation-uri', 'conversation-href'], ['item-uri' => $datarray['parent-uri']]);
+       $conversation = DBA::selectFirst('conversation', ['conversation-uri', 'conversation-href'], ['item-uri' => $datarray['thr-parent']]);
        if (DBA::isResult($conversation)) {
                if ($conversation['conversation-uri'] != '') {
                        $datarray['conversation-uri'] = $conversation['conversation-uri'];
@@ -690,7 +694,6 @@ function item_post(App $a) {
                // update filetags in pconfig
                FileTag::updatePconfig($uid, $categories_old, $categories_new, 'category');
 
-               info(DI::l10n()->t('Post updated.'));
                if ($return_path) {
                        DI::baseUrl()->redirect($return_path);
                }
@@ -712,7 +715,7 @@ function item_post(App $a) {
        $post_id = Item::insert($datarray);
 
        if (!$post_id) {
-               info(DI::l10n()->t('Item wasn\'t stored.'));
+               notice(DI::l10n()->t('Item wasn\'t stored.'));
                if ($return_path) {
                        DI::baseUrl()->redirect($return_path);
                }
@@ -741,42 +744,26 @@ function item_post(App $a) {
        FileTag::updatePconfig($uid, $categories_old, $categories_new, 'category');
 
        // These notifications are sent if someone else is commenting other your wall
-       if ($toplevel_item_id) {
-               if ($contact_record != $author) {
+       if ($contact_record != $author) {
+               if ($toplevel_item_id) {
                        notification([
-                               'type'         => Type::COMMENT,
-                               'notify_flags' => $user['notify-flags'],
-                               'language'     => $user['language'],
-                               'to_name'      => $user['username'],
-                               'to_email'     => $user['email'],
-                               'uid'          => $user['uid'],
-                               'item'         => $datarray,
-                               'link'         => DI::baseUrl().'/display/'.urlencode($datarray['guid']),
-                               'source_name'  => $datarray['author-name'],
-                               'source_link'  => $datarray['author-link'],
-                               'source_photo' => $datarray['author-avatar'],
-                               'verb'         => Activity::POST,
-                               'otype'        => 'item',
-                               'parent'       => $toplevel_item_id,
-                               'parent_uri'   => $toplevel_item['uri']
+                               'type'  => Type::COMMENT,
+                               'otype' => Notify\ObjectType::ITEM,
+                               'verb'  => Activity::POST,
+                               'uid'   => $user['uid'],
+                               'cid'   => $datarray['author-id'],
+                               'item'  => $datarray,
+                               'link'  => DI::baseUrl() . '/display/' . urlencode($datarray['guid']),
                        ]);
-               }
-       } else {
-               if (($contact_record != $author) && !count($forum_contact)) {
+               } elseif (empty($forum_contact)) {
                        notification([
-                               'type'         => Type::WALL,
-                               'notify_flags' => $user['notify-flags'],
-                               'language'     => $user['language'],
-                               'to_name'      => $user['username'],
-                               'to_email'     => $user['email'],
-                               'uid'          => $user['uid'],
-                               'item'         => $datarray,
-                               'link'         => DI::baseUrl().'/display/'.urlencode($datarray['guid']),
-                               'source_name'  => $datarray['author-name'],
-                               'source_link'  => $datarray['author-link'],
-                               'source_photo' => $datarray['author-avatar'],
-                               'verb'         => Activity::POST,
-                               'otype'        => 'item'
+                               'type'  => Type::WALL,
+                               'otype' => Notify\ObjectType::ITEM,
+                               'verb'  => Activity::POST,
+                               'uid'   => $user['uid'],
+                               'cid'   => $datarray['author-id'],
+                               'item'  => $datarray,
+                               'link'  => DI::baseUrl() . '/display/' . urlencode($datarray['guid']),
                        ]);
                }
        }
@@ -797,12 +784,6 @@ function item_post(App $a) {
                }
        }
 
-       // Insert an item entry for UID=0 for global entries.
-       // We now do it in the background to save some time.
-       // This is important in interactive environments like the frontend or the API.
-       // We don't fork a new process since this is done anyway with the following command
-       Worker::add(['priority' => PRIORITY_HIGH, 'dont_fork' => true], "CreateShadowEntry", $post_id);
-
        // When we are doing some forum posting via ! we have to start the notifier manually.
        // These kind of posts don't initiate the notifier call in the item class.
        if ($only_to_forum) {
@@ -815,7 +796,6 @@ function item_post(App $a) {
                return $post_id;
        }
 
-       info(DI::l10n()->t('Post published.'));
        item_post_return(DI::baseUrl(), $api_source, $return_path);
        // NOTREACHED
 }
@@ -850,7 +830,9 @@ function item_content(App $a)
 
        if (($a->argc >= 3) && ($a->argv[1] === 'drop') && intval($a->argv[2])) {
                if (DI::mode()->isAjax()) {
-                       $o = Item::deleteForUser(['id' => $a->argv[2]], local_user());
+                       Item::deleteForUser(['id' => $a->argv[2]], local_user());
+                       // ajax return: [<item id>, 0 (no perm) | <owner id>]
+                       System::jsonExit([intval($a->argv[2]), local_user()]);
                } else {
                        if (!empty($a->argv[3])) {
                                $o = drop_item($a->argv[2], $a->argv[3]);
@@ -859,12 +841,78 @@ function item_content(App $a)
                                $o = drop_item($a->argv[2]);
                        }
                }
+       }
 
-               if (DI::mode()->isAjax()) {
-                       // ajax return: [<item id>, 0 (no perm) | <owner id>]
-                       System::jsonExit([intval($a->argv[2]), intval($o)]);
+       return $o;
+}
+
+/**
+ * @param int    $id
+ * @param string $return
+ * @return string
+ * @throws HTTPException\InternalServerErrorException
+ */
+function drop_item(int $id, string $return = '')
+{
+       // locate item to be deleted
+       $fields = ['id', 'uid', 'guid', 'contact-id', 'deleted', 'gravity', 'parent'];
+       $item = Item::selectFirstForUser(local_user(), $fields, ['id' => $id]);
+
+       if (!DBA::isResult($item)) {
+               notice(DI::l10n()->t('Item not found.'));
+               DI::baseUrl()->redirect('network');
+       }
+
+       if ($item['deleted']) {
+               return '';
+       }
+
+       $contact_id = 0;
+
+       // check if logged in user is either the author or owner of this item
+       if (Session::getRemoteContactID($item['uid']) == $item['contact-id']) {
+               $contact_id = $item['contact-id'];
+       }
+
+       if ((local_user() == $item['uid']) || $contact_id) {
+               if (!empty($item['parent'])) {
+                       $parentitem = Item::selectFirstForUser(local_user(), ['guid'], ['id' => $item['parent']]);
                }
+
+               // delete the item
+               Item::deleteForUser(['id' => $item['id']], local_user());
+
+               $return_url = hex2bin($return);
+
+               // removes update_* from return_url to ignore Ajax refresh
+               $return_url = str_replace("update_", "", $return_url);
+
+               // Check if delete a comment
+               if ($item['gravity'] == GRAVITY_COMMENT) {
+                       // Return to parent guid
+                       if (!empty($parentitem)) {
+                               DI::baseUrl()->redirect('display/' . $parentitem['guid']);
+                               //NOTREACHED
+                       } // In case something goes wrong
+                       else {
+                               DI::baseUrl()->redirect('network');
+                               //NOTREACHED
+                       }
+               } else {
+                       // if unknown location or deleting top level post called from display
+                       if (empty($return_url) || strpos($return_url, 'display') !== false) {
+                               DI::baseUrl()->redirect('network');
+                               //NOTREACHED
+                       } else {
+                               DI::baseUrl()->redirect($return_url);
+                               //NOTREACHED
+                       }
+               }
+       } else {
+               notice(DI::l10n()->t('Permission denied.'));
+               DI::baseUrl()->redirect('display/' . $item['guid']);
+               //NOTREACHED
        }
 
-       return $o;
+       return '';
 }