]> git.mxchange.org Git - friendica.git/blobdiff - src/Model/Item.php
Update function names and calls
[friendica.git] / src / Model / Item.php
index 18606e16902e2bb2d0dd3f25b15ce81e343f3d56..1e1603ef6adaf00f85f01bf24a1b8c2c8e8f65c2 100644 (file)
@@ -6,28 +6,32 @@
 
 namespace Friendica\Model;
 
+use Friendica\BaseObject;
 use Friendica\Core\Addon;
 use Friendica\Core\Config;
+use Friendica\Core\L10n;
 use Friendica\Core\PConfig;
-use Friendica\Core\Worker;
 use Friendica\Core\System;
+use Friendica\Core\Worker;
+use Friendica\Database\DBM;
 use Friendica\Model\Contact;
 use Friendica\Model\Conversation;
 use Friendica\Model\GContact;
 use Friendica\Model\Group;
 use Friendica\Model\Term;
-use Friendica\Model\User;
-use Friendica\Database\DBM;
+use Friendica\Object\Image;
+use Friendica\Protocol\Diaspora;
 use Friendica\Protocol\OStatus;
+use Friendica\Util\DateTimeFormat;
 use dba;
 use Text_LanguageDetect;
 
-require_once 'include/tags.php';
+require_once 'boot.php';
 require_once 'include/threads.php';
 require_once 'include/items.php';
 require_once 'include/text.php';
 
-class Item
+class Item extends BaseObject
 {
        /**
         * @brief Update existing item entries
@@ -65,9 +69,9 @@ class Item
                                continue;
                        }
 
-                       create_tags_from_item($item['id']);
-                       Term::createFromItem($item['id']);
-                       update_thread($item['id']);
+                       Term::insertFromTagFieldByItemId($item['id']);
+                       Term::insertFromFileFieldByItemId($item['id']);
+                       self::updateThread($item['id']);
 
                        Worker::add(PRIORITY_HIGH, "Notifier", 'edit_post', $item['id']);
                }
@@ -144,12 +148,12 @@ class Item
 
                // Set the item to "deleted"
                dba::update('item', ['deleted' => true, 'title' => '', 'body' => '',
-                                       'edited' => datetime_convert(), 'changed' => datetime_convert()],
+                                       'edited' => DateTimeFormat::utcNow(), 'changed' => DateTimeFormat::utcNow()],
                                ['id' => $item['id']]);
 
-               create_tags_from_item($item['id']);
-               Term::createFromItem($item['id']);
-               delete_thread($item['id'], $item['parent-uri']);
+               Term::insertFromTagFieldByItemId($item['id']);
+               Term::insertFromFileFieldByItemId($item['id']);
+               self::deleteThread($item['id'], $item['parent-uri']);
 
                // If it's the parent of a comment thread, kill all the kids
                if ($item['id'] == $item['parent']) {
@@ -204,8 +208,8 @@ class Item
                        $guid_prefix = hash("crc32", $parsed["host"]);
                }
 
-               $arr['guid']          = ((x($arr, 'guid'))          ? notags(trim($arr['guid']))          : get_guid(32, $guid_prefix));
-               $arr['uri']           = ((x($arr, 'uri'))           ? notags(trim($arr['uri']))           : item_new_uri($a->get_hostname(), $uid, $arr['guid']));
+               $arr['guid'] = notags(trim(defaults($arr, 'guid', get_guid(32, $guid_prefix))));
+               $arr['uri'] = notags(trim(defaults($arr, 'uri', item_new_uri($a->get_hostname(), $uid, $arr['guid']))));
 
                // Store conversation data
                $arr = Conversation::insert($arr);
@@ -242,9 +246,7 @@ class Item
                        $arr['gravity'] = 6;   // extensible catchall
                }
 
-               if (!x($arr, 'type')) {
-                       $arr['type']      = 'remote';
-               }
+               $arr['type'] = defaults($arr, 'type', 'remote');
 
                $uid = intval($arr['uid']);
 
@@ -290,47 +292,47 @@ class Item
 
                self::addLanguageInPostopts($arr);
 
-               $arr['wall']          = ((x($arr, 'wall'))          ? intval($arr['wall'])                : 0);
-               $arr['extid']         = ((x($arr, 'extid'))         ? notags(trim($arr['extid']))         : '');
-               $arr['author-name']   = ((x($arr, 'author-name'))   ? trim($arr['author-name'])   : '');
-               $arr['author-link']   = ((x($arr, 'author-link'))   ? notags(trim($arr['author-link']))   : '');
-               $arr['author-avatar'] = ((x($arr, 'author-avatar')) ? notags(trim($arr['author-avatar'])) : '');
-               $arr['owner-name']    = ((x($arr, 'owner-name'))    ? trim($arr['owner-name'])    : '');
-               $arr['owner-link']    = ((x($arr, 'owner-link'))    ? notags(trim($arr['owner-link']))    : '');
-               $arr['owner-avatar']  = ((x($arr, 'owner-avatar'))  ? notags(trim($arr['owner-avatar']))  : '');
-               $arr['received']      = ((x($arr, 'received') !== false) ? datetime_convert('UTC','UTC', $arr['received']) : datetime_convert());
-               $arr['created']       = ((x($arr, 'created') !== false) ? datetime_convert('UTC','UTC', $arr['created']) : $arr['received']);
-               $arr['edited']        = ((x($arr, 'edited') !== false) ? datetime_convert('UTC','UTC', $arr['edited']) : $arr['created']);
-               $arr['changed']       = ((x($arr, 'changed') !== false) ? datetime_convert('UTC','UTC', $arr['changed']) : $arr['created']);
-               $arr['commented']     = ((x($arr, 'commented') !== false) ? datetime_convert('UTC','UTC', $arr['commented']) : $arr['created']);
-               $arr['title']         = ((x($arr, 'title'))         ? trim($arr['title'])         : '');
-               $arr['location']      = ((x($arr, 'location'))      ? trim($arr['location'])      : '');
-               $arr['coord']         = ((x($arr, 'coord'))         ? notags(trim($arr['coord']))         : '');
+               $arr['wall']          = intval(defaults($arr, 'wall', 0));
+               $arr['extid']         = trim(defaults($arr, 'extid', ''));
+               $arr['author-name']   = trim(defaults($arr, 'author-name', ''));
+               $arr['author-link']   = trim(defaults($arr, 'author-link', ''));
+               $arr['author-avatar'] = trim(defaults($arr, 'author-avatar', ''));
+               $arr['owner-name']    = trim(defaults($arr, 'owner-name', ''));
+               $arr['owner-link']    = trim(defaults($arr, 'owner-link', ''));
+               $arr['owner-avatar']  = trim(defaults($arr, 'owner-avatar', ''));
+               $arr['received']      = ((x($arr, 'received') !== false) ? DateTimeFormat::utc($arr['received']) : DateTimeFormat::utcNow());
+               $arr['created']       = ((x($arr, 'created') !== false) ? DateTimeFormat::utc($arr['created']) : $arr['received']);
+               $arr['edited']        = ((x($arr, 'edited') !== false) ? DateTimeFormat::utc($arr['edited']) : $arr['created']);
+               $arr['changed']       = ((x($arr, 'changed') !== false) ? DateTimeFormat::utc($arr['changed']) : $arr['created']);
+               $arr['commented']     = ((x($arr, 'commented') !== false) ? DateTimeFormat::utc($arr['commented']) : $arr['created']);
+               $arr['title']         = trim(defaults($arr, 'title', ''));
+               $arr['location']      = trim(defaults($arr, 'location', ''));
+               $arr['coord']         = trim(defaults($arr, 'coord', ''));
                $arr['visible']       = ((x($arr, 'visible') !== false) ? intval($arr['visible'])         : 1);
                $arr['deleted']       = 0;
-               $arr['parent-uri']    = ((x($arr, 'parent-uri'))    ? notags(trim($arr['parent-uri']))    : $arr['uri']);
-               $arr['verb']          = ((x($arr, 'verb'))          ? notags(trim($arr['verb']))          : '');
-               $arr['object-type']   = ((x($arr, 'object-type'))   ? notags(trim($arr['object-type']))   : '');
-               $arr['object']        = ((x($arr, 'object'))        ? trim($arr['object'])                : '');
-               $arr['target-type']   = ((x($arr, 'target-type'))   ? notags(trim($arr['target-type']))   : '');
-               $arr['target']        = ((x($arr, 'target'))        ? trim($arr['target'])                : '');
-               $arr['plink']         = ((x($arr, 'plink'))         ? notags(trim($arr['plink']))         : '');
-               $arr['allow_cid']     = ((x($arr, 'allow_cid'))     ? trim($arr['allow_cid'])             : '');
-               $arr['allow_gid']     = ((x($arr, 'allow_gid'))     ? trim($arr['allow_gid'])             : '');
-               $arr['deny_cid']      = ((x($arr, 'deny_cid'))      ? trim($arr['deny_cid'])              : '');
-               $arr['deny_gid']      = ((x($arr, 'deny_gid'))      ? trim($arr['deny_gid'])              : '');
-               $arr['private']       = ((x($arr, 'private'))       ? intval($arr['private'])             : 0);
-               $arr['bookmark']      = ((x($arr, 'bookmark'))      ? intval($arr['bookmark'])            : 0);
-               $arr['body']          = ((x($arr, 'body'))          ? trim($arr['body'])                  : '');
-               $arr['tag']           = ((x($arr, 'tag'))           ? notags(trim($arr['tag']))           : '');
-               $arr['attach']        = ((x($arr, 'attach'))        ? notags(trim($arr['attach']))        : '');
-               $arr['app']           = ((x($arr, 'app'))           ? notags(trim($arr['app']))           : '');
-               $arr['origin']        = ((x($arr, 'origin'))        ? intval($arr['origin'])              : 0);
-               $arr['postopts']      = ((x($arr, 'postopts'))      ? trim($arr['postopts'])              : '');
-               $arr['resource-id']   = ((x($arr, 'resource-id'))   ? trim($arr['resource-id'])           : '');
-               $arr['event-id']      = ((x($arr, 'event-id'))      ? intval($arr['event-id'])            : 0);
-               $arr['inform']        = ((x($arr, 'inform'))        ? trim($arr['inform'])                : '');
-               $arr['file']          = ((x($arr, 'file'))          ? trim($arr['file'])                  : '');
+               $arr['parent-uri']    = trim(defaults($arr, 'parent-uri', $arr['uri']));
+               $arr['verb']          = trim(defaults($arr, 'verb', ''));
+               $arr['object-type']   = trim(defaults($arr, 'object-type', ''));
+               $arr['object']        = trim(defaults($arr, 'object', ''));
+               $arr['target-type']   = trim(defaults($arr, 'target-type', ''));
+               $arr['target']        = trim(defaults($arr, 'target', ''));
+               $arr['plink']         = trim(defaults($arr, 'plink', ''));
+               $arr['allow_cid']     = trim(defaults($arr, 'allow_cid', ''));
+               $arr['allow_gid']     = trim(defaults($arr, 'allow_gid', ''));
+               $arr['deny_cid']      = trim(defaults($arr, 'deny_cid', ''));
+               $arr['deny_gid']      = trim(defaults($arr, 'deny_gid', ''));
+               $arr['private']       = intval(defaults($arr, 'private', 0));
+               $arr['bookmark']      = intval(defaults($arr, 'bookmark', 0));
+               $arr['body']          = trim(defaults($arr, 'body', ''));
+               $arr['tag']           = trim(defaults($arr, 'tag', ''));
+               $arr['attach']        = trim(defaults($arr, 'attach', ''));
+               $arr['app']           = trim(defaults($arr, 'app', ''));
+               $arr['origin']        = intval(defaults($arr, 'origin', 0));
+               $arr['postopts']      = trim(defaults($arr, 'postopts', ''));
+               $arr['resource-id']   = trim(defaults($arr, 'resource-id', ''));
+               $arr['event-id']      = intval(defaults($arr, 'event-id', 0));
+               $arr['inform']        = trim(defaults($arr, 'inform', ''));
+               $arr['file']          = trim(defaults($arr, 'file', ''));
 
                // When there is no content then we don't post it
                if ($arr['body'].$arr['title'] == '') {
@@ -338,13 +340,13 @@ class Item
                }
 
                // Items cannot be stored before they happen ...
-               if ($arr['created'] > datetime_convert()) {
-                       $arr['created'] = datetime_convert();
+               if ($arr['created'] > DateTimeFormat::utcNow()) {
+                       $arr['created'] = DateTimeFormat::utcNow();
                }
 
                // We haven't invented time travel by now.
-               if ($arr['edited'] > datetime_convert()) {
-                       $arr['edited'] = datetime_convert();
+               if ($arr['edited'] > DateTimeFormat::utcNow()) {
+                       $arr['edited'] = DateTimeFormat::utcNow();
                }
 
                if (($arr['author-link'] == "") && ($arr['owner-link'] == "")) {
@@ -738,9 +740,9 @@ class Item
                // update the commented timestamp on the parent
                // Only update "commented" if it is really a comment
                if (($arr['verb'] == ACTIVITY_POST) || !Config::get("system", "like_no_comment")) {
-                       dba::update('item', ['commented' => datetime_convert(), 'changed' => datetime_convert()], ['id' => $parent_id]);
+                       dba::update('item', ['commented' => DateTimeFormat::utcNow(), 'changed' => DateTimeFormat::utcNow()], ['id' => $parent_id]);
                } else {
-                       dba::update('item', ['changed' => datetime_convert()], ['id' => $parent_id]);
+                       dba::update('item', ['changed' => DateTimeFormat::utcNow()], ['id' => $parent_id]);
                }
 
                if ($dsprsig) {
@@ -777,9 +779,9 @@ class Item
                }
 
                if ($arr['parent-uri'] === $arr['uri']) {
-                       add_thread($current_post);
+                       self::addThread($current_post);
                } else {
-                       update_thread($parent_id);
+                       self::updateThread($parent_id);
                }
 
                dba::commit();
@@ -788,8 +790,8 @@ class Item
                 * Due to deadlock issues with the "term" table we are doing these steps after the commit.
                 * This is not perfect - but a workable solution until we found the reason for the problem.
                 */
-               create_tags_from_item($current_post);
-               Term::createFromItem($current_post);
+               Term::insertFromTagFieldByItemId($current_post);
+               Term::insertFromFileFieldByItemId($current_post);
 
                if ($arr['parent-uri'] === $arr['uri']) {
                        self::addShadow($current_post);
@@ -1026,7 +1028,8 @@ class Item
         *
         * @param array $arr Contains the just posted item record
         */
-       private static function updateContact($arr) {
+       private static function updateContact($arr)
+       {
                // Unarchive the author
                $contact = dba::selectFirst('contact', [], ['id' => $arr["author-link"]]);
                if ($contact['term-date'] > NULL_DATE) {
@@ -1068,94 +1071,8 @@ class Item
                }
        }
 
-       /**
-        * The purpose of this function is to apply system message length limits to
-        * imported messages without including any embedded photos in the length
-        *
-        * @brief Truncates imported message body string length to max_import_size
-        * @param string $body
-        * @return string
-        */
-       public static function limitBodySize($body)
+       private static function setHashtags(&$item)
        {
-               $maxlen = get_max_import_size();
-
-               // If the length of the body, including the embedded images, is smaller
-               // than the maximum, then don't waste time looking for the images
-               if ($maxlen && (strlen($body) > $maxlen)) {
-
-                       logger('the total body length exceeds the limit', LOGGER_DEBUG);
-
-                       $orig_body = $body;
-                       $new_body = '';
-                       $textlen = 0;
-
-                       $img_start = strpos($orig_body, '[img');
-                       $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false);
-                       $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false);
-                       while (($img_st_close !== false) && ($img_end !== false)) {
-
-                               $img_st_close++; // make it point to AFTER the closing bracket
-                               $img_end += $img_start;
-                               $img_end += strlen('[/img]');
-
-                               if (!strcmp(substr($orig_body, $img_start + $img_st_close, 5), 'data:')) {
-                                       // This is an embedded image
-
-                                       if (($textlen + $img_start) > $maxlen) {
-                                               if ($textlen < $maxlen) {
-                                                       logger('the limit happens before an embedded image', LOGGER_DEBUG);
-                                                       $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen);
-                                                       $textlen = $maxlen;
-                                               }
-                                       } else {
-                                               $new_body = $new_body . substr($orig_body, 0, $img_start);
-                                               $textlen += $img_start;
-                                       }
-
-                                       $new_body = $new_body . substr($orig_body, $img_start, $img_end - $img_start);
-                               } else {
-
-                                       if (($textlen + $img_end) > $maxlen) {
-                                               if ($textlen < $maxlen) {
-                                                       logger('the limit happens before the end of a non-embedded image', LOGGER_DEBUG);
-                                                       $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen);
-                                                       $textlen = $maxlen;
-                                               }
-                                       } else {
-                                               $new_body = $new_body . substr($orig_body, 0, $img_end);
-                                               $textlen += $img_end;
-                                       }
-                               }
-                               $orig_body = substr($orig_body, $img_end);
-
-                               if ($orig_body === false) {
-                                       // in case the body ends on a closing image tag
-                                       $orig_body = '';
-                               }
-
-                               $img_start = strpos($orig_body, '[img');
-                               $img_st_close = ($img_start !== false ? strpos(substr($orig_body, $img_start), ']') : false);
-                               $img_end = ($img_start !== false ? strpos(substr($orig_body, $img_start), '[/img]') : false);
-                       }
-
-                       if (($textlen + strlen($orig_body)) > $maxlen) {
-                               if ($textlen < $maxlen) {
-                                       logger('the limit happens after the end of the last image', LOGGER_DEBUG);
-                                       $new_body = $new_body . substr($orig_body, 0, $maxlen - $textlen);
-                               }
-                       } else {
-                               logger('the text size with embedded images extracted did not violate the limit', LOGGER_DEBUG);
-                               $new_body = $new_body . $orig_body;
-                       }
-
-                       return $new_body;
-               } else {
-                       return $body;
-               }
-       }
-
-       private static function setHashtags(&$item) {
 
                $tags = get_tags($item["body"]);
 
@@ -1222,7 +1139,8 @@ class Item
                $item["body"] = str_replace("&num;", "#", $item["body"]);
        }
 
-       public static function getGuidById($id) {
+       public static function getGuidById($id)
+       {
                $r = q("SELECT `guid` FROM `item` WHERE `id` = %d LIMIT 1", intval($id));
                if (DBM::is_result($r)) {
                        return $r[0]["guid"];
@@ -1231,8 +1149,8 @@ class Item
                }
        }
 
-       public static function getIdAndNickByGuid($guid, $uid = 0) {
-
+       public static function getIdAndNickByGuid($guid, $uid = 0)
+       {
                $nick = "";
                $id = 0;
 
@@ -1371,13 +1289,14 @@ class Item
                        dbesc($u[0]['deny_gid']),
                        intval($item_id)
                );
-               update_thread($item_id);
+               self::updateThread($item_id);
 
                Worker::add(['priority' => PRIORITY_HIGH, 'dont_fork' => true], 'Notifier', 'tgroup', $item_id);
 
        }
 
-       public static function isRemoteSelf($contact, &$datarray) {
+       public static function isRemoteSelf($contact, &$datarray)
+       {
                $a = get_app();
 
                if (!$contact['remote_self']) {
@@ -1564,7 +1483,8 @@ class Item
                return $new_body;
        }
 
-       private static function hasPermissions($obj) {
+       private static function hasPermissions($obj)
+       {
                return (
                        (
                                x($obj, 'allow_cid')
@@ -1578,7 +1498,8 @@ class Item
                );
        }
 
-       private static function samePermissions($obj1, $obj2) {
+       private static function samePermissions($obj1, $obj2)
+       {
                // first part is easy. Check that these are exactly the same.
                if (($obj1['allow_cid'] == $obj2['allow_cid'])
                        && ($obj1['allow_gid'] == $obj2['allow_gid'])
@@ -1598,7 +1519,8 @@ class Item
        }
 
        // returns an array of contact-ids that are allowed to see this object
-       private static function enumeratePermissions($obj) {
+       private static function enumeratePermissions($obj)
+       {
                $allow_people = expand_acl($obj['allow_cid']);
                $allow_groups = Group::expand(expand_acl($obj['allow_gid']));
                $deny_people  = expand_acl($obj['deny_cid']);
@@ -1609,7 +1531,8 @@ class Item
                return $recipients;
        }
 
-       public static function getFeedTags($item) {
+       public static function getFeedTags($item)
+       {
                $ret = [];
                $matches = false;
                $cnt = preg_match_all('|\#\[url\=(.*?)\](.*?)\[\/url\]|', $item['tag'], $matches);
@@ -1632,8 +1555,8 @@ class Item
                return $ret;
        }
 
-       public static function expire($uid, $days, $network = "", $force = false) {
-
+       public static function expire($uid, $days, $network = "", $force = false)
+       {
                if (!$uid || ($days < 1)) {
                        return;
                }
@@ -1709,7 +1632,8 @@ class Item
        }
 
        /// @TODO: This query seems to be really slow
-       public static function firstPostDate($uid, $wall = false) {
+       public static function firstPostDate($uid, $wall = false)
+       {
                $r = q("SELECT `id`, `created` FROM `item`
                        WHERE `uid` = %d AND `wall` = %d AND `deleted` = 0 AND `visible` = 1 AND `moderated` = 0
                        AND `id` = `parent`
@@ -1718,8 +1642,344 @@ class Item
                        intval($wall ? 1 : 0)
                );
                if (DBM::is_result($r)) {
-                       return substr(datetime_convert('',date_default_timezone_get(), $r[0]['created']),0,10);
+                       return substr(DateTimeFormat::local($r[0]['created']),0,10);
                }
                return false;
        }
+
+       /**
+        * @brief add/remove activity to an item
+        *
+        * Toggle activities as like,dislike,attend of an item
+        *
+        * @param string $item_id
+        * @param string $verb
+        *              Activity verb. One of
+        *                      like, unlike, dislike, undislike, attendyes, unattendyes,
+        *                      attendno, unattendno, attendmaybe, unattendmaybe
+        * @hook 'post_local_end'
+        *              array $arr
+        *                      'post_id' => ID of posted item
+        */
+       public static function performLike($item_id, $verb)
+       {
+               if (!local_user() && !remote_user()) {
+                       return false;
+               }
+
+               switch ($verb) {
+                       case 'like':
+                       case 'unlike':
+                               $bodyverb = L10n::t('%1$s likes %2$s\'s %3$s');
+                               $activity = ACTIVITY_LIKE;
+                               break;
+                       case 'dislike':
+                       case 'undislike':
+                               $bodyverb = L10n::t('%1$s doesn\'t like %2$s\'s %3$s');
+                               $activity = ACTIVITY_DISLIKE;
+                               break;
+                       case 'attendyes':
+                       case 'unattendyes':
+                               $bodyverb = L10n::t('%1$s is attending %2$s\'s %3$s');
+                               $activity = ACTIVITY_ATTEND;
+                               break;
+                       case 'attendno':
+                       case 'unattendno':
+                               $bodyverb = L10n::t('%1$s is not attending %2$s\'s %3$s');
+                               $activity = ACTIVITY_ATTENDNO;
+                               break;
+                       case 'attendmaybe':
+                       case 'unattendmaybe':
+                               $bodyverb = L10n::t('%1$s may attend %2$s\'s %3$s');
+                               $activity = ACTIVITY_ATTENDMAYBE;
+                               break;
+                       default:
+                               logger('like: unknown verb ' . $verb . ' for item ' . $item_id);
+                               return false;
+               }
+
+               // Enable activity toggling instead of on/off
+               $event_verb_flag = $activity === ACTIVITY_ATTEND || $activity === ACTIVITY_ATTENDNO || $activity === ACTIVITY_ATTENDMAYBE;
+
+               logger('like: verb ' . $verb . ' item ' . $item_id);
+
+               $item = dba::selectFirst('item', [], ['`id` = ? OR `uri` = ?', $item_id, $item_id]);
+               if (!DBM::is_result($item)) {
+                       logger('like: unknown item ' . $item_id);
+                       return false;
+               }
+
+               $uid = $item['uid'];
+               if (($uid == 0) && local_user()) {
+                       $uid = local_user();
+               }
+
+               if (!can_write_wall($uid)) {
+                       logger('like: unable to write on wall ' . $uid);
+                       return false;
+               }
+
+               // Retrieves the local post owner
+               $owner_self_contact = dba::selectFirst('contact', [], ['uid' => $uid, 'self' => true]);
+               if (!DBM::is_result($owner_self_contact)) {
+                       logger('like: unknown owner ' . $uid);
+                       return false;
+               }
+
+               // Retrieve the current logged in user's public contact
+               $author_id = public_contact();
+
+               $author_contact = dba::selectFirst('contact', [], ['id' => $author_id]);
+               if (!DBM::is_result($author_contact)) {
+                       logger('like: unknown author ' . $author_id);
+                       return false;
+               }
+
+               // Contact-id is the uid-dependant author contact
+               if (local_user() == $uid) {
+                       $item_contact_id = $owner_self_contact['id'];
+                       $item_contact = $owner_self_contact;
+               } else {
+                       $item_contact_id = Contact::getIdForURL($author_contact['url'], $uid);
+                       $item_contact = dba::selectFirst('contact', [], ['id' => $item_contact_id]);
+                       if (!DBM::is_result($item_contact)) {
+                               logger('like: unknown item contact ' . $item_contact_id);
+                               return false;
+                       }
+               }
+
+               // Look for an existing verb row
+               // event participation are essentially radio toggles. If you make a subsequent choice,
+               // we need to eradicate your first choice.
+               if ($event_verb_flag) {
+                       $verbs = "'" . dbesc(ACTIVITY_ATTEND) . "', '" . dbesc(ACTIVITY_ATTENDNO) . "', '" . dbesc(ACTIVITY_ATTENDMAYBE) . "'";
+               } else {
+                       $verbs = "'".dbesc($activity)."'";
+               }
+
+               $existing_like = q("SELECT `id`, `guid`, `verb` FROM `item`
+                       WHERE `verb` IN ($verbs)
+                       AND `deleted` = 0
+                       AND `author-id` = %d
+                       AND `uid` = %d
+                       AND (`parent` = '%s' OR `parent-uri` = '%s' OR `thr-parent` = '%s')
+                       LIMIT 1",
+                       intval($author_contact['id']),
+                       intval($item['uid']),
+                       dbesc($item_id), dbesc($item_id), dbesc($item['uri'])
+               );
+
+               // If it exists, mark it as deleted
+               if (DBM::is_result($existing_like)) {
+                       $like_item = $existing_like[0];
+
+                       // Already voted, undo it
+                       $fields = ['deleted' => true, 'unseen' => true, 'changed' => DateTimeFormat::utcNow()];
+                       dba::update('item', $fields, ['id' => $like_item['id']]);
+
+                       // Clean up the Diaspora signatures for this like
+                       // Go ahead and do it even if Diaspora support is disabled. We still want to clean up
+                       // if it had been enabled in the past
+                       dba::delete('sign', ['iid' => $like_item['id']]);
+
+                       $like_item_id = $like_item['id'];
+                       Worker::add(PRIORITY_HIGH, "Notifier", "like", $like_item_id);
+
+                       if (!$event_verb_flag || $like_item['verb'] == $activity) {
+                               return true;
+                       }
+               }
+
+               // Verb is "un-something", just trying to delete existing entries
+               if (strpos($verb, 'un') === 0) {
+                       return true;
+               }
+
+               // Else or if event verb different from existing row, create a new item row
+               $post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
+               if ($item['object-type'] === ACTIVITY_OBJ_EVENT) {
+                       $post_type = L10n::t('event');
+               }
+               $objtype = $item['resource-id'] ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE ;
+               $link = xmlify('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $owner_self_contact['nick'] . '/' . $item['id'] . '" />' . "\n") ;
+               $body = $item['body'];
+
+               $obj = <<< EOT
+
+               <object>
+                       <type>$objtype</type>
+                       <local>1</local>
+                       <id>{$item['uri']}</id>
+                       <link>$link</link>
+                       <title></title>
+                       <content>$body</content>
+               </object>
+EOT;
+
+               $ulink = '[url=' . $author_contact['url'] . ']' . $author_contact['name'] . '[/url]';
+               $alink = '[url=' . $item['author-link'] . ']' . $item['author-name'] . '[/url]';
+               $plink = '[url=' . System::baseUrl() . '/display/' . $owner_self_contact['nick'] . '/' . $item['id'] . ']' . $post_type . '[/url]';
+
+               $new_item = [
+                       'guid'          => get_guid(32),
+                       'uri'           => item_new_uri(self::getApp()->get_hostname(), $item['uid']),
+                       'uid'           => $item['uid'],
+                       'contact-id'    => $item_contact_id,
+                       'type'          => 'activity',
+                       'wall'          => $item['wall'],
+                       'origin'        => 1,
+                       'gravity'       => GRAVITY_LIKE,
+                       'parent'        => $item['id'],
+                       'parent-uri'    => $item['uri'],
+                       'thr-parent'    => $item['uri'],
+                       'owner-id'      => $item['owner-id'],
+                       'owner-name'    => $item['owner-name'],
+                       'owner-link'    => $item['owner-link'],
+                       'owner-avatar'  => $item['owner-avatar'],
+                       'author-id'     => $author_contact['id'],
+                       'author-name'   => $author_contact['name'],
+                       'author-link'   => $author_contact['url'],
+                       'author-avatar' => $author_contact['thumb'],
+                       'body'          => sprintf($bodyverb, $ulink, $alink, $plink),
+                       'verb'          => $activity,
+                       'object-type'   => $objtype,
+                       'object'        => $obj,
+                       'allow_cid'     => $item['allow_cid'],
+                       'allow_gid'     => $item['allow_gid'],
+                       'deny_cid'      => $item['deny_cid'],
+                       'deny_gid'      => $item['deny_gid'],
+                       'visible'       => 1,
+                       'unseen'        => 1,
+               ];
+
+               $new_item_id = Item::insert($new_item);
+
+               // @todo: Explain this block
+               if (! $item['visible']) {
+                       q("UPDATE `item` SET `visible` = 1 WHERE `id` = %d",
+                               intval($item['id'])
+                       );
+               }
+
+               // Save the author information for the like in case we need to relay to Diaspora
+               Diaspora::storeLikeSignature($item_contact, $new_item_id);
+
+               $new_item['id'] = $new_item_id;
+
+               Addon::callHooks('post_local_end', $new_item);
+
+               Worker::add(PRIORITY_HIGH, "Notifier", "like", $new_item_id);
+
+               return true;
+       }
+
+       private static function addThread($itemid, $onlyshadow = false) {
+               $items = q("SELECT `uid`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`,
+                               `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`, `gcontact-id`,
+                               `deleted`, `origin`, `forum_mode`, `mention`, `network`, `author-id`, `owner-id`
+                       FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
+       
+               if (!$items)
+                       return;
+       
+               $item = $items[0];
+               $item['iid'] = $itemid;
+       
+               if (!$onlyshadow) {
+                       $result = dba::insert('thread', $item);
+       
+                       logger("Add thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
+               }
+       }
+
+       public static function updateThreadFromUri($itemuri, $uid) {
+               $messages = q("SELECT `id` FROM `item` WHERE uri ='%s' AND uid=%d", dbesc($itemuri), intval($uid));
+       
+               if (DBM::is_result($messages)) {
+                       foreach ($messages as $message) {
+                               self::updateThread($message["id"]);
+                       }
+               }
+       }
+
+       public static function updateThread($itemid, $setmention = false) {
+               $items = q("SELECT `uid`, `guid`, `title`, `body`, `created`, `edited`, `commented`, `received`, `changed`, `wall`, `private`, `pubmail`, `moderated`, `visible`, `spam`, `starred`, `bookmark`, `contact-id`, `gcontact-id`,
+                               `deleted`, `origin`, `forum_mode`, `network`, `rendered-html`, `rendered-hash` FROM `item` WHERE `id` = %d AND (`parent` = %d OR `parent` = 0) LIMIT 1", intval($itemid), intval($itemid));
+       
+               if (!DBM::is_result($items)) {
+                       return;
+               }
+       
+               $item = $items[0];
+       
+               if ($setmention) {
+                       $item["mention"] = 1;
+               }
+       
+               $sql = "";
+       
+               foreach ($item AS $field => $data)
+                       if (!in_array($field, ["guid", "title", "body", "rendered-html", "rendered-hash"])) {
+                               if ($sql != "") {
+                                       $sql .= ", ";
+                               }
+       
+                               $sql .= "`".$field."` = '".dbesc($data)."'";
+                       }
+       
+               $result = q("UPDATE `thread` SET ".$sql." WHERE `iid` = %d", intval($itemid));
+       
+               logger("Update thread for item ".$itemid." - guid ".$item["guid"]." - ".print_r($result, true)." ".print_r($item, true), LOGGER_DEBUG);
+       
+               // Updating a shadow item entry
+               $items = q("SELECT `id` FROM `item` WHERE `guid` = '%s' AND `uid` = 0 LIMIT 1", dbesc($item["guid"]));
+       
+               if (!DBM::is_result($items)) {
+                       return;
+               }
+       
+               $result = q("UPDATE `item` SET `title` = '%s', `body` = '%s', `rendered-html` = '%s', `rendered-hash` = '%s' WHERE `id` = %d",
+                               dbesc($item["title"]),
+                               dbesc($item["body"]),
+                               dbesc($item["rendered-html"]),
+                               dbesc($item["rendered-hash"]),
+                               intval($items[0]["id"])
+                       );
+               logger("Updating public shadow for post ".$items[0]["id"]." - guid ".$item["guid"]." Result: ".print_r($result, true), LOGGER_DEBUG);
+       }
+       
+       public static function deleteThreadFromUri($itemuri, $uid) {
+               $messages = q("SELECT `id` FROM `item` WHERE uri ='%s' AND uid=%d", dbesc($itemuri), intval($uid));
+       
+               if (DBM::is_result($messages)) {
+                       foreach ($messages as $message) {
+                               self::deleteThread($message["id"], $itemuri);
+                       }
+               }
+       }
+       
+       public static function deleteThread($itemid, $itemuri = "") {
+               $item = q("SELECT `uid` FROM `thread` WHERE `iid` = %d", intval($itemid));
+       
+               if (!DBM::is_result($item)) {
+                       logger('No thread found for id '.$itemid, LOGGER_DEBUG);
+                       return;
+               }
+       
+               // Using dba::delete at this time could delete the associated item entries
+               $result = dba::e("DELETE FROM `thread` WHERE `iid` = ?", $itemid);
+       
+               logger("deleteThread: Deleted thread for item ".$itemid." - ".print_r($result, true), LOGGER_DEBUG);
+       
+               if ($itemuri != "") {
+                       $r = q("SELECT `id` FROM `item` WHERE `uri` = '%s' AND NOT `deleted` AND NOT (`uid` IN (%d, 0))",
+                                       dbesc($itemuri),
+                                       intval($item["uid"])
+                               );
+                       if (!DBM::is_result($r)) {
+                               dba::delete('item', ['uri' => $itemuri, 'uid' => 0]);
+                               logger("deleteThread: Deleted shadow for item ".$itemuri, LOGGER_DEBUG);
+                       }
+               }
+       }
 }